1

ターミナル サービスが実行されているかどうかを検出しようとしています。MSDN Wayを使用しようとしました:

OSVERSIONINFOEX osVersionInfo;
DWORDLONG dwlConditionMask = 0;

memset( &osVersionInfo, 0, sizeof( osVersionInfo ) );
osVersionInfo.dwOSVersionInfoSize = sizeof( osVersionInfo );
osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;

VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );

return VerifyVersionInfo( &osVersionInfo, VER_SUITENAME, dwlConditionMask );

うまく機能しますが、次の場合:

OS Name: Microsoft(R) Windows(R) Server 2003, Enterprise Edition  
OS Version:                5.2.3790 Service Pack 2 Build 3790  
OS Manufacturer:           Microsoft Corporation  
OS Configuration:          Standalone Server  
OS Build Type:             Multiprocessor Free

ターミナル サービスの役割がない場合、 への呼び出しはVerifyVersionInfoゼロ以外の値を返します。これは、「現在実行中のオペレーティング システムが指定された要件を満たしている」か、関数が失敗したことを意味します。

GetLastError戻り値:

0x000000cb "The system could not find the environment option that was entered."

Windows XP SP3 では、 を呼び出すとVerifyVersionInfo0 の値が返されるため、入力エラーは発生しないと思います。

この動作をどのように処理しますか? これをターミナル サービスがないものとして扱ってよいでしょうか。より良いテクニックはありますか?

OSのバグですか?

アップデート:

Windows Server 2008 R1 の動作も同様です (失敗します)。他の多くのシステムにもある可能性があります。

4

3 に答える 3

0

まあ、私はほとんど機能する解決策を見つけました(Win2kサーバーでのみ失敗します)。

OSVERSIONINFOEX osVersionInfo;
DWORDLONG dwlConditionMask = 0;

memset( &osVersionInfo, 0, sizeof( osVersionInfo ) );
osVersionInfo.dwOSVersionInfoSize = sizeof( osVersionInfo );
osVersionInfo.wSuiteMask = VER_SUITE_SINGLEUSERTS;

VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );

return !VerifyVersionInfo( &osVersionInfo, VER_SUITENAME, dwlConditionMask );

興味深い事実 - VerifyVersionInfo を呼び出しても、最後のエラー コードは変更されません。GetLastError が返すエラー コード 0x000000cb は単なるゴミです。

于 2010-07-14T11:33:03.060 に答える
0

Terminal Services is an NT-service like any other, internally named TermServices, and if you have the permission.privilege to access the service manager, you could poll there to see if it's running:

OpenSCManager OpenService QueryServiceStatus

于 2010-07-10T19:48:39.927 に答える
-1

以下のコードは Delphi ですが、c/c++ ではあまり変更する必要はありません。

function AreWeRunningTerminalServices: Boolean;
var VersionInfo: TOSVersionInfoEx;
  dwlConditionMask: Int64;
begin
  // Zero Memory and set structure size
  ZeroMemory(@VersionInfo, SizeOf(VersionInfo));
  VersionInfo.dwOSVersionInfoSize := SizeOf(VersionInfo);

  // We are either Terminal Server or Personal Terminal Server
  VersionInfo.wSuiteMask := VER_SUITE_TERMINAL or VER_SUITE_SINGLEUSERTS;
  dwlConditionMask := VerSetConditionMask(0, VER_SUITENAME, VER_OR);

  // Test it
  Result := VerifyVersionInfo(VersionInfo, VER_SUITENAME, dwlConditionMask);
end;

または、ターミナル サーバー サービスが実際に実行されていることを確認する場合は、次のように入力します。

function IsTerminalServiceRunning: boolean;
var hSCM: HANDLE;
  hService: HANDLE;
  ServiceStatus: SERVICE_STATUS;
begin
  Result := False;
  // Open handle to Service Control Manager
  hSCM := OpenSCManager(nil, SERVICES_ACTIVE_DATABASE, GENERIC_READ);
  if hSCM > 0 then
  begin
    // Open handle to Terminal Server Service
    hService := OpenService(hSCM, 'TermService', GENERIC_READ);
    if hService > 0 then
    begin
      // Check if the service is running
      QueryServiceStatus(hService, ServiceStatus);
      Result := ServiceStatus.dwCurrentState = SERVICE_RUNNING;
      // Close the handle
      CloseServiceHandle(hService);
    end;
    // Close the handle
    CloseServiceHandle(hSCM);
  end;
end;
于 2010-12-03T10:14:25.420 に答える