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

如何在C#中获取活动进程名称?,c#,C#,如何在C#中获取活动进程名称 我知道我必须使用以下代码: [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); 但是我不知道如何使用它。我建议使用System.Diagnostics.Process var currentProc = System.Diagnostics.Process.GetCurrentProcess(); string name = currentProc.Proces

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

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

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

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

我建议使用
System.Diagnostics.Process

var currentProc = System.Diagnostics.Process.GetCurrentProcess();
string name = currentProc.ProcessName;
作为替代方案,您可以使用:

string name = currentProc.MainModule.FileName;
如中所述,必须使用
GetWindowThreadProcessId()
获取窗口的进程id,然后才能使用
进程

[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();
}
请注意,当活动进程为64位时,从32位应用程序运行时,这似乎会引发异常(“32位进程无法访问64位进程的模块”)


EDIT:正如Damien指出的,此代码容易出现争用情况,因为调用
GetForegroundWindow()
时具有活动窗口的进程在调用
GetWindowThreadProcessId()
时可能不再存在。更糟糕的情况是,如果同一个hwnd在当时被分配到另一个窗口,但我想这应该非常罕见。

这里有一个链接描述了您想要做的事情:

还有一个描述函数的,我在下面复制

请注意,要使此代码正常工作,您可能需要引用一些额外的程序集。 查看每个函数的MSDN。例如,需要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;
    }
} 

它只需要两行代码,就可以使用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 );
}
现在,只要联机,您就拥有了所有活动进程。

public void GetProcessNames()
    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
        }
    }
{ List windowNames=新列表(); foreach(Process.getprocesss()中的进程窗口) { if(window.MainWindowHandle!=IntPtr.Zero) { windowNames.Add(window.MainWindowTitle); } //就这么简单 } }
您应该知道,尝试使用
GetForegroundWindow
以及任何其他函数(如Gustavo的回答所示,
GetProcessByName
)都会受到竞争条件的影响。系统可以在从每个函数获取返回值之间进行切换(无论调用顺序如何),这样就无法保证从这两个函数中找到相应的值。也许如果你解释一下你打算用这个值做什么,可能会得到更好的回答。因为他提到了
getforegroughindow()
,我想他想要当前活动窗口的进程,不是当前进程。请注意,该问题询问当前活动进程的名称。使用此API和此函数,您的程序集将是TR/Dropper.MSIL.Gen,某些AVI尚未对其进行测试,但是可以避免64位问题。使用
p.processName
代替
p.MainModule.FileName
可以避免32-64位的无法访问错误