tags:

views:

57

answers:

4

Hi there:

I developed a little application in Delphi 7 using the unit cwinsrvc, widely used by Delphi programmers. My application only has to test if a service is running. It works in all machines I have tested, including Windows XP and Windows 2000 Advanced Server. The problem is that there is a machine (windows 2000 Advanced Server) in wich my application does not "see" any service... I mean, when I ask if a service is running or stopped, it returns "UNKNOWN". I tested my application in a similar PC (Windows 2000 Advanced Server) and IT WORKS!!! So, what is the problem in an specific machine????

I tried to start a service in that machine in order to obtain an exception with a message, but it didn't raise an exception, so I can see what is the problem...

Can somebody help me, please???? I am sorry about my English.

The code of the Unit I am using is the next (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.
A: 

There are a number of reasons why remote control of a machine won't work. First things to check are:

  • does your user account has the access rights and privileges to control (services on) the remote computer
  • is the network connection between the two computers valid, including any firewalls or virusscanners that may block your network requests
  • does the computer respond to the network requests (I believe these requests are handled over the "IPC$", served by the 'Server' or 'LanMan' services)
Stijn Sanders
+1  A: 

Windows functions usually won't raise an exception. You have to raise them explicitly calling RaiseLastOSError() (or calling GetLastError to know what the problem was) if they return a code that tells there was an error. Your code simply skips portions if something wasn't working, and that way you'll never know why. In your case it could be a permission issue - the process must have proper privileges to query and control services. But only getting the actual error code you'll know.

ldsandon
A: 

I am sorry... All my tests are in localhost, using the same machine in wich I am running my app. Never in a remote machine.

DelphiProgrammer
Welcome to Stack Overflow. Please remember to use the same log-in credentials you used last time. Then you will be allowed to *comment* on others' answers instead of being forced to *answer* your question with something that clearly isn't an answer to the the question.
Rob Kennedy
A: 

Hey boys, I just got the error in testing a service. Windows returned this error: System Error. Code: 1722. RPC Server is not available. Now, what can I do to solve that problem?? How to make RPC Server available??

DelphiProgrammer
Hello. Please, add your comments to other's answers and consider deleting this useless (and out of context) ones.
jachguate