【问题标题】:Problem testing services in Windows 2000 Advanced ServerWindows 2000 Advanced Server 中的问题测试服务
【发布时间】:2010-08-31 19:41:16
【问题描述】:

我在 Delphi 7 中使用单元 cwinsrvc 开发了一个小应用程序,该单元被 Delphi 程序员广泛使用。我的应用程序只需要测试服务是否正在运行。它适用于我测试过的所有机器,包括 Windows XP 和 Windows 2000 Advanced Server。问题是有一台机器(windows 2000 Advanced Server)在我的应用程序中没有“看到”任何服务......我的意思是,当我询问服务是否正在运行或停止时,它返回“UNKNOWN”。我在类似的 PC (Windows 2000 Advanced Server) 上测试了我的应用程序,它工作正常!!!那么,特定机器的问题是什么????

我试图在那台机器上启动一个服务以获取带有消息的异常,但它没有引发异常,所以我可以看到问题所在......

有人可以帮帮我吗????我对我的英语感到抱歉。

我正在使用的单元的代码是下一个(cwinsrvc):

unit cwinsrvc;

interface

uses Windows, SysUtils, WinSvc;

    function ServiceGetStrCode(nID : integer) : string;
    function ServiceGetStatus(sMachine,sService : string) : DWord;
    function ServiceRunning(sMachine,sService : string) : boolean;
    function ServiceStopped(sMachine,sService : string) : boolean;
    function ServiceStart(sMachine,sService : string) : boolean;
    function ServiceStop(sMachine,sService : string) : boolean;


implementation 

function ServiceGetStrCode(nID : integer) : string;
var
  s : string;
begin
  case nID of
   SERVICE_STOPPED          : s := 'STOPPED';
   SERVICE_RUNNING          : s := 'RUNNING';
   SERVICE_PAUSED           : s := 'PAUSED';
   SERVICE_START_PENDING    : s := 'START/PENDING';
   SERVICE_STOP_PENDING     : s := 'STOP/PENDING';
   SERVICE_CONTINUE_PENDING : s := 'CONTINUE/PENDING';
   SERVICE_PAUSE_PENDING    : s := 'PAUSE/PENDING';
  else
   s := 'UNKNOWN';  
  end;
  Result := s;
end;

function ServiceGetStatus(sMachine,sService : string) : DWord;
var
schm   : SC_Handle; 
schs   : SC_Handle;     
ss     : TServiceStatus;
dwStat : DWord;         
begin
  dwStat := 1;
  schm := OpenSCManager( PChar(sMachine), Nil,
                         SC_MANAGER_CONNECT);

  if(schm > 0)then
  begin

    schs := OpenService( schm, PChar(sService),
                         SERVICE_QUERY_STATUS);

    if(schs > 0)then
    begin

      if (QueryServiceStatus( schs, ss)) then
      begin
        dwStat := ss.dwCurrentState;
      end;

      CloseServiceHandle(schs);
    end;

    CloseServiceHandle(schm);
  end;
  Result := dwStat;
end;

function ServiceRunning(sMachine,sService : string) : boolean;
begin
  Result := SERVICE_RUNNING =
            ServiceGetStatus(sMachine, sService);
end;

function ServiceStopped(sMachine,sService : string) : boolean;
begin
  Result := SERVICE_STOPPED =
            ServiceGetStatus(sMachine, sService);
end;

function ServiceStart(sMachine,sService : string) : boolean;
var
  schm,
  schs   : SC_Handle;
  ss     : TServiceStatus;
  psTemp : PChar;
  dwChkP : DWord; 
begin
  ss.dwCurrentState := 1;

  schm := OpenSCManager(PChar(sMachine), nil,
                        SC_MANAGER_CONNECT);

  if(schm > 0)then
  begin

    schs := OpenService(schm, PChar(sService),
            SERVICE_START or SERVICE_QUERY_STATUS);

    if(schs > 0)then
    begin
      psTemp := Nil;
      if(StartService( schs, 0,psTemp))then
      begin

        if(QueryServiceStatus(schs, ss))then
        begin
          while(SERVICE_RUNNING <> ss.dwCurrentState)do
          begin

            dwChkP := ss.dwCheckPoint;

            Sleep(ss.dwWaitHint);
            if not QueryServiceStatus(schs, ss) then
            begin

              break;
            end;

            if ss.dwCheckPoint < dwChkP then
            begin

              break;
            end;
          end;
        end;
      end;

      CloseServiceHandle(schs);
    end;

    CloseServiceHandle(schm);
  end;

  Result := SERVICE_RUNNING = ss.dwCurrentState;
end;



function ServiceStop(sMachine,sService : string) : boolean;
var
  schm,
  schs   : SC_Handle;
  ss     : TServiceStatus;
  dwChkP : DWord;
begin

  schm := OpenSCManager(PChar(sMachine), nil,
                        SC_MANAGER_CONNECT);

  if schm > 0 then
  begin

    schs := OpenService( schm, PChar(sService),
            SERVICE_STOP or SERVICE_QUERY_STATUS);

    if schs > 0 then
    begin
      if ControlService(schs, SERVICE_CONTROL_STOP,
                        ss) then
      begin

        if(QueryServiceStatus(schs, ss))then
        begin
          while(SERVICE_STOPPED <> ss.dwCurrentState)do
          begin

            dwChkP := ss.dwCheckPoint;

            Sleep(ss.dwWaitHint);

            if(not QueryServiceStatus(schs,ss))then
            begin

              break;
            end;

            if(ss.dwCheckPoint <
              dwChkP)then
            begin

              break;
            end;
          end;
        end;
      end;


      CloseServiceHandle(schs);
    end;


    CloseServiceHandle(schm);
  end;


  Result := SERVICE_STOPPED = ss.dwCurrentState;
end;

end.

【问题讨论】:

  • 仅供参考,Microsoft 现在完全不支持 Windows 2000。

标签: windows delphi


【解决方案1】:

Windows 函数通常不会引发异常。如果它们返回的代码表明存在错误,则必须显式调用 RaiseLastOSError() (或调用 GetLastError 以了解问题所在)。 如果某些东西不起作用,您的代码只会跳过部分,这样您就永远不会知道为什么。在您的情况下,这可能是一个权限问题 - 该进程必须具有适当的权限来查询和控制服务。但只有得到实际的错误代码才会知道。

【讨论】:

    【解决方案2】:

    无法远程控制机器的原因有很多。首先要检查的是:

    • 您的用户帐户是否具有控制(服务)远程计算机的访问权限和特权
    • 两台计算机之间的网络连接是否有效,包括任何可能阻止您的网络请求的防火墙或病毒扫描程序
    • 计算机是否响应网络请求(我相信这些请求是通过“IPC$”处理的,由“Server”或“LanMan”服务提供服务)

    【讨论】:

      猜你喜欢
      • 2011-02-04
      • 2011-03-04
      • 1970-01-01
      • 2011-04-24
      • 2012-07-29
      • 2013-04-05
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      相关资源
      最近更新 更多