由于手头上有个项目, 需要获得系统进程快照,并且要求能够获得系统的进程用户名,所以写了下试验函数,源码如下, 其中对OpenProcessToken函数失败的情况未进行进一步处理,而只是粗略的认为其为系统进程。其Release版本已经在WIN2000、XP、2003下测试成功,欢迎大家给予错误指定。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <Winbase.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include "Tlhelp32.h"
/************************************************************************/
/* 根据进程ID获得进程用户名 */
/* 成功返回0, 失败返回-1 */
/************************************************************************/
int PrintUserName(DWORD ProcessId, char *pUserName, int StrLen)
{
HANDLE hToken = NULL;
BOOL TokenRet = false;
PTOKEN_USER pTokenUser = NULL;
DWORD cb = 0;
SID_NAME_USE snu;
char domain[1024];
DWORD cbdomain = 1023;
memset(domain, 0, sizeof(domain));
//PROCESS_QUERY_INFORMATION方式打开进程
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, ProcessId);
if(!hProcess)
{
fprintf(stderr, "OpenProcess PROCESS_QUERY_INFORMATION方式 失败,GetLastError()=%d/n", GetLastError());
return -1;
}
//获得进程的令牌句柄,进行信息查询
TokenRet = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
if(!TokenRet) //如果失败
{
//关闭之前的句柄
if (hProcess)
{
CloseHandle(hProcess);
hProcess = NULL;
}
//更换打开权限方式
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, ProcessId);
if(!hProcess)
{
fprintf(stderr, "OpenProcess PROCESS_ALL_ACCESS 方式失败,GetLastError()=%d/n", GetLastError());
goto ERRORRETURN;
}
//重新获得进程的令牌句柄,进行信息查询
TokenRet = OpenProcessToken(hProcess,TOKEN_QUERY,&hToken);
if(!TokenRet)
{
fprintf(stderr, "/nOpenProcessToken 打开失败,GetLastError()=%d/n", GetLastError());
goto ERRORRETURN;
}
}
//获得信息的长度
TokenRet = GetTokenInformation(hToken, TokenUser/*TokenOwner*/, NULL, cb, &cb);
if(!TokenRet)
{
DWORD dwResult = GetLastError();
if ( dwResult != ERROR_INSUFFICIENT_BUFFER)
{
fprintf(stderr, "GetTokenInformation 失败,GetLastError()=%d/n", GetLastError());
goto ERRORRETURN;
}
}
//申请结构体空间
pTokenUser = (PTOKEN_USER) GlobalAlloc(GPTR, cb);
if (!pTokenUser)
{
fprintf(stderr, "GlobalAlloc 失败,GetLastError()=%d/n", GetLastError());
goto ERRORRETURN;
}
//获得信息
TokenRet = GetTokenInformation(hToken, TokenUser/*TokenOwner*/, pTokenUser, cb, &cb);
//获得进程用户名
TokenRet = LookupAccountSid(NULL,pTokenUser->User.Sid/*pto-> Owner*/
, pUserName, (unsigned long *)&StrLen, domain, &cbdomain, &snu);
if(!TokenRet)
{
goto ERRORRETURN;
}
//释放结构体空间
if (pTokenUser)
{
GlobalFree(pTokenUser);
pTokenUser = NULL;
}
//关闭句柄
if (hToken)
{
CloseHandle(hToken);
hToken = NULL;
}
//关闭句柄
if (hProcess)
{
CloseHandle(hProcess);
hProcess = NULL;
}
return 0;
//错误处理
ERRORRETURN:
//释放结构体空间
if (pTokenUser)
{
GlobalFree(pTokenUser);
pTokenUser = NULL;
}
//关闭句柄
if (hToken)
{
CloseHandle(hToken);
hToken = NULL;
}
//关闭句柄
if (hProcess)
{
CloseHandle(hProcess);
hProcess = NULL;
}
return -1;
}
int main()
{
HANDLE hSnapShot = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pEntry;
struct _timeb tstruct1, tstruct2;
char ProceUserName[100];
int Retcode = 0;
memset(&pEntry, 0, sizeof(pEntry));
memset(ProceUserName, 0, sizeof(ProceUserName));
//获得初始时间
_ftime(&tstruct1);
//给定大小
pEntry.dwSize = sizeof(pEntry);
//获得系统快照
hSnapShot = CreateToolhelp32Snapshot (TH32CS_SNAPALL, NULL);
if (hSnapShot == INVALID_HANDLE_VALUE)
return -1;
//获得第一个进程
Process32First(hSnapShot, &pEntry);
for(;;)
{
//获得下一进程
BOOL hRes=Process32Next (hSnapShot,&pEntry);
if(hRes == FALSE)
break;
//获得进程用户名
Retcode = PrintUserName(pEntry.th32ProcessID, ProceUserName, sizeof(ProceUserName)-1);
if (Retcode != 0)
{
sprintf(ProceUserName, "SYSTEM");
}
printf("%s/t", pEntry.szExeFile);
printf("%s/t", ProceUserName);
// printf("%d/t", pEntry.th32ProcessID);
// printf("%d/t", pEntry.cntThreads);
printf("/n");
}
if (hSnapShot)
{
CloseHandle (hSnapShot);
hSnapShot = NULL;
}
_ftime( &tstruct2 );
//打印时间
if (tstruct2.time == tstruct1.time)
printf( "使用时间 milliseconds:/t/t/t%d/n", tstruct2.millitm - tstruct1.millitm);
else if (tstruct2.time > tstruct1.time)
{
printf( "使用时间 milliseconds:/t/t/t%d/n"
, tstruct2.time*1000 - tstruct1.time*1000 + tstruct2.millitm - tstruct1.millitm);
}
return 0;
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <Winbase.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include "Tlhelp32.h"
/************************************************************************/
/* 根据进程ID获得进程用户名 */
/* 成功返回0, 失败返回-1 */
/************************************************************************/
int PrintUserName(DWORD ProcessId, char *pUserName, int StrLen)
{
HANDLE hToken = NULL;
BOOL TokenRet = false;
PTOKEN_USER pTokenUser = NULL;
DWORD cb = 0;
SID_NAME_USE snu;
char domain[1024];
DWORD cbdomain = 1023;
memset(domain, 0, sizeof(domain));
//PROCESS_QUERY_INFORMATION方式打开进程
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, ProcessId);
if(!hProcess)
{
fprintf(stderr, "OpenProcess PROCESS_QUERY_INFORMATION方式 失败,GetLastError()=%d/n", GetLastError());
return -1;
}
//获得进程的令牌句柄,进行信息查询
TokenRet = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken);
if(!TokenRet) //如果失败
{
//关闭之前的句柄
if (hProcess)
{
CloseHandle(hProcess);
hProcess = NULL;
}
//更换打开权限方式
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, ProcessId);
if(!hProcess)
{
fprintf(stderr, "OpenProcess PROCESS_ALL_ACCESS 方式失败,GetLastError()=%d/n", GetLastError());
goto ERRORRETURN;
}
//重新获得进程的令牌句柄,进行信息查询
TokenRet = OpenProcessToken(hProcess,TOKEN_QUERY,&hToken);
if(!TokenRet)
{
fprintf(stderr, "/nOpenProcessToken 打开失败,GetLastError()=%d/n", GetLastError());
goto ERRORRETURN;
}
}
//获得信息的长度
TokenRet = GetTokenInformation(hToken, TokenUser/*TokenOwner*/, NULL, cb, &cb);
if(!TokenRet)
{
DWORD dwResult = GetLastError();
if ( dwResult != ERROR_INSUFFICIENT_BUFFER)
{
fprintf(stderr, "GetTokenInformation 失败,GetLastError()=%d/n", GetLastError());
goto ERRORRETURN;
}
}
//申请结构体空间
pTokenUser = (PTOKEN_USER) GlobalAlloc(GPTR, cb);
if (!pTokenUser)
{
fprintf(stderr, "GlobalAlloc 失败,GetLastError()=%d/n", GetLastError());
goto ERRORRETURN;
}
//获得信息
TokenRet = GetTokenInformation(hToken, TokenUser/*TokenOwner*/, pTokenUser, cb, &cb);
//获得进程用户名
TokenRet = LookupAccountSid(NULL,pTokenUser->User.Sid/*pto-> Owner*/
, pUserName, (unsigned long *)&StrLen, domain, &cbdomain, &snu);
if(!TokenRet)
{
goto ERRORRETURN;
}
//释放结构体空间
if (pTokenUser)
{
GlobalFree(pTokenUser);
pTokenUser = NULL;
}
//关闭句柄
if (hToken)
{
CloseHandle(hToken);
hToken = NULL;
}
//关闭句柄
if (hProcess)
{
CloseHandle(hProcess);
hProcess = NULL;
}
return 0;
//错误处理
ERRORRETURN:
//释放结构体空间
if (pTokenUser)
{
GlobalFree(pTokenUser);
pTokenUser = NULL;
}
//关闭句柄
if (hToken)
{
CloseHandle(hToken);
hToken = NULL;
}
//关闭句柄
if (hProcess)
{
CloseHandle(hProcess);
hProcess = NULL;
}
return -1;
}
int main()
{
HANDLE hSnapShot = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pEntry;
struct _timeb tstruct1, tstruct2;
char ProceUserName[100];
int Retcode = 0;
memset(&pEntry, 0, sizeof(pEntry));
memset(ProceUserName, 0, sizeof(ProceUserName));
//获得初始时间
_ftime(&tstruct1);
//给定大小
pEntry.dwSize = sizeof(pEntry);
//获得系统快照
hSnapShot = CreateToolhelp32Snapshot (TH32CS_SNAPALL, NULL);
if (hSnapShot == INVALID_HANDLE_VALUE)
return -1;
//获得第一个进程
Process32First(hSnapShot, &pEntry);
for(;;)
{
//获得下一进程
BOOL hRes=Process32Next (hSnapShot,&pEntry);
if(hRes == FALSE)
break;
//获得进程用户名
Retcode = PrintUserName(pEntry.th32ProcessID, ProceUserName, sizeof(ProceUserName)-1);
if (Retcode != 0)
{
sprintf(ProceUserName, "SYSTEM");
}
printf("%s/t", pEntry.szExeFile);
printf("%s/t", ProceUserName);
// printf("%d/t", pEntry.th32ProcessID);
// printf("%d/t", pEntry.cntThreads);
printf("/n");
}
if (hSnapShot)
{
CloseHandle (hSnapShot);
hSnapShot = NULL;
}
_ftime( &tstruct2 );
//打印时间
if (tstruct2.time == tstruct1.time)
printf( "使用时间 milliseconds:/t/t/t%d/n", tstruct2.millitm - tstruct1.millitm);
else if (tstruct2.time > tstruct1.time)
{
printf( "使用时间 milliseconds:/t/t/t%d/n"
, tstruct2.time*1000 - tstruct1.time*1000 + tstruct2.millitm - tstruct1.millitm);
}
return 0;
}