服务程序中如何得到当前登陆用户名

 

这也是开发当中经常遇到的一个问题,因为服务程序是用system身份运行的,所以如果直接使用getusername是不行的。但是如果用我上一篇文章中的思路,那么这个问题同样也可以迎刃而解了。方法就是可以通过取得shell的token,根据这个token来得到Sid,在根据Sid来得到当前登陆的用户名和domain。下面是示例代码:

 

//根据进程名称得到进程token
BOOL GetTokenByName(HANDLE &hToken,LPSTR lpName)
{
	if(!lpName)
	{
		return FALSE;
	}
	HANDLE         hProcessSnap = NULL; 
	BOOL           bRet      = FALSE; 
	PROCESSENTRY32 pe32      = {0}; 

	hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == INVALID_HANDLE_VALUE) 
		return (FALSE); 

	pe32.dwSize = sizeof(PROCESSENTRY32); 

	if (Process32First(hProcessSnap, &pe32)) 
	{
		do 
		{
			if(!strcmp(_strupr(pe32.szExeFile),_strupr(lpName)))
			{
				HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
					FALSE,pe32.th32ProcessID);
				bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS,&hToken);
				CloseHandle (hProcessSnap); 
				return (bRet);
			}
		} 
		while (Process32Next(hProcessSnap, &pe32)); 
		bRet = TRUE; 
	} 
	else 
		bRet = FALSE;

	CloseHandle (hProcessSnap); 
	return (bRet);
}

BOOL GetCurrentUserName()
{
	HANDLE hToken;

	//得到shell的token
	if(!GetTokenByName(hToken,"EXPLORER.EXE"))
	{
		return FALSE;
	}
	DWORD        cbti     = 0;
	PTOKEN_USER  ptiUser  = NULL;
	SID_NAME_USE snu;

	//取得所需空间大小
	if (GetTokenInformation(hToken, TokenUser, NULL, 0, &cbti)) 
	{
		CloseHandle(hToken);
		return FALSE;
	}

	//分配空间
	ptiUser = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbti);
	if(!ptiUser)
	{
		CloseHandle(hToken);
		return FALSE;
	}

	//取得token信息
	if (!GetTokenInformation(hToken, TokenUser, ptiUser, cbti, &cbti))
	{
		CloseHandle(hToken);
		HeapFree(GetProcessHeap(), 0, ptiUser);
		return FALSE;
	}

	char szUser[50];
	char szDomain[50];
	DWORD nUser = 50;
	DWORD nDomain = 50;

	//根据用户的sid得到用户名和domain

	if (!LookupAccountSid(NULL, ptiUser->User.Sid, szUser, &nUser, 
		szDomain, &nDomain, &snu))
	{
		CloseHandle(hToken);
		HeapFree(GetProcessHeap(), 0, ptiUser);
		return FALSE;
	}
	OutputDebugString(szUser);
	OutputDebugString("\r\n");
	OutputDebugString(szDomain);
	OutputDebugString("\r\n");

	CloseHandle(hToken);
	HeapFree(GetProcessHeap(), 0, ptiUser);
	return TRUE;
}

在 Windows 服务程序,可以通过调用 Windows API 来获取当前是否有用户登录,以及当前登录用户的用户名。以下是获取信息的示例代码: ```cpp #include <Windows.h> #include <TlHelp32.h> BOOL IsUserLoggedOn() { // 获取当前登录会话的 ID DWORD session_id = WTSGetActiveConsoleSessionId(); // 获取进程快照 HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (snapshot == INVALID_HANDLE_VALUE) { return FALSE; } // 遍历进程列表,查找 explorer.exe 进程 PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); BOOL bRet = Process32First(snapshot, &pe); while (bRet) { if (_tcsicmp(pe.szExeFile, _T("explorer.exe")) == 0) { // 获取 explorer.exe 进程所属的登录会话 ID DWORD explorer_session_id; WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, pe.th32ProcessID, WTSConnectState, (LPTSTR*)&explorer_session_id, NULL); // 如果与当前登录会话 ID 相同,则表示有用户登录 if (explorer_session_id == session_id) { CloseHandle(snapshot); return TRUE; } } bRet = Process32Next(snapshot, &pe); } CloseHandle(snapshot); return FALSE; } BOOL GetLoggedOnUserName(LPTSTR szUserName, DWORD* pdwSize) { // 获取当前登录会话的 ID DWORD session_id = WTSGetActiveConsoleSessionId(); // 获取当前登录会话的用户名 WCHAR* pUserName; DWORD dwSize; if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id, WTSUserName, &pUserName, &dwSize)) { wcsncpy_s(szUserName, *pdwSize, pUserName, dwSize); *pdwSize = dwSize; WTSFreeMemory(pUserName); return TRUE; } return FALSE; } ``` `IsUserLoggedOn()` 函数用于检查当前是否有用户登录。该函数遍历进程列表,查找 explorer.exe 进程,并获取该进程所属的登录会话 ID。如果该 ID 与当前登录会话的 ID 相同,则表示有用户登录。 `GetLoggedOnUserName()` 函数用于获取当前登录用户的用户名。该函数调用 `WTSQuerySessionInformation` API 来获取当前登录会话的用户名。如果获取成功,则将用户名复制到 `szUserName` 缓冲区,并将缓冲区大小更新为用户名长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值