首先是WMI方式:
引用System.Management.dll
private string GetProcessUserName(int pID)
{
string str = null;
SelectQuery query = new SelectQuery("Select * from Win32_Process WHERE processID=" + pID);
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
try
{
foreach (ManagementObject disk in searcher.Get())
{
ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
inPar = disk.GetMethodParameters("GetOwner");
outPar = disk.InvokeMethod("GetOwner", inPar, null);
str = outPar["User"].ToString();
break;
}
}
catch
{
str = "SYSTEM";
}
return str;
}
这种方式我没有成功,查找原因发现是执行效率极低,编译器判定超时。
然后是API方式,这个方法很赞:
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;
}