2

I would like to know how to query for a process's owner in (or via) C#. I've tried the example at http://www.codeproject.com/KB/cs/processownersid.aspx.

WMI: Can query all process and their owners, but it's far too slow.

WIN32: Fast, but I get a permission denied exception when querying for owner of any process but my own.

I've tried to implement impersonation to solve the WIN32 issue, no go. I've also tried running the compiled .exe as an administrator, no go. I'm only a few months into this C# thing, so go easy.

BoggleKing
  • 23
  • 1
  • 4

2 Answers2

0

Seems like I've misunderstood the question first, sorry. Just found an interesting topic on the subject which may help you.

Oleg Kolosov
  • 1,588
  • 14
  • 12
0

I added the following to the Win32 example from: http://www.codeproject.com/KB/cs/processownersid.aspx

static void ProcessSID(Process process)
{
    string sid;
    ExGetProcessInfoByPID(process.Id, out sid);
    Console.WriteLine("{0} {1} {2}", process.Id, process.ProcessName, sid);
}

static void Main(string[] args)
{
    foreach (Process process in Process.GetProcesses())
    {
        ProcessSID(process);
    }
}

and when I run it as administrator it successfully prints the SIDs for all processes (except System and protected processes such as audiodg). It doesn't produce an access-denied error.

Does this code work for you?

I'm also using Windows 7 x64.

Update

This works for all processes except RunAs processes. The problem is the internals of Process.Handle, which ask for too many permissions.

If you replace the call to Process.Handle with

IntPtr procHandle=OpenProcess(ProcessAccessFlags.QueryInformation, false, PID);

and add the following definitions then the code also works with RunAs processes.

[Flags]
enum ProcessAccessFlags : uint
{
    All = 0x001F0FFF,
    Terminate = 0x00000001,
    CreateThread = 0x00000002,
    VMOperation = 0x00000008,
    VMRead = 0x00000010,
    VMWrite = 0x00000020,
    DupHandle = 0x00000040,
    SetInformation = 0x00000200,
    QueryInformation = 0x00000400,
    Synchronize = 0x00100000,
    ReadControl = 0x00020000
}

[DllImport("kernel32.dll")]
static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
arx
  • 16,686
  • 2
  • 44
  • 61
  • I'm sorry, I don't see how you added/changed anything from the posters original code. It looks as if you're just trying to show me how to utilize the code **Warlib** posted. In any case, it still is not showing the names of other users running processes. Create a user called *sampleuser*, shift-click Notepad and run-as, and see if you can see *sampleuser* displayed. – BoggleKing Jan 16 '12 at 02:08
  • "It looks as if you're just trying to show me how to utilize the code Warlib posted." Yes, I am. The code worked for me but didn't work for you so I posted what I did. Is that unhelpful? "Create a user called sampleuser, shift-click Notepad and run-as, and see if you can see sampleuser displayed." I see the SID for sampleuser, I don't see "sampleuser". That's what the code does. If you want to know how how to convert a SID to a user name, post another question. – arx Jan 16 '12 at 02:23
  • http://www.codeproject.com/Questions/314697/Csharp-query-for-process-owner-Windows-7-x64 I've posted my code. You may notice that I'm able to convert a SID to username. I still need help on understanding why I cannot see a process (eg Notepad) when I run-as sampleuser. Reiterating what Warlib posted, but not adding anything isn't helpful. – BoggleKing Jan 16 '12 at 02:43
  • My apologies. My code handled everything except the RunAs case and I hadn't noticed. I've posted a solution above. – arx Jan 16 '12 at 03:18
  • 1
    It should be noted, the codeproject post by WarLib is incomplete, code is taken almost wholesale from this post made years prior. http://www.pcreview.co.uk/forums/call-win32-native-api-gettokeninformation-using-c-t1351008.html – sean_m Apr 03 '14 at 17:30