获取当前登录的用户名,C++作为服务运行时不显示任何内容
Get current logged in user name in C++ doesn't show anything when run as service
这是我的代码。我在发布模式下编译并运行它。它打印输出。我在链接器中添加了库作为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 及更高版本中,所有服务都在会话 0 中运行,用户登录到会话 1 及更高版本。 这称为会话 0 隔离:
服务始终在会话 0 中运行。在 Windows Vista 之前,第一个登录的用户也被分配到会话 0。现在,会话 0 专门保留给与交互式用户会话无关的服务和其他应用程序。(第一个登录的用户连接到会话 1,第二个登录的用户连接到会话 2,依此类推。会话 0 不支持与用户交互的进程。
此更改意味着服务无法向应用程序发布或发送消息,并且应用程序无法向服务发送或发布消息。此外,服务不能直接显示用户界面项,如对话框。服务可以使用 WTSSendMessage 函数在另一个会话中显示对话框。
会话 0 隔离对 Windows 中的服务和驱动程序的影响
会话 0 隔离:向后兼容性输给安全性的地方
要从服务内部查找登录用户,您必须使用 WTSEnumerateSessions()
枚举可用会话,在每个会话上调用WTSQuerySessionInformation()
(您也可以在 Win2000 和 XP 中执行此操作,它们允许用户登录到会话 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;
}
话虽如此,在非服务进程中,如果需要与运行应用的会话关联的登录用户名,并且您没有以与登录用户不同的用户身份运行代码(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;
}
- CMake-按正确顺序将项目与C运行时对象文件链接
- 我在c++代码中生成了一个运行时#3异常
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 删除指向指针的指针是运行时错误吗
- 如何用参数值调用函数(仅在运行时已知)
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- c++中的指针和运行时错误
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 建议在运行时将带有类实例的列表从c++导入qml
- 在 Linux 上C++:在作为 systemd 服务运行时侦听键盘输入
- 当程序作为服务运行时重定向 std::cout
- 作为服务运行时连接到远程计算机的 WMI
- OpenSSL 在作为 win32 服务运行时SSL_CTX_new崩溃
- 获取当前登录的用户名,C++作为服务运行时不显示任何内容
- 作为windows服务运行时,如何获取活动监视器的数量?C++
- 当java作为服务运行时,从java启动进程
- 在运行时保存服务的输出
- 当 boost 的 io 服务正在运行时,无法执行字符串