Click here to Skip to main content
15,885,309 members
Articles / Programming Languages / C#

How to Get Elevated Process Path in .NET

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
23 Dec 2011CPOL 19K   6   2
How to Get Elevated Process Path in .NET

As you know, retrieving process path in .NET is quite straightforward. For example, if you have process instance someProcess you can get the process path by accessing someProcess.MainModule.FileName. However, for elevated processes, the previous code snippet throws Win32Exception.

As you have probably guessed, the reason is related to the bugs I mentioned in my previous post. In this case too, the Process class is using PROCESS_QUERY_INFORMATION access right to open the desired process. The difference from the previous case is that in order to get the main module and process path, the code really needs PROCESS_QUERY_INFORMATION so we cannot simply change it with PROCESS_QUERY_LIMITED_INFORMATION.

Fortunately, Microsoft has introduced a new function for getting process path QueryFullProcessImageName which does work with PROCESS_QUERY_LIMITED_INFORMATION access right. To call the function, we need to open the process ourselves and pass the handle.

C#
private static string GetExecutablePath(Process Process)
{
    //If running on Vista or later use the new function
    if (Environment.OSVersion.Version.Major >= 6)
    {
        return GetExecutablePathAboveVista(Process.Id);
    }

    return Process.MainModule.FileName;
}

private static string GetExecutablePathAboveVista(int ProcessId)
{
    var buffer = new StringBuilder(1024);
    IntPtr hprocess = OpenProcess(ProcessAccessFlags.PROCESS_QUERY_LIMITED_INFORMATION,
                                  false, ProcessId);
    if (hprocess != IntPtr.Zero)
    {
        try
        {
            int size = buffer.Capacity;
            if (QueryFullProcessImageName(hprocess, 0, buffer, out size))
            {
                return buffer.ToString();
            }
        }
        finally
        {
            CloseHandle(hprocess);
        }
    }
    throw new Win32Exception(Marshal.GetLastWin32Error());
}

[DllImport("kernel32.dll")]
private static extern bool QueryFullProcessImageName(IntPtr hprocess, int dwFlags,
               StringBuilder lpExeName, out int size);
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess,
               bool bInheritHandle, int dwProcessId);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hHandle);

You can turn the above code snippet into an extension method too. If you want Microsoft to add a new property for easily getting the process path, vote for this suggestion at the connect website: Add Path property to Process class so that it works with elevated processes too.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Georgia Georgia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionfeedback Pin
Member 1334938631-Aug-17 21:48
Member 1334938631-Aug-17 21:48 
QuestionProcessAccessFlags Pin
mikegrey2814-Mar-15 5:59
mikegrey2814-Mar-15 5:59 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.