17

How to get active process name in C#?

I know that I must use this code:

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

but I don't know how use it.

Bolu
  • 8,696
  • 4
  • 38
  • 70
p.eon13
  • 207
  • 1
  • 3
  • 4
  • 3
    You should be aware that trying to use `GetForegroundWindow` along with any other functions (e.g. `GetProcessesByName`, as shown by Gustavo's answer) is subject to race conditions. The system can change between obtaining the return values from each function (doesn't matter which order they're called in), such that you won't be able to guarantee finding corresponding values from the two. Perhaps if you explain what you intend to do with this value, a better response might be obtained. – Damien_The_Unbeliever Jul 04 '11 at 09:26

5 Answers5

25

As mentioned in this answer, you have to use GetWindowThreadProcessId() to get the process id for the window and then you can use the 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();
}

Be aware that this seems to throw an exception (“A 32 bit processes cannot access modules of a 64 bit process”) when run from a 32-bit application when the active process is 64-bit.

EDIT: As Damien pointed out, this code is prone to race conditions, because the process that had the active window at the time when GetForegroundWindow() was called might not exist anymore when GetWindowThreadProcessId() is called. Even worse situation would be if the same hwnd would be assigned to another window at that time, but I guess this should be really rare.

Community
  • 1
  • 1
svick
  • 236,525
  • 50
  • 385
  • 514
  • with this API and this function your assembly will be TR/Dropper.MSIL.Gen by some AV – Hichem Mar 09 '14 at 10:40
  • I haven't tested it, but [`GetProcessImageFileName`](https://msdn.microsoft.com/en-us/library/ms683217.aspx) might avoid the 64 bit problem. – CodesInChaos Aug 17 '15 at 11:07
  • 2
    using ``p.processName`` insted of ``p.MainModule.FileName`` avoids 32-64bit cant access error – bh_earth0 Feb 28 '18 at 11:26
9

I would suggest using System.Diagnostics.Process.

var currentProc = System.Diagnostics.Process.GetCurrentProcess();
string name = currentProc.ProcessName;

As an alternative you could use:

string name = currentProc.MainModule.FileName;
Ostemar
  • 5,778
  • 2
  • 19
  • 16
  • 11
    Because he mentions `GetForegroundWindow()`, I think he wants the process of the currently active window, not the current process. – svick Jul 04 '11 at 09:29
3

Its just need two line of code, you can use linq to get all processes.

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

Now you have all active process by just on line.

Marijn
  • 10,367
  • 5
  • 59
  • 80
khaled Dehia
  • 821
  • 7
  • 13
2

Here's a link describing the exact thing you want to do:

http://www.blackwasp.co.uk/GetActiveProcess.aspx

And another one describing the GetForegroundWindow function, which I copy below.

Note that you may need to reference some extra assemblies, for this code to work. Look at the MSDN for each function. Example, GetProcessesByName requires 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;
    }
} 
Gustavo Mori
  • 8,319
  • 3
  • 38
  • 52
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
        }
    }
Jamisco
  • 1,658
  • 3
  • 13
  • 17