2013-07-11 2 views
1

Время от времени к моему приложению обращаются клиенты удаленного рабочего стола, я хочу знать, используется ли он в сеансе консоли или сеансе удаленного рабочего стола, если это случай, и сеанс отключен (пользователь отключился, но не вышел из системы) он должен перенаправить себя на консоль (например, «tscon.exe 0/dest: console» работает в Windows XP). Теперь я запускаю сценарий оболочки для достижения этого (используя «query.exe user» и «tscon.exe»), но хотел бы, чтобы это приложение для Delhi6.Delphi6: нужно знать, что мое приложение работает в сеансе консоли или сеансе удаленного рабочего стола

ответ

3

Я использую следующие

const 
    SM_REMOTESESSION = $1000; 
if GetSystemMetrics(SM_REMOTESESSION) <> 0 then 
begin 
    // you are in a remote session 
end 

За странице MSDN для GetSystemMetrics:
SM_REMOTESESSION = 0x1000
Эта система метрика используется в среде служб терминалов. Если вызывающий процесс связан с сеансом клиента служб терминалов, возвращаемое значение отличное от нуля. Если вызывающий процесс связан с сеансом консоли служб терминалов, возвращаемое значение равно 0. Windows Server 2003 и Windows XP: сеанс консоли не обязательно является физической консолью. Для получения дополнительной информации см. WTSGetActiveConsoleSessionId.

Я использую это в Delphi 2007, и функция определена в блоке Windows, но мне нужно было определить константу самостоятельно. Я не знаю, определена ли функция Delphi 6. Минимальная поддерживаемая версия Windows была Windows 2000, поэтому вы можете использовать ее, если не собираетесь вернуться.

-

Чтобы узнать текущее состояние сеанса необходима функция WTSQuerySessionInformation. Вы можете использовать эту функцию, чтобы узнать много информации о текущем сеансе, включая текущее состояние.

Я нашел запись на форуме обсуждения Embarcadero, которая дала мне стартовый код. Этот пост был назван remote desktop question.

Вот некоторые константы и прототипы функций вам потребуется:


const 
    WTS_CURRENT_SERVER_HANDLE: THandle = 0; 
    WTS_CURRENT_SESSION: DWORD = DWORD(-1); 


type 
    WTS_INFO_CLASS = (
    WTSInitialProgram, 
    WTSApplicationName, 
    WTSWorkingDirectory, 
    WTSOEMId, 
    WTSSessionId, 
    WTSUserName, 
    WTSWinStationName, 
    WTSDomainName, 
    WTSConnectState, 
    WTSClientBuildNumber, 
    WTSClientName, 
    WTSClientDirectory, 
    WTSClientProductId, 
    WTSClientHardwareId, 
    WTSClientAddress, 
    WTSClientDisplay, 
    WTSClientProtocolType, 
    WTSIdleTime, 
    WTSLogonTime, 
    WTSIncomingBytes, 
    WTSOutgoingBytes, 
    WTSIncomingFrames, 
    WTSOutgoingFrames, 
    WTSClientInfo, 
    WTSSessionInfo, 
    WTSSessionInfoEx, 
    WTSConfigInfo, 
    WTSValidationInfo, 
    WTSSessionAddressV4, 
    WTSIsRemoteSession 
); 

WTS_CONNECTSTATE_CLASS = (
    WTSActive,    // User logged on to WinStation 
    WTSConnected,   // WinStation connected to client 
    WTSConnectQuery,  // In the process of connecting to client 
    WTSShadow,    // Shadowing another WinStation 
    WTSDisconnected,  // WinStation logged on without client 
    WTSIdle,    // Waiting for client to connect 
    WTSListen,    // WinStation is listening for connection 
    WTSReset,    // WinStation is being reset 
    WTSDown,    // WinStation is down due to error 
    WTSInit);    // WinStation in initialization 

    TWTSQuerySessionInformationFunction = function(hServer: THandle; SessionId: 
       DWORD; WTSInfoClass: WTS_INFO_CLASS; var ppBuffer: Pointer; var pBytesReturned: DWORD): BOOL; stdcall; 
    TWTSFreeMemoryProcedure = procedure(pMemory: Pointer); stdcall; 

А вот код используется. Я помещаю это в таймер и выводим состояние в поле списка. Я мог отключиться, а затем снова подключиться и увидеть изменение состояния в списке.

Существуют различные способы обработки библиотеки загрузки и вызова сопоставления функций. Вероятно, не нужно загружать библиотеку при каждом вызове, если вы закончите опрос таким образом. Я просто использовал пример, который я нашел.


function TForm3.GetTSClientState: WTS_CONNECTSTATE_CLASS; 
var 
    LibHandle: HMODULE; 
    WTSQuerySessionInformation: TWTSQuerySessionInformationFunction; 
    WTSFreeMemory: TWTSFreeMemoryProcedure; 
    ClientState: Pointer; 
    cBytesReturned: DWORD; 
begin 

    LibHandle := LoadLibrary('wtsapi32.dll'); 
    if LibHandle <> 0 then 
    begin 
    try 
     @WTSQuerySessionInformation := GetProcAddress(LibHandle, 'WTSQuerySessionInformationA'); 
     @WTSFreeMemory := GetProcAddress(LibHandle, 'WTSFreeMemory'); 
     if Assigned(WTSQuerySessionInformation) and Assigned(WTSFreeMemory) 
     then 
     begin 
     if WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, 
             WTSConnectState, ClientState, cBytesReturned) then 
     try 
      result := WTS_CONNECTSTATE_CLASS(ClientState^); 
     finally 
      WTSFreeMemory(ClientState); 
     end; 

     end; 
    finally 
     FreeLibrary(LibHandle); 
    end; 
    end; 
end; 


procedure TForm3.Timer1Timer(Sender: TObject); 
var 
    State: WTS_CONNECTSTATE_CLASS; 
begin 
    ListBox1.AddItem(GetTSClientName, nil); 

    State := GetTSClientState; 

    case State of 
    WTSActive: ListBox1.AddItem('WTSActive', nil); 
    WTSConnected: ListBox1.AddItem('WTSConnected', nil); 
    WTSConnectQuery: ListBox1.AddItem('WTSConnectQuery', nil); 
    WTSShadow: ListBox1.AddItem('WTSShadow', nil); 
    WTSDisconnected: ListBox1.AddItem('WTSDisconnected', nil); 
    WTSIdle: ListBox1.AddItem('WTSIdle', nil); 
    WTSListen: ListBox1.AddItem('WTSListen', nil); 
    WTSReset: ListBox1.AddItem('WTSReset', nil); 
    WTSDown: ListBox1.AddItem('WTSDown', nil); 
    WTSInit: ListBox1.AddItem('WTSInit', nil); 
    end; 
end; 
+0

Да это работает, но дело в том, чтобы знать, на этой сессии «отключен» (пользователь закрыл окно просмотра и пользовательский интерфейс не отображается нигде) или «активный» (пользователь worknig на него удаленно). – amilewski

+0

Обновленный ответ, чтобы включить способ получения состояния сеанса. –

+0

Итак, теперь я знаю состояние сеанса, единственное, что осталось открыть, - это как перенаправить сеанс на консоль, как это делает «tscon.exe 0/dest: console». Любые, хотя? – amilewski

Смежные вопросы