admin 管理员组

文章数量: 1086056

c# 之API获取进程用户名。

 

正在做一个小程序需要获取进程用户名,先在网上搜索得到下面代码。。可以用,但是效率之低下令人发指!

private static string GetProcessUserName(int pID)
{
    string text1 = null;

    SelectQuery query1 = new SelectQuery("Select * from Win32_Process WHERE processID=" + pID);
    ManagementObjectSearcher searcher1 = new ManagementObjectSearcher(query1);

    try
    {
        foreach (ManagementObject disk in searcher1.Get())
        {
            ManagementBaseObject inPar = null;
            ManagementBaseObject outPar = null;

            inPar = disk.GetMethodParameters("GetOwner");

            outPar = disk.InvokeMethod("GetOwner", inPar, null);

            text1 = outPar["User"].ToString();
            break;
        }
    }
    catch
    {
        text1 = "SYSTEM";
    }

    return text1;
}

后来在网上找到调用API的方法呵呵。。效果好多了,不过代码是易语言的。

下面是我翻译成c#代码:

sing System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace MyTool
{
    public class GetProcessUser
    {
        const int ERROR_NO_MORE_ITEMS = 259;
        [DllImport("wtsapi32", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool WTSEnumerateProcesses(
        IntPtr ProcessHandle, // 进程句柄
        int Reserved, // dmust be 0
        uint Version, // must be 1
        ref IntPtr ppProcessInfo, // 指向结构体的指针
        ref uint pCount // 进程数
        );
        [DllImport("wtsapi32.dll")]
        private static extern void WTSFreeMemory(ref WTS_PROCESS_INFO pMemory);
        [DllImport("advapi32", CharSet = CharSet.Auto)]
        static extern bool ConvertSidToStringSid(
        IntPtr pSID,
        [In, Out, MarshalAs(UnmanagedType.LPTStr)] ref string pStringSid);

        [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool LookupAccountSid
        (
        string lpSystemName, // 本地或远程计算机名称
        IntPtr pSid, // UserSid
        StringBuilder Account, // account name buffer
        ref int cbName, // Account长度
        StringBuilder DomainName, // domain name
        ref int cbDomainName, // DomainName长度
        ref int peUse // SID type
        );
        /// <summary>
        /// 从进程id获取进程用户名
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static string GetProcessUserNameById(int id)
        {
            if (id == 0 || id ==4)
            {
                return "SYSTEM";
            }
            IntPtr lngInfo = new IntPtr();
            uint lngCount = 0;
            IntPtr lngAddr;
            int lngTmp = 0;
            WTS_PROCESS_INFO objWtsProcessInfo = new WTS_PROCESS_INFO();
            bool lngRet = WTSEnumerateProcesses(IntPtr.Zero, 0, 1, ref lngInfo, ref lngCount);
            if (lngRet)
            {
                lngAddr = lngInfo;
                for (int i = 0; i < lngCount; i++)
                {
                    objWtsProcessInfo = (WTS_PROCESS_INFO)Marshal.PtrToStructure(lngAddr, typeof(WTS_PROCESS_INFO));


                    if (objWtsProcessInfo.ProcessID == id)
                    {

                        StringBuilder strUserName = new StringBuilder(255);
                        StringBuilder strDomain = new StringBuilder(255);
                        int a = 255;
                        int b = 255;
                        LookupAccountSid(null, objWtsProcessInfo.UserSid, strUserName, ref a, strDomain, ref b, ref lngTmp);
                        return strUserName.ToString();
                    }
                    lngAddr = (IntPtr)((int)lngAddr + Marshal.SizeOf(typeof(WTS_PROCESS_INFO)));
                }
                WTSFreeMemory(ref objWtsProcessInfo);
                return "获取失败";
            }
            return "获取失败";
           
        }

    }
    [StructLayout(LayoutKind.Sequential)]
    public struct WTS_PROCESS_INFO
    {
        public int SessionID;
        public int ProcessID;
        //指向进程名的文本指针
        public IntPtr ProcessName;
        public IntPtr UserSid;
    }
}

本文标签: c 之API获取进程用户名