如何在C#中获取活动进程名称?

17

如何在C#中获取活动进程的名称?

我知道我必须使用以下代码:

[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();

但是我不知道如何使用它。


3
请注意,尝试使用GetForegroundWindow与其他函数(例如Gustavo回答中显示的GetProcessesByName)可能存在竞争条件。系统可以在获取每个函数的返回值之间进行更改(无论它们以什么顺序被调用),使得你将无法保证从两个函数找到相应的值。也许如果你解释一下打算如何使用这个值,就可能会得到更好的回答。 - Damien_The_Unbeliever
5个回答

25

正如这个答案中所提到的,您必须使用GetWindowThreadProcessId()来获取窗口的进程ID,然后您可以使用Process

[DllImport("user32.dll")]
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);

[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();

string GetActiveProcessFileName()
{
    IntPtr hwnd = GetForegroundWindow();
    uint pid;
    GetWindowThreadProcessId(hwnd, out pid);
    Process p = Process.GetProcessById((int)pid);
    p.MainModule.FileName.Dump();
}

请注意,当在一个32位应用程序下,活动进程为64位时,似乎会抛出异常(“32位进程无法访问64位进程的模块”)。

编辑:Damien指出,该代码容易发生竞态条件,因为调用GetForegroundWindow()时具有活动窗口的进程可能已经不存在了,这时调用GetWindowThreadProcessId()。更糟糕的情况是,同一hwnd在那个时候被分配给另一个窗口,但我想这应该非常罕见。


使用这个API和这个函数,你的汇编代码可能会被一些杀毒软件识别为TR/Dropper.MSIL.Gen。 - Hichem
我还没有测试过,但GetProcessImageFileName可能会避免64位问题。 - CodesInChaos
2
使用“p.processName”代替“p.MainModule.FileName”可以避免32-64位无法访问的错误。 - bh_earth0

9
我建议使用 System.Diagnostics.Process
var currentProc = System.Diagnostics.Process.GetCurrentProcess();
string name = currentProc.ProcessName;

作为一种替代方案,您可以使用:
string name = currentProc.MainModule.FileName;

12
因为他提到了“GetForegroundWindow()”,我认为他想要的是当前活动窗口的进程,而不是当前进程。 - svick

3

只需两行代码,您就可以使用Linq获取所有进程。

var processss = from proc in System.Diagnostics.Process.GetProcesses() orderby proc.ProcessName ascending select proc;
foreach (var item in processss) {
    Console.WriteLine(item.ProcessName );
}

现在您只需在线即可查看所有活动进程。


5
请注意问题要求提供当前正在运行的进程名称。 - Adrian Heine

2
这里提供一个链接,描述了您想要完成的确切操作:http://www.blackwasp.co.uk/GetActiveProcess.aspx。另一个链接描述了 GetForegroundWindow 函数,并将其复制如下。
请注意,为使此代码正常工作,您可能需要引用一些额外的程序集。查看每个函数的MSDN文档。例如,GetProcessesByName 需要 System.Diagnostics。
public ApplicationState AppState
{
    get
    {
        Process[] processCollection =
                           Process.GetProcessesByName(ProcessName);
        if(processCollection != null && 
           processCollection.Length  >= 1 && 
            processCollection[0] != null)
        {
            IntPtr activeWindowHandle = Win32.GetForegroundWindow();
            // Optional int ProcessID;
            // Optional Win32.GetWindowThreadProcessId(
                                                 GetForegroundWindow(), 
                                                 out ProcessID)
            foreach(Process wordProcess in processCollection)
            {
                //Optional if( ProcessID == wordProcess.Id )
                //          return ApplicationState.Focused;
                if(wordProcess.MainWindowHandle == activeWindowHandle)
                {
                    return ApplicationState.Focused;
                }
            }

            return ApplicationState.Running;
        }

        return ApplicationState.NotRunning;
    }
} 

0
    public void GetProcessNames()
    {
        List<string> windowNames = new List<string>();

        foreach (Process window in Process.GetProcesses())
        {
            if (window.MainWindowHandle != IntPtr.Zero)
            {                    
                windowNames.Add(window.MainWindowTitle);
            }

            // It's that simple
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接