gpt4 book ai didi

c++ - 作为服务运行时,获取 C++ 中的当前登录用户名不显示任何内容

转载 作者:行者123 更新时间:2023-11-28 00:07:01 24 4
gpt4 key购买 nike

这是我的代码。我在 Release模式下编译并运行它。它打印输出。我在链接器中添加了库作为 wtsapi32.lib。

 #include "stdafx.h"
#include <windows.h>
#include <conio.h>
#include <iostream>
#include <tchar.h>
#include <wtsapi32.h>
#include <atlstr.h>
#include <string>

#define INFO_BUFFER_SIZE 32767

int _tmain(int argc, _TCHAR* argv[])
{
//bool pidToSessionId = ProcessIdToSessionId(GetCurrentProcessId(),_Out_ DWORD *pSessionId);
DWORD*pSessionId = (DWORD*)malloc(sizeof(DWORD));
bool pidToSessionId = ProcessIdToSessionId(GetCurrentProcessId(),pSessionId);
std::cout << *pSessionId << std::endl;

LPWSTR*infoBuf = (LPWSTR*)malloc(sizeof(LPWSTR));
DWORD bufCharCount = INFO_BUFFER_SIZE;

WTSQuerySessionInformation(NULL, *pSessionId,/**_WTS_INFO_CLASS.*/WTSUserName, infoBuf, &bufCharCount);
std::wcout << *infoBuf << std::endl;

std::string st = CW2A(*infoBuf);
std::cout << st << std::endl;

_getch();
return 0;
}

我需要将其作为服务运行。然后我用 nssm https://nssm.cc/ 安装它并设置一个文件来打印输出。 nssm 允许您打印文件中的输出。但它只打印 pSessionId。我的代码有什么问题?谁能说说原因?

最佳答案

首先,您使用 malloc() 分配指针变量既浪费又不必要,更不用说您正在泄漏正在分配的内存。只需在堆栈上声明指针即可,这样更容易也更安全。

其次,在 Vista 及更高版本中,所有服务都在 Session 0 中运行,用户登录到 Session 1 及更高版本。这被称为 Session 0 Isolation :

Services have always run in session 0. Before Windows Vista, the first user to log on was also assigned to session 0. Now, session 0 is reserved exclusively for services and other applications not associated with an interactive user session. (The first user to log on is connected to session 1, the second user to log on is connected to session 2, and so on.) Session 0 does not support processes that interact with the user.

This change means that a service cannot post or send a message to an application and an application cannot send or post a message to a service. In addition, services cannot display a user interface item such as a dialog box directly. A service can use the WTSSendMessage function to display a dialog box in another session.

Impact of Session 0 Isolation on Services and Drivers in Windows

Session 0 isolation: Where backward compatibility loses to security

要从服务内部查找登录用户,您必须使用 WTSEnumerateSessions() 枚举可用 session ,在每个上调用 WTSQuerySessionInformation()(您也可以在 Win2000 和 XP 中执行此操作,它们允许用户登录到 Session 0)。并且不要忘记释放 WTS 函数返回给您的所有内存缓冲区。

第三,您根本没有进行任何错误处理。

尝试更像这样的东西:

int _tmain(int argc, _TCHAR* argv[])
{
PWTS_SESSION_INFO pSessions = NULL;
DWORD dwCount = 0;
DWORD dwError;

if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessions, &dwCount))
{
dwError = GetLastError();
std::cout << "Error enumerating sessions: " << dwError << std::endl;
}
else if (dwCount == 0)
{
std::cout << "No sessions available" << std::endl;
}
else
{
DWORD dwNumActive = 0;
for (DWORD i = 0; i < dwCount; ++i)
{
if (pSessions[i].State == WTSActive) // has a logged in user
{
++dwNumActive;

std::cout << "Session: " << pSessions[i].SessionId << ", ";

LPWSTR pUserName = NULL;
DWORD dwBufSize = 0;

if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, pSessions[i].SessionId, WTSUserName, &pUserName, &dwBufSize))
{
dwError = GetLastError();
std::cout << "Error getting username: " << dwError;
}
else
{
//std::wcout << pUserName << std::endl;
std::string st = CW2A(pUserName);
std::cout << "User: " << st;
WTSFreeMemory(pUserName);
}

std::cout << std::endl;
}
}

if (!dwNumActive)
std::cout << "No users are logged in" << std::endl;
}

WTSFreeMemory(pSessions);

_getch();
return 0;
}

话虽如此,在非服务进程中,如果您需要与运行您的应用程序的 session 关联的登录用户名,并且您没有将代码作为与登录用户不同的用户(UAC 提升、模拟等),那么您可以只使用 GetUserName()相反:

int _tmain(int argc, _TCHAR* argv[])
{
WCHAR szUserName[UNLEN+1];
DWORD dwCount = UNLEN+1;

if (!GetUserNameW(szUserName, &dwCount))
{
DWORD dwError = GetLastError();
std::cout << "Error getting username: " << dwError << std::endl;
}
else
{
//std::wcout << szUserName << std::endl;
std::string st = CW2A(szUserName);
std::cout << "User: " << st << std::endl;
}

_getch();
return 0;
}

否则,您将再次返回到 WTSQuerySessionInformation():

int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwSessionId;
DWORD dwError;

if (!ProcessIdToSessionId(GetCurrentProcessId(), &dwSessionId))
{
dwError = GetLastError();
std::cout << "Error getting Session ID: " << dwError << std::endl;
}
else
{
std::cout << "Session: " << dwSessionId << ", ";

LPWSTR pUserName = NULL;
DWORD dwBufSize = 0;

if (!WTSQuerySessionInformationW(WTS_CURRENT_SERVER_HANDLE, dwSessionId, WTSUserName, &pUserName, &dwBufSize))
{
dwError = GetLastError();
std::cout << "Error getting username: " << dwError;
}
else
{
//std::wcout << pUserName << std::endl;
std::string st = CW2A(pUserName);
std::cout << "User: " << st;
WTSFreeMemory(pUserName);
}

std::cout << std::endl;
}

_getch();
return 0;
}

关于c++ - 作为服务运行时,获取 C++ 中的当前登录用户名不显示任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35029332/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com