获取windows当前登录的用户名

参考:

  1. GetUserNameA function (winbase.h) - Win32 apps | Microsoft Docs
  2. Getting System Information - Win32 apps | Microsoft Docs
  3. WINDOWS-API:取得当前用户账户名-GetUserName - CPYER - 博客园
  4. 获取windows当前登录的用户名_kevin的博客-CSDN博客_windows用户名

公司项目有个要求,就是要获取windows当前登录的用户名作为安装路径的一部分,于是百度很容易地找到了GetUserName这个windows提供的方法。

本以为一切就是这么简单,后来才发现,GetUserName返回的只是当前线程关联的用户名。

Retrieves the name of the user associated with the current thread.

也就是说,这个用户名就是任务管理器中显示的用户名。如果这个线程是以system权限运行的,返回的就是system,而不是windows当前登录的用户名!

感谢获取windows当前登录的用户名_kevin的博客-CSDN博客_windows用户名这位博主的文章给了我很大的帮助!

文章中的法1还是会返回system,这里采用文章中的法2:获取explorer.exe的用户名,但是NetUserGetInfo会返回失败,导致一度认为哪里有问题,其实LookupAccountSid就已经获取到用户名了。这里改进下代码,同时优化下获取explorer.exe的方式,无需像原来那样通过遍历的方式找到explorer.exe。(而且遍历的方式也有一个问题,就是多个用户使用同一台机的时候,切换到其他用户的桌面,找到的explorer.exe,不一定是当前登录的用户的,还可能是其他已登录的用户的!)

#include <windows.h>
#include <string>
#include <algorithm>

bool Get_LogUser(std::wstring& wsName)
{
	HWND hwnd = ::GetShellWindow();
	if (nullptr == hwnd) {
		return false;
	}

	DWORD dwProcessID = 0;
	GetWindowThreadProcessId(hwnd, &dwProcessID);
	if (0 == dwProcessID) {
		return false;
	}

	HANDLE hProc = NULL;
	HANDLE hToken = NULL;
	TOKEN_USER* pTokenUser = NULL;

	// Open the process with PROCESS_QUERY_INFORMATION access
	hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessID);
	if (hProc == NULL)
	{
		return false;
	}
	if (!OpenProcessToken(hProc, TOKEN_QUERY, &hToken))
	{
		return false;
	}

	DWORD dwNeedLen = 0;
	GetTokenInformation(hToken, TokenUser, NULL, 0, &dwNeedLen);
	if (dwNeedLen > 0)
	{
		pTokenUser = (TOKEN_USER*)new BYTE[dwNeedLen];
		if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dwNeedLen, &dwNeedLen))
		{
			return false;
		}
	}
	else
	{
		return false;
	}

	SID_NAME_USE sn;
	TCHAR szDomainName[MAX_PATH];
	DWORD dwDmLen = MAX_PATH;

	WCHAR wstrName[MAX_PATH] = {};
	DWORD nNameLen = MAX_PATH;
	LookupAccountSid(NULL, pTokenUser->User.Sid, wstrName, &nNameLen,
		szDomainName, &dwDmLen, &sn);

	wsName = wstrName;

	if (hProc)
		::CloseHandle(hProc);
	if (hToken)
		::CloseHandle(hToken);
	if (pTokenUser)
		delete[](char*)pTokenUser;

	//LPUSER_INFO_3 bufptr = NULL;
	//NET_API_STATUS t3;
	//t3 = NetUserGetInfo(0, wstrName, 3, (LPBYTE*)&bufptr);
	//if (t3 != NERR_Success)
	//{
	//	return;
	//}

	//全名不为空,就使用用户名的全名,为空就使用用户名
	//CString strFullName = bufptr->usri3_full_name;
	//if (strFullName.IsEmpty())
	//{
	//	csName = bufptr->usri3_name;
	//}
	//else
	//{
	//	csName = bufptr->usri3_full_name;
	//}

	//NetApiBufferFree(bufptr);
	//bufptr = NULL;

	return true;
}

bool GetCurrentProcessUser(std::wstring& wstrUserName)
{
    bool bRet = false;
    wstrUserName.clear();
    try
    {
        DWORD dwSize = MAX_PATH;
        TCHAR* pszName = new TCHAR[dwSize];

        // Get and display the user name. 
        bRet = GetUserName(pszName, &dwSize);
        if (!bRet)
        {
            // If lpBuffer is too small, the function failsand GetLastError returns ERROR_INSUFFICIENT_BUFFER.
            // This parameter receives the required buffer size, including the terminating null character.
            delete[] pszName;
            pszName = new TCHAR[dwSize];
            bRet = GetUserName(pszName, &dwSize);
        }

        if (pszName != NULL)
        {
            wstrUserName = pszName;
            delete[] pszName;
        }

        std::transform(wstrUserName.begin(), wstrUserName.end(), wstrUserName.begin(), std::tolower);
        if (!wstrUserName.compare(L"system"))
        {
            wstrUserName.clear();
			bRet = Get_LogUser(wstrUserName);
        }
    }
    catch (...)
    {
        bRet = false;
    }

    return bRet;
}

void main()
{
    std::wstring wstrUserName;
    GetCurrentProcessUser(wstrUserName);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值