윈도우의 터미널 서버를 이용하는 경우, 해당 세션별 정보나 프로세스 정보
그러한 목록을 가지고 먼가 작업을 해야 하는경우.. 사용할 수 있는 간단한 래핑클래스 입니다.

class CWTSSession

클래스의 경우는 해당 세션  ID를 알고 있을 경우 세션의 디테일한 정보를 읽어 오는 클래스이죠.
클래스의 내부 멤버를 보시면 어떤 정보를 열거하는지 바로 확인이 가능합니다.

class CWTSBase
위 클래스는 어떤 세션이 존재하는지, 어떤 서버가 존재하는지, 프로세스 목록은 어떤게 있는지
등등을 열거해주는 기능을 제공해줍니다.

[-] Collapse

#include <WtsApi32.h>

class CWTSSession
{
public:
    CWTSSession();
    CWTSSession(HANDLE hWTS, DWORD SessionID);
    ~CWTSSession();

    CHAR    IPAddress[16];
    USHORT  HorizontalResolution;
    USHORT  VerticalResolution;
    USHORT  ColorDepth;
    USHORT  ProtocolType;
    LPTSTR  ClientName;
    LPTSTR  DomainName;
    LPTSTR  UserName;
    LPTSTR  WinStation;
protected:
    void Query(HANDLE hWTS, DWORD SessionID);
    void Init();
    void Free();
};

class CWTSBase
{
public:
    CWTSBase();
    virtual ~CWTSBase();

    BOOL Open(LPTSTR servername);
    void Close();
    void Free(void* data);
    HANDLE GetHandle();

    BOOL EnumSessions(PWTS_SESSION_INFO& info, LPDWORD count);
    BOOL EnumServers(LPTSTR domainname, PWTS_SERVER_INFO& info, LPDWORD count);
    BOOL EnumProcesses(PWTS_PROCESS_INFO& info, LPDWORD count);

protected:
    HANDLE m_hWTS;
}; 

세션 아이디를 알고 있을 경우, 해당 세션의 세부정보를 읽어오는 샘플
CWTSSession ws(WTS_CURRENT_SERVER_HANDLE, 세션아이디);

모든 세션에 걸친 프로세스 목록을 읽어오는 샘플
CWTSBase wts;
DWORD count;
PWTS_PROCESS_INFO info;
wts.EnumProcesses(info, &count);

어떤 세션이 존재하는지, 세션 목록 정보를 읽어오는 샘플
CWTSBase wts;
DWORD count;
PWTS_SESSION_INFO info;
wts.EnumProcesses(info, &count);

현재 나의 프로그램이 어떤 세션에 속해있는지를 판단하는 샘플
DWORD PID = GetCurrentProcessId();
DWORD SID = 9999999;
if(ProcessIdToSessionId(PID, &SID))
{
    CWTSSession ws(WTS_CURRENT_SERVER_HANDLE, SID);
    printf("%s\n", ws.IPAddress);
    printf("%s\n", ws.ClientName);
    printf("%s\n", ws.DomainName);
    printf("%s\n", ws.UserName);
    printf("%s\n", ws.WinStation);
}

지정된 세션에 동일한 프로세스가 있을 경우, 해당 세션의 특정 프로세스에 메시지 보내기
오직 하나의 프로그램이 동작하도록 할경우를 제외한 하나의 세션당 하나의 프로그래만
구동되도록 작성해야 할경우.. 사용한 샘플입니다.
BOOL CALLBACK CROWBACK_WNDENUMPROC(HWND hWnd, LPARAM lp)
{
    DWORD target = lp;
    DWORD pid = 9999999;
    GetWindowThreadProcessId(hWnd, &pid);
    if(pid == target)
    {
        char caption[512] = {0};
        ::GetWindowText(hWnd, caption, 512);
        if(strstr(caption, "Alert Management"))
        {
            ::PostMessage(hWnd, 0x9999, 0, 0);
            return FALSE;
        }
    }

    return TRUE;
}

DWORD PID = GetCurrentProcessId();
DWORD SID = 9999999;

if(ProcessIdToSessionId(PID, &SID))
{
    AllowSetForegroundWindow(PID);

    char Module[512] = {0};
    ::GetModuleFileName(NULL, Module, 512);
    CString name = Module;
    name = name.Right(name.GetLength()-name.ReverseFind('\\')-1);
    CWTSBase wts;

    DWORD count;
    PWTS_PROCESS_INFO info2;
    wts.EnumProcesses(info2, &count);
    for(UINT i=0; i<count; i++)
    {
        if(info2[i].SessionId == SID && info2[i].ProcessId != PID)
        {
            if(name.CompareNoCase(info2[i].pProcessName) == 0)
            {
                ::EnumWindows(CROWBACK_WNDENUMPROC, info2[i].ProcessId);
                return TRUE;
            }
        }
    }
}

+ Recent posts