将正在运行的程序的用户名与登录到Windows的用户名进行比较
Compare username of running program to username logged into Windows
我试图实现一个程序来控制登录计算机的用户和运行程序的用户的名称是否相同,但我认为我做错了什么。用户名登录的名称有效,但不是获取运行程序的用户的名称。
#include <Windows.h>
#include <iostream>
#include <stdlib.h>
#include <Lmcons.h>
#include <tchar.h>
#include <stdio.h>
#define INFO_BUFFER_SIZE 32767
using namespace std;
void Test() {
WCHAR UsernameSSR[INFO_BUFFER_SIZE];
TCHAR UsernameWindows[INFO_BUFFER_SIZE];
DWORD bufCharCountWindows = INFO_BUFFER_SIZE;
DWORD bufCharCountSSR = INFO_BUFFER_SIZE;
GetUserName(UsernameWindows, &bufCharCountWindows);
GetUserNameW(UsernameSSR, &bufCharCountSSR);
cout << UsernameWindows << " and " << UsernameSSR;
return;
}
GetUserName()
只是一个映射到GetUserNameA()
(ANSI(或GetUserNameW()
(Unicode(的预处理器宏,具体取决于您的项目设置。 无论哪种方式,GetUserName(A|W)
都会返回当前与调用线程关联的用户名,在您的示例中,该用户名也是用于运行程序的用户名。 没有GetUserNameA()
和GetUserNameW()
混合在一起会得到你想要的结果,因为它们将返回相同的用户名,只是在不同的字符编码中。
要获取登录到Windows本身的用户名,您需要一个不同的功能,例如WTSQuerySessionInformation()
(A或W变体(,例如:
#include <iostream>
#include <Windows.h>
#include <wtsapi32.h>
#include <Lmcons.h>
void Test()
{
WCHAR UsernameSSR[UNLEN+1];
DWORD bufCharCountSSR = UNLEN+1;
if (GetUserNameW(UsernameSSR, &bufCharCountSSR))
std::wcout << L"UsernameSSR: " << UsernameSSR << std::endl;
else
std::wcout << L"Error getting UserNameSSR" << std::endl;
// alternatively, use GetUserNameExW() instead...
LPWSTR UsernameWindows;
DWORD bufByteCountWindows;
if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSUserName, &UsernameWindows, &bufByteCountWindows))
{
LPWSTR Domain;
DWORD bufByteCountDomain;
std::wcout << L"UsernameWindows: ";
if (WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSDomainName, &Domain, &bufByteCountDomain))
{
if (*Domain)
std::wcout << Domain << L"\";
WTSFreeMemory(Domain);
}
std::wcout << UsernameWindows << std::endl;
WTSFreeMemory(UsernameWindows);
}
else
std::wcout << L"Error getting UserNameWindows" << std::endl;
// alternatively, query WTSQuerySessionInformation() for WTSSessionInfo, which
// returns both Domain and UserName in a single call, amongst other pieces of info...
}
话虽如此,比较用户名字符串并不是确定程序是否由登录到 Windows 的同一用户运行的最佳方法。
例如,另一种方法是获取运行程序的用户的安全标识符(SID(,然后将其与使用EqualSid()
登录到Windows的用户的SID进行比较。
获取调用进程的 SID 非常简单:可以使用GetCurrentProcessId()
、OpenProcessToken(TOKEN_QUERY)
和GetTokenInformation(TokenUser)
。
但是,获取已登录的 Windows 会话的 SID 有点棘手。 您可以:
获取登录用户的会话 ID,例如生成程序的父进程的
ProcessIdToSessionId()
或QueryTokenInformation(TokenSessionId)
(若要查找父进程 ID,请使用CreateToolhelp32Snapshot()
、Process32First()
和Process32Next()
(,然后将该会话 ID 传递给WTSQueryUserToken()
,然后从该令牌查询 SID。 问题是WTSQueryUserToken()
只能从LocalSystem
帐户下运行的服务调用,因此您必须编写这样的服务并通过您选择的 IPC 机制委托给它。如上所述检索用户会话的域\用户名,然后使用 WMI 查询该特定用户的
Win32_UserAccount
表并读取其Sid
属性,然后使用ConvertStringSidToSid()
将 SID 解析为其二进制形式。
您在第一个参数 (name
之后错过了,
:GetUserNameA((LPSTR)name(LPDWORD) & size)
另外,你为什么使用GetUserName
而不是GetUserNameW
?在某些情况下GetUserName
将与GetUserNameA
相同,因此,如果您尝试获得差异,请直接写GetUserNameW
。
- 是否有 Windows 用户空间函数来枚举连接的网络共享?
- Windows 后台服务(系统配置文件)无法使用 C++ 访问 win 10 上的用户 appData 文件夹?
- 通过JNA发送用户定义的Windows消息
- 当PSO细粒度策略对使用AdsGetObject MSDN API的Windows操作系统生效时,如何获取用户密码到期日
- 在Windows中将用户输入屏蔽为星号
- 检查用户是否是 Windows 中本地计算机上的管理员C++
- 如何通过Windows API获取所有(未禁用)用户SID?
- 如何从 Windows 上的服务在未登录用户的桌面上启动应用程序
- 将Windows SYSTEMTIME转换为字符串或字符buf,C++与用户的"Region and Language"格式?
- 从Windows上的系统工作的服务中获取用户文档文件夹.C++
- 获取 Windows 系统已加入 Azure AD 时登录用户的 UserPrincipalName
- 从 Windows KMD 调用用户空间 API 函数
- 标准Windows 7用户如何能够删除C:Program Files下的文件
- 如何在Windows控制台中禁用用户选择
- 仅通过帐户名来获取Windows用户帐户SID
- 如何检查用户登录到Windows的时间
- Windows:如何获取完整用户帐户
- 有任何替代SHGetKnownFolderPath的Windows XP用户令牌的方案吗
- 以系统用户 (Windows) 身份调用应用程序
- 如何创建桌面图标/按钮来启动用户Windows屏幕保护程序,并设置选项