王朝网络
分享
 
 
 

如何获取Windows系统登陆用户名

王朝vc·作者佚名  2006-01-17
宽屏版  字体: |||超大  

如何获取Windows系统登陆用户名

作者:yy2better

下载源代码

关键字:获取登陆用户名 GetUserName WTSQuerySessionInformation

一般用 GetUserName(或 GetUserNameEx )函数可得到当前登陆登陆用户名(但不总会得到,下面会分析),此系统函数在Win95、WinNT 及以后所有操作系统中都可用。代码如下:BOOL CSecurityTool::GetCurrProcessUser(CString& strName)

{

BOOL bRet(TRUE);

strName = _T("");

DWORD dwSize = MAX_PATH;

TCHAR *pszName = new TCHAR[dwSize];

if (!GetUserName(pszName, &dwSize))

{

delete[] pszName;

pszName = new TCHAR[dwSize];

bRet = GetUserName(pszName, &dwSize);

}

strName = pszName;

delete[] pszName;

return bRet;

}

此函数目的准确来说是获取当前线程的用户名(MSDN语:retrieves the user name of the current thread)。如果是NT service(NT服务程序)将此进程启动,得到的结果是NT Service进程的用户名,即“SYSTEM”,而不是登陆用户名;同理,如果此进程是通过CreateProcessAsUser创建的,GetUserName获取的用户将是“AsUser”的用户名。另外,如果当前线程正impersonate其他用户环境(用函数ImpersonateLoggedOnUser可达到此目的),它获取的将是其他用户名。因此,此函数只能在特定环境中才可以获取登陆用户名。

那如何不因进程本身运行环境的不同,而准确地获取登陆用户名呢?

我们首先看看Windows XP操作系统,它提供了WTSQuerySessionInformation函数,这个函数可以获取会话(session)相关信息,其中一个用

途是获取会话的登陆用户。代码如下:

BOOL CSecurityTool::GetLogUserXP(CString& strName)

{

BOOL bRet = FALSE;

strName = _T("");

//for xp or above

TCHAR *szLogName = NULL;

DWORD dwSize = 0;

if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE,

WTS_CURRENT_SESSION,

WTSUserName,

&szLogName,

&dwSize))

{

strName = szLogName;

WTSFreeMemory(szLogName);

bRet = TRUE;

}

return bRet;

}

如果用户还没有登陆,获取的用户名将为空(譬如在NT service程序中)。虽然MSDN中指明WTSQuerySessionInformation可以在win2000 pro

中使用,但由于安装win2000 professional时,terminal service是没有安装的(除非用特殊方法如第三方工具可以安装terminal service)

,所以调用此函数会失败,需要寻找其他方法。

再看Win2000:查阅了许多资料,未能发现在Win2000中直接获取登陆用户名的系统函数,看来只有曲线救国了。由于Explorer.exe进程的用户肯定是当前登

陆用户,所以获取到它的用户名就等于获取到登陆用户名。具体实现:首先枚举系统所有进程,找到Explorer.exe进程ID,然后通过ID获取此

进程的令牌(Token),再获取令牌的用户信息,即为登陆用户名。代码如下:

//获取win2000登陆用户

BOOL CSecurityTool::GetLogUser2K(CString& strName)

{

BOOL bRet = FALSE;

HANDLE hSnapshot = NULL;

strName = _T("");

__try

{

// Get a snapshot of the processes in the system

hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (hSnapshot == NULL)

{

__leave;

}

PROCESSENTRY32 pe32;

pe32.dwSize = sizeof(pe32);

// Find the "System" process

BOOL fProcess = Process32First(hSnapshot, &pe32);

while (fProcess)

{

if (lstrcmpi(pe32.szExeFile, TEXT("explorer.exe")) == 0)

{

TCHAR szUserName[MAX_PATH];

if (GetProcessUser(pe32.th32ProcessID, szUserName, MAX_PATH))

{

bRet = TRUE;

strName = szUserName;

}

break;

}

fProcess = Process32Next(hSnapshot, &pe32);

}

if (!fProcess)

{

__leave; // Didn''t find "System" process

}

}

__finally

{

// Cleanup the snapshot

if (hSnapshot != NULL)

CloseHandle(hSnapshot);

}

return bRet;

}

//获取进程的用户名

BOOL CSecurityTool::GetProcessUser(DWORD dwProcessID, TCHAR *szUserName, DWORD nNameLen)

{

BOOL fResult = FALSE;

HANDLE hProc = NULL;

HANDLE hToken = NULL;

TOKEN_USER *pTokenUser = NULL;

__try

{

// Open the process with PROCESS_QUERY_INFORMATION access

hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcessID);

if (hProc == NULL)

{

__leave;

}

fResult = OpenProcessToken(hProc, TOKEN_QUERY, &hToken);

if(!fResult)

{

__leave;

}

DWORD dwNeedLen = 0;

fResult = GetTokenInformation(hToken,TokenUser, NULL, 0, &dwNeedLen);

if (dwNeedLen 0)

{

pTokenUser = (TOKEN_USER*)new BYTE[dwNeedLen];

fResult = GetTokenInformation(hToken,

TokenUser,

pTokenUser,

dwNeedLen,

&dwNeedLen);

if (!fResult)

{

__leave;

}

}

else

{

__leave;

}

SID_NAME_USE sn;

TCHAR szDomainName[MAX_PATH];

DWORD dwDmLen = MAX_PATH;

fResult = LookupAccountSid(NULL,

pTokenUser-User.Sid,

szUserName,

&nNameLen,

szDomainName,

&dwDmLen,

&sn);

}

__finally

{

if (hProc)

::CloseHandle(hProc);

if (hToken)

::CloseHandle(hToken);

if (pTokenUser)

delete[] (char*)pTokenUser;

return fResult;

}

}

熟悉win2000系统的同仁肯定会发现此方法存在缺陷:explorer.exe进程可能不存在(被用户kill掉或自己中断了),这时候这个方法就获取不到登陆用户名。但在没有更好方法前,只能将就。

总结

因此,软件中如果需要获取登陆用户名,要根据具体情况选择不同的方法。如果确信自己的进程一定在登陆用户环境下启动,则GetUserName即可;否则,需要采用后面的两种方法,当然,在使用前需要判断一下操作系统的类型。附

源代码

欢迎诸位与大家分享其他方法。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有