【问题标题】:Correct Detecting of the Terminal Services终端服务的正确检测
【发布时间】:2010-07-07 16:39:49
【问题描述】:

我一直在尝试检测终端服务是否正在运行。我尝试使用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 上,对 VerifyVersionInfo 的调用返回一个零值,所以我想没有输入错误。

我该如何处理这种行为?将其视为没有终端服务是否很好?有没有更好的技术?

这是操作系统中的错误吗?

更新:

在 Windows Server 2008 R1 上的行为类似(失败)。也可能在许多其他系统上。

【问题讨论】:

    标签: winapi windows-server-2003 terminal-services


    【解决方案1】:

    终端服务和其他任何服务一样是 NT 服务,内部命名为 TermServices,如果您有访问服务管理器的权限。您可以在那里轮询以查看它是否正在运行:

    OpenSCManager OpenService QueryServiceStatus

    【讨论】:

      【解决方案2】:

      好吧,我找到了几乎可行的解决方案(仅在 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只是一个垃圾。

      【讨论】:

        【解决方案3】:

        迟到总比不晚好,下面的代码是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;
        

        【讨论】:

        • 我想知道为什么这被否决了,答案是正确的。如果您对某些内容投反对票,请发表评论!!!
        猜你喜欢
        • 2020-05-17
        • 1970-01-01
        • 2017-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多