私は以下を使用します
const
SM_REMOTESESSION = $1000;
if GetSystemMetrics(SM_REMOTESESSION) <> 0 then
begin
// you are in a remote session
end
GetSystemMetricsの MSDN ページによると:
SM_REMOTESESSION = 0x1000
このシステム メトリックは、ターミナル サービス環境で使用されます。呼び出しプロセスがターミナル サービス クライアント セッションに関連付けられている場合、戻り値はゼロ以外です。呼び出しプロセスがターミナル サービス コンソール セッションに関連付けられている場合、戻り値は 0 です。 Windows Server 2003 および Windows XP: コンソール セッションは必ずしも物理コンソールではありません。詳細については、WTSGetActiveConsoleSessionIdを参照してください。
私はこれを Delphi 2007 で使用しており、関数は Windows ユニットで定義されていますが、自分で定数を定義する必要がありました。Delphi 6 に関数が定義されているかどうかはわかりません。サポートされている Windows の最小バージョンは Windows 2000 だったので、以前に戻らない限り、それを使用できるはずです。
--
セッションの現在の状態を確認するには、 WTSQuerySessionInformation関数が必要です。この関数を使用して、現在の状態を含む現在のセッションに関する多くの情報を見つけることができます。
Embarcadero ディスカッション フォーラムで、開始コードを提供するエントリを見つけました。その投稿は、リモート デスクトップの質問と呼ばれていました。
必要な定数と関数プロトタイプを次に示します。
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;