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

C++ 在C+;中获取当前登录的用户名+;不';当作为服务运行时,不显示任何内容,c++,windows,winapi,C++,Windows,Winapi,这是我的密码。我在发布模式下编译并运行它。它打印输出。我已经在链接器中添加了库wtsapi32.lib #include "stdafx.h" #include <windows.h> #include <conio.h> #include <iostream> #include <tchar.h> #include <wtsapi32.h>

这是我的密码。我在发布模式下编译并运行它。它打印输出。我已经在链接器中添加了库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;
        }
#包括“stdafx.h”
#包括
#包括
#包括
#包括
#包括

#包括并设置一个文件以打印输出。nssm允许您在文件中打印输出。但它只打印psSessionID。我的代码怎么了?有人能说出原因吗?

首先,使用
malloc()
分配指针变量是浪费和不必要的,更不用说正在泄漏分配的内存了。只需在堆栈上声明指针即可,这样更简单、更安全

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

服务始终在会话0中运行。在Windows Vista之前,第一个登录的用户也被分配到会话0。现在,会话0仅保留给与交互式用户会话无关的服务和其他应用程序。(第一个登录的用户连接到会话1,第二个登录的用户连接到会话2,依此类推。)会话0不支持与该用户交互的进程

此更改意味着服务无法向应用程序发送或发布消息,应用程序也无法向服务发送或发布消息。此外,服务无法直接显示对话框等用户界面项。服务可以使用WTSSendMessage函数在另一个会话中显示对话框

要从服务内部查找登录的用户,必须使用枚举可用会话,对每个会话调用
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;
}
否则,您将再次返回到
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;
}
int-tmain(int-argc,_-TCHAR*argv[]
{
德沃德·德沃德·塞西奥尼德;
德沃德误差;
如果(!ProcessIdToSessionId(GetCurrentProcessId(),&dwSessionId))
{
dwError=GetLastError();

std::cout首先,使用
malloc()
分配指针变量是浪费和不必要的,更不用说正在泄漏分配的内存了。只需在堆栈上声明指针即可,这样更简单、更安全

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

服务始终在会话0中运行。在Windows Vista之前,第一个登录的用户也已分配给会话0。现在,会话0仅保留给与交互用户会话无关的服务和其他应用程序。(第一个登录的用户连接到会话1,第二个登录的用户连接到会话2,依此类推。)会话0不支持与该用户交互的进程

此更改意味着服务无法向应用程序发布或发送消息,应用程序也无法向服务发送或发布消息。此外,服务无法直接显示对话框等用户界面项。服务可以使用WTSSendMessage功能在另一个会话中显示对话框

要从服务中查找登录的用户,您必须使用枚举可用会话,对每个会话调用
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;
}
否则,您将再次返回到
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;
}
int-tmain(int-argc,_-TCHAR*argv[]
{
德沃德·德沃德·塞西奥尼德;
德沃德误差;
如果(!ProcessIdToSessionId(GetCurrentProcessId(),&dwSessionId))
{
dwError=GetLastError();

std::cout如果您作为服务运行,则没有登录用户。@JonathanPotter:可能有,只是不在服务运行的同一会话中。如果您作为服务运行,则没有登录用户。@JonathanPotter:可能有,只是不在服务运行的同一会话中。
GetUserName()
在非服务流程中使用时工作正常,您运行代码的用户与登录的用户(UAC提升、模拟等)不同。
GetUserName()
在非服务流程中使用时工作正常,您运行代码的用户与登录的用户不同(UAC提升、模拟等)。