アプリケーションインスタンス数のカウント

アプリケーションの二重起動の防止等、インスタンス数を制御する方法は色々あるが、"一つだけ許可"などではなく、"五つまでは許す"、や、"アプリケーションAは三つ"、"アプリケーションBは四つまで許可する"など、アプリケーション毎に許可するインスタンス数を制御したい場合はプロセスクラス(System.Diagnotics.Process)を使ってアプリケーションインスタンス数をカウントするのが簡単な方法だ。

public static int GetProcessCount(string processName)
{
    int result = 0;
    foreach (Process proc in Process.GetProcessesByName(processName))
    {
        result++;
    }
    return result;
}

これを基本にしてモジュール情報を取得すれば、もう少し厳密にインスタンス数をカウントすることもできる。

//同じプロセス、製品名のアプリケーションが幾つ存在しているか、カウントする
public static int GetInstanceCount(string procName, string product)
{
    int result = 0;
    foreach (Process proc in Process.GetProcessesByName(procName))
    {
        if ( process.ProcessName == processName )
        {
            if ( process.MainModule != null)
            {
                if (File.Exists(process.MainModule.FileName))
                {
                    if (process.MainModule.FileVersionInfo != null &&
                       productName == process.MainModule.FileVersionInfo.ProductName)
                    {
                        result++;
                    }
                }
            }
        }
    }
    return result;
}

C#2.0ならば、Array.FindAllが使えるので、以下のようにも書いても良いだろうか。

public static int GetInstanceCount(string processName, string productName)
{
    Process[] procArray = Array.FindAll(Process.GetProcesses(),
        delegate(Process process)
        {
            if ( process.ProcessName == processName )
            {
                if ( process.MainModule != null)
                {
                    if (File.Exists(process.MainModule.FileName))
                    {
                        if (process.MainModule.FileVersionInfo != null 
                            && productName == process.MainModule.FileVersionInfo.ProductName)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        });
    return procArray.Length;
}

なお、上記メソッドで必要な、現在実行中のアプリケーションのプロセス名、製品名は以下のコードで取得できる。

//自らのプロセス名を取得
public static string GetCurrentProcessName()
{
    return Process.GetCurrentProcess().ProcessName;
}

//アセンブリマニフェストのメタデータから、製品名を取得する
public static string GetProductName()
{
    Assembly entryAssembly = Assembly.GetEntryAssembly();
    object[] productArray = entryAssembly.GetCustomAttributes(typeof(AssemblyProductAttribute), false);
    if ((productArray != null) && (productArray.Length > 0))
    {
        return ((AssemblyProductAttribute)productArray[0]).Product;
    }
    return "";
}

他に、もっとスマートな書き方があれば、是非ご教授願いたい。