DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

実行ファイル名からプロセスを探す

ここでは、実行ファイル名(あるいは、実行ファイルのパス)からプロセスを探して列挙する方法を紹介します。

ProcessModule.FileNameを使用して探す

実行されているすべてのプロセスを取得する」で紹介している方法ですべてのプロセスを列挙して、その中から指定されたファイル名のプロセスを探すという方針で考えてみましょう。

以下の例(GetProcessesByFileNameメソッド)では、Process.MainModuleプロパティでメインモジュールを取得し、そのProcessModule.FileNameプロパティでパスを取得しています。このパスのファイル名と、探しているファイル名を比較し、一致したプロセスの配列を返しています。

このメソッドの使い方は、例えば「notepad.exe」(メモ帳)を探したいのであれば、「GetProcessesByFileName("notepad.exe")」として呼び出せば、見つかったプロセスをProcessオブジェクトの配列として取得できます。

VB.NET
コードを隠すコードを選択
''' <summary>
''' 指定した実行ファイル名のプロセスをすべて取得する。
''' </summary>
''' <param name="searchFileName">検索する実行ファイル名。</param>
''' <returns>一致したProcessの配列。</returns>
Public Shared Function GetProcessesByFileName(searchFileName As String) _
        As System.Diagnostics.Process()
    searchFileName = searchFileName.ToLower()
    Dim list As New System.Collections.ArrayList()

    'すべてのプロセスを列挙する
    For Each p As System.Diagnostics.Process In _
            System.Diagnostics.Process.GetProcesses()
        Dim fileName As String
        Try
            'メインモジュールのパスを取得する
            fileName = p.MainModule.FileName
        Catch generatedExceptionName As System.ComponentModel.Win32Exception
            'MainModuleの取得に失敗
            fileName = ""
        End Try
        If 0 < fileName.Length Then
            'ファイル名の部分を取得する
            fileName = System.IO.Path.GetFileName(fileName)
            '探しているファイル名と一致した時、コレクションに追加
            If searchFileName.Equals(fileName.ToLower()) Then
                list.Add(p)
            End If
        End If
    Next

    'コレクションを配列にして返す
    Return DirectCast(list.ToArray(GetType(System.Diagnostics.Process)),  _
        System.Diagnostics.Process())
End Function
C#
コードを隠すコードを選択
/// <summary>
/// 指定した実行ファイル名のプロセスをすべて取得する。
/// </summary>
/// <param name="searchFileName">検索する実行ファイル名。</param>
/// <returns>一致したProcessの配列。</returns>
public static System.Diagnostics.Process[] GetProcessesByFileName(
    string searchFileName)
{
    searchFileName = searchFileName.ToLower();
    System.Collections.ArrayList list = new System.Collections.ArrayList();

    //すべてのプロセスを列挙する
    foreach (System.Diagnostics.Process p
        in System.Diagnostics.Process.GetProcesses())
    {
        string fileName;
        try
        {
            //メインモジュールのパスを取得する
            fileName = p.MainModule.FileName;
        }
        catch (System.ComponentModel.Win32Exception)
        {
            //MainModuleの取得に失敗
            fileName = "";
        }
        if (0 < fileName.Length)
        {
            //ファイル名の部分を取得する
            fileName = System.IO.Path.GetFileName(fileName);
            //探しているファイル名と一致した時、コレクションに追加
            if (searchFileName.Equals(fileName.ToLower()))
            {
                list.Add(p);
            }
        }
    }

    //コレクションを配列にして返す
    return (System.Diagnostics.Process[])
        list.ToArray(typeof(System.Diagnostics.Process));
}

WMIのWin32_Processを使用して探す

今度は、「実行されているすべてのプロセスを取得する」で紹介しているもう一つの方法、WMIのWin32_Processクラスを使ってみましょう。この方法では、System.Management.dllを参照設定に追加する必要があります。

下の例では、Win32_ProcessのExecutablePathプロパティが「\(指定された文字列)」で終わるプロセスを探しています。ExecutablePathの代わりに、Nameプロパティが探している実行ファイル名と一致したプロセスを探す方法でも良いかもしれません。

VB.NET
コードを隠すコードを選択
''' <summary>
''' 指定した実行ファイル名のプロセスをすべて取得する。
''' </summary>
''' <param name="searchFileName">検索する実行ファイル名。</param>
''' <returns>一致したProcessの配列。</returns>
Public Shared Function GetProcessesByFileName(searchFileName As String) _
        As System.Diagnostics.Process()
    Dim list As New System.Collections.ArrayList()

    'ExecutablePathの最後が「\(検索する実行ファイル名)」のプロセスを探す
    Dim mos As New System.Management.ManagementObjectSearcher( _
        String.Format( _
            "SELECT * FROM Win32_Process WHERE ExecutablePath LIKE '%\\{0}'", _
            searchFileName))
    Dim moc As System.Management.ManagementObjectCollection = mos.[Get]()

    For Each mo As System.Management.ManagementObject In moc
        'プロセスIDを取得する
        Dim processId As Integer = Convert.ToInt32(mo("ProcessId"))
        'Processオブジェクトを作成して、コレクションに追加
        list.Add(System.Diagnostics.Process.GetProcessById(processId))

        mo.Dispose()
    Next

    moc.Dispose()
    mos.Dispose()

    'コレクションを配列にして返す
    Return DirectCast(list.ToArray(GetType(System.Diagnostics.Process)),  _
        System.Diagnostics.Process())
End Function
C#
コードを隠すコードを選択
/// <summary>
/// 指定した実行ファイル名のプロセスをすべて取得する。
/// </summary>
/// <param name="searchFileName">検索する実行ファイル名。</param>
/// <returns>一致したProcessの配列。</returns>
public static System.Diagnostics.Process[] GetProcessesByFileName(
    string searchFileName)
{
    System.Collections.ArrayList list = new System.Collections.ArrayList();

    //ExecutablePathの最後が「\(検索する実行ファイル名)」のプロセスを探す
    System.Management.ManagementObjectSearcher mos =
        new System.Management.ManagementObjectSearcher(
            string.Format(
                @"SELECT * FROM Win32_Process WHERE ExecutablePath LIKE '%\\{0}'",
                searchFileName));
    System.Management.ManagementObjectCollection moc =
        mos.Get();

    foreach (System.Management.ManagementObject mo in moc)
    {
        //プロセスIDを取得する
        int processId = Convert.ToInt32(mo["ProcessId"]);
        //Processオブジェクトを作成して、コレクションに追加
        list.Add(System.Diagnostics.Process.GetProcessById(processId));

        mo.Dispose();
    }

    moc.Dispose();
    mos.Dispose();

    //コレクションを配列にして返す
    return (System.Diagnostics.Process[])
        list.ToArray(typeof(System.Diagnostics.Process));
}

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • 「???を参照に追加します」の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。