C ++:检查计算机是否已锁定

时间:2015-03-29 07:26:47

标签: c++ windows-7 windows-xp

我正在试图弄清楚计算机是否已锁定。

我查看了LockWorkStation函数,但我希望找到的函数是IsWorkStationLocked


我需要支持所有Windows版本> = XP

4 个答案:

答案 0 :(得分:11)

对于Windows 7和abowe,可以使用WTS API:

bool IsSessionLocked() {
    typedef BOOL (PASCAL * WTSQuerySessionInformation)(HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPTSTR* ppBuffer, DWORD* pBytesReturned);
    typedef void (PASCAL * WTSFreeMemory)( PVOID pMemory);

    WTSINFOEXW * pInfo = NULL;
    WTS_INFO_CLASS wtsic = DW_WTSSessionInfoEx;
    bool bRet = false;
    LPTSTR ppBuffer = NULL;
    DWORD dwBytesReturned = 0;
    LONG dwFlags = 0;
    WTSQuerySessionInformation pWTSQuerySessionInformation = NULL;
    WTSFreeMemory pWTSFreeMemory = NULL;

    HMODULE hLib = LoadLibrary( _T("wtsapi32.dll") );
    if (!hLib) {
        return false;
    }
    pWTSQuerySessionInformation = (WTSQuerySessionInformation)GetProcAddress(hLib, "WTSQuerySessionInformationW" );
    if (!pWTSQuerySessionInformation) {
        goto EXIT;
    }

    pWTSFreeMemory = (WTSFreeMemory)GetProcAddress(hLib, "WTSFreeMemory" );
    if (pWTSFreeMemory == NULL) {
        goto EXIT;
    }

    if(pWTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, g_dwSessionID, wtsic, &ppBuffer, &dwBytesReturned)) {
        if(dwBytesReturned > 0) {
            pInfo =  (WTSINFOEXW*)ppBuffer; 
            if (pInfo->Level == 1) {
                dwFlags = pInfo->Data.WTSInfoExLevel1.SessionFlags;
            }
            if (dwFlags == WTS_SESSIONSTATE_LOCK) {
                bRet = true;
            }
        }
        pWTSFreeMemory(ppBuffer);
        ppBuffer = NULL;
    }
EXIT:
    if (hLib != NULL) {
        FreeLibrary(hLib);
    }
    return bRet;
}

请查看以下文章,了解WTSINFOEX结构支持的平台: https://technet.microsoft.com/ru-ru/sysinternals/ee621017

答案 1 :(得分:5)

根据您提供的same MSDN link,“备注”的第三段说:

  

此功能与按Ctrl + Alt + Del并单击“锁定工作站”的结果相同。要解锁工作站,用户必须登录。您无法调用以确定工作站是否已锁定。要在用户登录时接收通知,请使用WTSRegisterSessionNotification函数接收WM_WTSSESSION_CHANGE消息。 您可以使用会话通知来跟踪桌面状态,以便了解是否可以与用户进行互动。

答案 2 :(得分:4)

作为MGamsby帖子的改进:如果您以Win8.1 SDK或Win10 SDK为目标,那么就不必弄乱GetProcAddress(),LoadLibrary()和WTSGetActiveConsoleSessionId()了,代码变得非常多更紧凑:

bool isSessionLocked()
{
    WTSINFOEXW* pInfo = NULL;
    WTS_INFO_CLASS wtsic = WTSSessionInfoEx;
    LPTSTR ppBuffer = NULL;
    DWORD dwBytesReturned = 0;
    LONG sessionFlags = WTS_SESSIONSTATE_UNKNOWN; // until we know otherwise. Prevents a false positive since WTS_SESSIONSTATE_LOCK == 0

    DWORD dwSessionID = WTSGetActiveConsoleSessionId();

    if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, dwSessionID, wtsic, &ppBuffer, &dwBytesReturned))
    {
        if (dwBytesReturned > 0)
        {
            pInfo = (WTSINFOEXW*)ppBuffer;
            if (pInfo->Level == 1)
            {
                sessionFlags = pInfo->Data.WTSInfoExLevel1.SessionFlags;
            }
        }
        WTSFreeMemory(ppBuffer);
        ppBuffer = NULL;
    }

    return (sessionFlags == WTS_SESSIONSTATE_LOCK);
}

注意: 我意识到问题是关于Windows 7的,但您仍然可以使用Win8.1 SDK定位Win7,并且可以在VS2015及更高版本中使用。

编辑:糟糕。我只是意识到OP在这种情况下才要求WinXP,是的,您确实需要弄乱LoadLibrary()等。很抱歉。 如果对任何人有用,我将在这里保留我的代码。

答案 3 :(得分:3)

Alex Vershynin的版本运行良好,我必须进行一些代码更改。

我必须:将DW_WTSSessionInfoEx更改为WTSSessionInfoEx(回答user586399),定义" g_dwSessionID"到WTSGetActiveConsoleSessionId(),包括Wtsapi32.h。我认为这就是......

由于我无法发表评论,因此我会在此处粘贴整个代码。

#include "Wtsapi32.h"
bool IsSessionLocked()
{
    typedef BOOL( PASCAL * WTSQuerySessionInformation )( HANDLE hServer, DWORD SessionId, WTS_INFO_CLASS WTSInfoClass, LPTSTR* ppBuffer, DWORD* pBytesReturned );
    typedef void ( PASCAL * WTSFreeMemory )( PVOID pMemory );

    WTSINFOEXW * pInfo = NULL;
    WTS_INFO_CLASS wtsic = WTSSessionInfoEx;
    bool bRet = false;
    LPTSTR ppBuffer = NULL;
    DWORD dwBytesReturned = 0;
    LONG dwFlags = 0;
    WTSQuerySessionInformation pWTSQuerySessionInformation = NULL;
    WTSFreeMemory pWTSFreeMemory = NULL;

    HMODULE hLib = LoadLibrary( "wtsapi32.dll" );
    if( !hLib )
    {
        return false;
    }
    pWTSQuerySessionInformation = (WTSQuerySessionInformation) GetProcAddress( hLib, "WTSQuerySessionInformationW" );
    if( pWTSQuerySessionInformation )
    {
        pWTSFreeMemory = (WTSFreeMemory) GetProcAddress( hLib, "WTSFreeMemory" );
        if( pWTSFreeMemory != NULL )
        {
            DWORD dwSessionID = WTSGetActiveConsoleSessionId();
            if( pWTSQuerySessionInformation( WTS_CURRENT_SERVER_HANDLE, dwSessionID, wtsic, &ppBuffer, &dwBytesReturned ) )
            {
                if( dwBytesReturned > 0 )
                {
                    pInfo = (WTSINFOEXW*) ppBuffer;
                    if( pInfo->Level == 1 )
                    {
                        dwFlags = pInfo->Data.WTSInfoExLevel1.SessionFlags;
                    }
                    if( dwFlags == WTS_SESSIONSTATE_LOCK )
                    {
                        bRet = true;
                    }
                }
                pWTSFreeMemory( ppBuffer );
                ppBuffer = NULL;
            }
        }
    }
    if( hLib != NULL )
    {
        FreeLibrary( hLib );
    }
    return bRet;
}