Click here to Skip to main content
15,888,008 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,
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.
Posted

1 solution

The following is as far as I've gotten. If you create a user called sampleuser and do a "run-as" on Notepad as that account, the following code doesn't show sampleuser



C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Windows.Forms;
using System.Timers;
using System.Threading;
using HANDLE = System.IntPtr;
using System.Security.Permissions;
using System.DirectoryServices.AccountManagement; 

namespace ConsoleApplication2
{
    class Program
    {
        enum TOKEN_INFORMATION_CLASS
        {
            TokenUser = 1,
            TokenGroups,
            TokenPrivileges,
            TokenOwner,
            TokenPrimaryGroup,
            TokenDefaultDacl,
            TokenSource,
            TokenType,
            TokenImpersonationLevel,
            TokenStatistics,
            TokenRestrictedSids,
            TokenSessionId
        }

        [StructLayout(LayoutKind.Sequential)]
        struct TOKEN_USER
        {
            public _SID_AND_ATTRIBUTES User;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _SID_AND_ATTRIBUTES
        {
            public IntPtr Sid;
            public int Attributes;
        }

        [DllImport("advapi32")]
        static extern bool OpenProcessToken(
            HANDLE ProcessHandle, // handle to process
            int DesiredAccess, // desired access to process
            ref IntPtr TokenHandle // handle to open access token
        );

        [DllImport("kernel32")]
        static extern HANDLE GetCurrentProcess();

        [DllImport("advapi32", CharSet = CharSet.Auto)]
        static extern bool GetTokenInformation(
            HANDLE hToken,
            TOKEN_INFORMATION_CLASS tokenInfoClass,
            IntPtr TokenInformation,
            int tokeInfoLength,
            ref int reqLength
        );

        [DllImport("kernel32")]
        static extern bool CloseHandle(HANDLE handle);

        [DllImport("advapi32", CharSet = CharSet.Auto)]
        static extern bool ConvertSidToStringSid(
            IntPtr pSID,
            [In, Out, MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid
        );



        static void Main(string[] args)
        {
            try
            {
                foreach (Process theprocess in Process.GetProcesses())
                {
                    string samAccountname = string.Empty;
                    string SID;
                    string process = ExGetProcessInfoByPID(theprocess.Id, out SID);

                    //Convert the user SID to a domain\name
                    if (SID != "")
                    {
                        samAccountname = new SecurityIdentifier(SID).Translate(typeof(NTAccount)).ToString();
                    }

                    Console.WriteLine("Process ID: " + theprocess.Id);
                    Console.WriteLine("Process Name: " + theprocess.ProcessName);
                    Console.WriteLine("User Executing: " + samAccountname);
                    Console.WriteLine();
                }
            }
            catch (Exception myException)
            {
                myException.ToString();
            }
            Console.ReadLine();
        }

        public static bool DumpUserInfo(HANDLE pToken, out IntPtr SID)
        {
            HANDLE procToken = IntPtr.Zero;
            bool ret = false;
            SID = IntPtr.Zero;
            try
            {
                if (OpenProcessToken(pToken, 0X00000008, ref procToken))
                {
                    WindowsIdentity wi = new WindowsIdentity(procToken);
                    ret = ProcessTokenToSid(procToken, out SID);
                    CloseHandle(procToken);
                }
                return ret;
            }
            catch
            {
                return false;
            }
        }

        private static bool ProcessTokenToSid(HANDLE token, out IntPtr SID)
        {
            TOKEN_USER tokUser;
            const int bufLength = 256;
            IntPtr tu = Marshal.AllocHGlobal(bufLength);
            bool ret = false;
            SID = IntPtr.Zero;
            try
            {
                int cb = bufLength;
                ret = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenUser, tu, cb, ref cb);
                if (ret)
                {
                    tokUser = (TOKEN_USER)Marshal.PtrToStructure(tu, typeof(TOKEN_USER));
                    SID = tokUser.User.Sid;
                }
                return ret;
            }
            catch
            {
                return false;
            }
            finally
            {
                Marshal.FreeHGlobal(tu);
            }
        }

        public static string ExGetProcessInfoByPID(int PID, out string SID)
        {
            IntPtr _SID = IntPtr.Zero;
            SID = String.Empty;
            try
            {
                Process process = Process.GetProcessById(PID);
                if (DumpUserInfo(process.Handle, out _SID))
                {
                    ConvertSidToStringSid(_SID, ref SID);
                }
                return process.ProcessName;
            }
            catch
            {
                return "Unknown";
            }
        }

    }
}
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900