Results 1 to 8 of 8

Thread: Probleem bij query van Windows services

  1. #1

    Probleem bij query van Windows services

    Goedemiddag allen,

    Ben bezig met een wrapper over UltraVNC en stunnel om simpel remote support te kunnen aanbieden.
    (Source hier: https://bitbucket.org/reiniero/checkride/src

    Hierbij check ik of de ultravnc service runt en gebruik daarbij de volgende code:
    Code:
    implementation
    
    uses
      ServiceManager, JwaWinSvc {for declarations};
    Code:
    function TCheckRideMain.IsServiceRunning(ServiceName: string): boolean;
      //<- Checks if a service is running
    var
      Services: TServiceManager;
      ServiceStatus: TServiceStatus;
    begin
      //Check for existing services
      //equivalent to sc query <servicename>
      Services := TServiceManager.Create(nil);
      try
        try
          Services.GetServiceStatus(ServiceName, ServiceStatus);
          if ServiceStatus.dwCurrentState = SERVICE_RUNNING then
          begin
            Result := True;
          end
          else
          begin
            Result := False;
          end;
        except
          on E: EServiceManager do
          begin
            // A missing service might throw a missing handle exception?
            Result := False;
          end;
          on E: Exception do
          begin
            Memo1.Append('Error getting service information for ' + ServiceName +
              '. Technical details: ' + E.ClassName + '/' + E.Message);
            Result := False;
          end;
        end;
      finally
        Services.Free;
      end;
    end;
    Echter, ik krijg bij elke run van deze functie de melding
    Error getting service information for uvnc_service. Technical details: EOSError/System error, (OS Code 6):
    The handle is invalid.
    in mijn memo, zowel als de service niet runt als wel.

    Wat doe ik verkeerd?

  2. #2
    32 of 64 bit applicatie ?

    in het geval van een 64bit app, zou het kunnen zijn dat jwa ergens nog een 32bit handle gebruikt

  3. #3
    Mmmm, is wel een 64 bits OS, maar een 32 bits applicatie.

  4. #4
    Ok, de invalid handle deed me even hier aan denken, maar voor een 32bit app zou ik het niet weten.

  5. #5
    Bedankt.

    Ben bezig om SVN versie FPC/Lazarus nou eindelijk op 'n nette manier naar binnen te krijgen (waarschijnlijk PEBKAC/PICNIC ; zal daarna kijken of dat helpt en zo niet, aankloppen op Engelstalige forum.
    (Programma was overigens gecompileerd met FPC 2.5.1 SVN van een aantal dagen terug).

  6. #6
    Wat meer info: prog draait onder admin/elevated privileges op Vista (aangezet in manifest).
    Service status code van hierboven draait ook niet op Windows 2000, met dezelfde foutmelding.

    Heb deze alternatieve code van het net gevonden die het wel doet.

    Hoop dat ik eruit kom waar de verschillen liggen, als ik iets vind, bug report bij Lazarus...
    Misschien in elk geval het beste om een klein testprogramma te maken en dat als bug aan te maken...

    Code:
    // Replacement code for faulty fpc services code from
    //http://www.chami.com/tips/delphi/031498D.html
    //-------------------------------------
    // get service status
    //
    // return status code if successful
    // -1 if not
    //
    // return codes:
    //   SERVICE_STOPPED
    //   SERVICE_RUNNING
    //   SERVICE_PAUSED
    //
    // following return codes
    // are used to indicate that
    // the service is in the
    // middle of getting to one
    // of the above states:
    //   SERVICE_START_PENDING
    //   SERVICE_STOP_PENDING
    //   SERVICE_CONTINUE_PENDING
    //   SERVICE_PAUSE_PENDING
    //
    // sMachine:
    //   machine name, ie: \SERVER
    //   empty = local machine
    //
    // sService
    //   service name, ie: Alerter
    //
    function ServiceGetStatus(
      sMachine,
      sService : string ) : DWord;
    var
      //
      // service control
      // manager handle
      schm,
      //
      // service handle
      schs   : SC_Handle;
      //
      // service status
      ss     : TServiceStatus;
      //
      // current service status
      dwStat : DWord;
    begin
      dwStat := -1;
    
      // connect to the service
      // control manager
      schm := OpenSCManager(
        PChar(sMachine),
        Nil,
        SC_MANAGER_CONNECT);
    
      // if successful...
      if(schm > 0)then
      begin
        // open a handle to
        // the specified service
        schs := OpenService(
          schm,
          PChar(sService),
          // we want to
          // query service status
          SERVICE_QUERY_STATUS);
    
        // if successful...
        if(schs > 0)then
        begin
          // retrieve the current status
          // of the specified service
          if(QueryServiceStatus(
               schs,
               ss))then
          begin
            dwStat := ss.dwCurrentState;
          end;
    
          // close service handle
          CloseServiceHandle(schs);
        end;
    
        // close service control
        // manager handle
        CloseServiceHandle(schm);
      end;
      Result := dwStat;
    end;
    
    //-------------------------------------
    // return TRUE if the specified
    // service is running, defined by
    // the status code SERVICE_RUNNING.
    // return FALSE if the service
    // is in any other state, including
    // any pending states
    //
    function IsServiceRunning(ServiceName: string): boolean;
    begin
      Result := SERVICE_RUNNING =
        ServiceGetStatus(
          '', ServiceName );
    end;
    Last edited by BigChimp; 08-Jun-11 at 11:07. Reason: Iets minder hoog van de toren blazen ;)

  7. #7
    Als dit wel werkt, dan lijkt het mij eerder een issue van de JWA implementatie van TServiceManager

  8. #8
    Mmmja, denk meer dat het ligt aan mijn onbegrip van die unit.

    Bij het nalopen van de twee implementaties lijkt het erop dat je eerst een .Connect moet doen bij de FPC versie, dus zoiets als:
    Code:
      function IsServiceRunning(ServiceName: string): boolean;
        {description Checks if a Windows service is running}
      var
        Services: TServiceManager;
        ServiceStatus: TServiceStatus;
      begin
        //Check for existing services
        //equivalent to sc query <servicename>
        Services := TServiceManager.Create(nil);
        try
          try
            Services.Connect;
            Services.GetServiceStatus(ServiceName, ServiceStatus);
            if ServiceStatus.dwCurrentState = SERVICE_RUNNING then
            begin
              Result := True;
            end
            else
            begin
              Result := False;
            end;
            Services.Disconnect;
          except
            on E: EServiceManager do
            begin
              // A missing service might throw a missing handle exception? No?
            {LogOutput('Error getting service information for ' + ServiceName +
              '. Technical details: ' + E.ClassName + '/' + E.Message);}
              Result := False;
              raise; //rethrow original exception
            end;
            on E: Exception do
            begin
            {LogOutput('Error getting service information for ' + ServiceName +
              '. Technical details: ' + E.ClassName + '/' + E.Message);
              }
              Result := False;
              raise; //rethrow original exception
            end;
          end;
        finally
          Services.Free;
        end;
      end;
    En nou lijkt het wel te werken zolang je elevated bent op Vista. Nu nog uitzoeken hoe je het ook als "gewone" unelevated admin kan runnen; dit
    Code:
            Services.Acces := SC_MANAGER_CONNECT; //Note typo in property.
    geeft access denied onder gewone admin, maar werkt als elevated.

    Weet iemand wellicht waar de documentatie van ServiceManager te vinden is? Lijkt erop dat Microsoft MSDN/Windows API documentatie de enige is

    Denk dat ik in ieder geval dit voorbeeld maar op de Lazarus wiki zet:
    http://wiki.lazarus.freepascal.org/ServiceManager
    Last edited by BigChimp; 10-Jun-11 at 11:33. Reason: Wiki link toegevoegd.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •