C++ - 以管理员身份运行进程时的 GetUserName()
Posted
技术标签:
【中文标题】C++ - 以管理员身份运行进程时的 GetUserName()【英文标题】:C++ - GetUserName() when process is run as administrator 【发布时间】:2015-04-24 16:32:33 【问题描述】:我有一个提示用户名的简单 C++ 程序
#include <windows.h>
#include <Lmcons.h>
#include <winbase.h>
int _tmain(int argc, _TCHAR* argv[])
wchar_t username[UNLEN + 1];
DWORD username_len = UNLEN + 1;
::GetUserName(username, &username_len);
MessageBox(NULL, username, NULL, 1);
return 1;
GetUserName() 在管理员帐户中按预期执行,这意味着打印真实用户名。
但是,当在非管理员帐户中以管理员身份运行时,我得到的是管理员名称,而不是真正的登录用户。
我相信这种行为是意料之中的,因为它记录在 GetUserName():如果当前线程正在模拟另一个客户端,GetUserName 函数会返回该线程正在模拟的客户端的用户名。
问题
有没有办法获得真正的登录用户(非管理员用户),即使进程以管理员身份运行?
【问题讨论】:
上述“解决方案”不起作用。这样做:***.com/questions/5218778/… @UserX,该问题询问有关从服务获取当前登录用户的问题。这个问题询问如何从交互式应用程序中获取当前登录的用户。它们是不同的问题,需要不同的解决方案。 【参考方案1】:我相信你想问 Windows 的问题是“哪个用户登录到当前会话”。
为此,请使用您自己的进程 ID 调用 ProcessIdToSessionId() 以确定当前会话 ID。
然后使用WTSUserName
选项调用WTSQuerySessionInformation() 以获取用户名。
【讨论】:
根据msdn.microsoft.com/en-us/library/aa383838%28v=vs.85%29.aspx,不是 @igalk:XP 不受支持,因此文档中对它的引用正在慢慢消失。根据可靠消息来源,WTSQuerySessionInformation() 自 Windows 2000 以来就已可用。【参考方案2】:问题不在于冒充的线程。您正在管理员登录下运行整个应用程序。这就是为什么当您从非管理员帐户启动 Windows 时,它会要求您使用管理员帐户登录。
因此,您从GetUserName()
得到的结果是正确的。该名称是您应用的真实登录用户。
如果您想要其他名称,标准的解决方案是以普通用户身份启动,并使用“提升”按钮以提升的权限重新启动您的应用程序。看起来像任务管理器,如果您想查看所有正在运行的进程,它会执行此操作。此时,您当然可以将任何您想要的内容传递给新进程,包括该用户名。
【讨论】:
我想知道是否有一个选项可以让真正的登录用户使用提升的进程? @idanshmu:我认为这个问题没有明确定义。 什么真正的登录用户?因为就 Windows 而言,您提供了以管理员身份登录的管理员密码。那你怎么不是管理员? real 用户是激活进程的人,如果我以idan
登录并以管理员身份运行进程,real 用户是idan
。无论如何,我希望能够获得idan
而不是管理员名称。例如,有人告诉我,即使您以管理员身份运行该进程,活动桌面仍位于 真实 用户控件上。一定有办法得到这个名字。
好吧,桌面只是一个由 Explorer.Exe 进程管理的大窗口。这个过程大概有“idan”作为它的所有者。但出于安全原因,UIPI(UI 进程隔离)会将您的管理员应用程序与不太安全的进程分开。为什么你甚至需要这个名字?
我不想要进程用户名。无论我的应用程序以何种方式运行,我都希望能够获得 real 用户名。对我来说,GetUserName()
应该返回最后登录的用户(当然不包括由于提升的进程所需的日志记录)。以上是关于C++ - 以管理员身份运行进程时的 GetUserName()的主要内容,如果未能解决你的问题,请参考以下文章