Announcement

Collapse
No announcement yet.

Dienste unter NT kontrollieren

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dienste unter NT kontrollieren

    Hallo,<br>ich brauche dringent Hilfe bei der Funktion "QueryServiceStatus".<p>
    Wie rufe ich diese Funktion richtig auf?<br>
    Wenn ich die ServiceDatenbank mit OpenSCManager öffnen will,<br>
    bekomme ich immer eine 0 zurück.<br>
    Kann mir jemand mit ein Stück Quellcode antworten???<p>

  • #2
    Hallo,

    wenn der Benutzer die notwendigen NT-Privilegien hat (was bei einem Mitglied der Administrator-Gruppe in der Regel der Fall ist), sollte das folgende Beispiel funktionieren:
    <pre>
    procedure TFormMain.StartStopRC(bStart: Boolean);
    var
    hSCM : THandle;
    hSrv : THandle;
    aSrvStatus : TServiceStatus;
    pSrvArgs : PChar;
    const
    cSRV_NAME = 'xyz';
    cERR_NO_SCM = 'Kein Zugriff auf SCM!';
    cERR_NO_SRV = 'OpenService für %s ist fehlgeschlagen';
    cERR_RUN = 'Der Dienst »%s« läuft bereit!';
    cERR_STOP = 'Der Dienst »%s« ist bereits gestoppt!';
    begin
    hSCM := OpenSCManager(nil, nil, SC_MANAGER_CONNECT);
    try
    if hSCM = 0 then
    raise Exception.Create(cERR_NO_SCM);
    hSrv := OpenService(hSCM, PChar(cSRV_NAME), SERVICE_START or SERVICE_STOP);
    if hSrv = 0 then
    raise Exception.Create(Format(cERR_NO_SRV, [cSRV_NAME]));
    QueryServiceStatus(hSrv, aSrvStatus);
    if bStart = True then
    begin
    if aSrvStatus.dwCurrentState = SERVICE_RUNNING then
    begin
    ShowMessage(Format(cERR_RUN, [cSRV_NAME]));
    end
    else
    begin
    pSrvArgs := nil;
    StartService(hSrv, 0, pSrvArgs);
    end;
    end
    else
    begin
    if aSrvStatus.dwCurrentState = SERVICE_STOPPED then
    begin
    ShowMessage(Format(cERR_STOP, [cSRV_NAME]));
    end
    else
    begin
    ControlService(hSrv, SERVICE_CONTROL_STOP, aSrvStatus);
    end;
    end;
    CloseServiceHandle(hSrv);
    finally
    CloseServiceHandle(hSCM);
    end;
    end;
    </pre>
    Falls immer noch 0 zurückgeliefert wird, würde ich über die API-Funktion <b>GetLastError</b> beim Betriebssystem nachfragen, warum es ein Veto eingelegt hat. Alternativ können alle API-Aufrufe auch in die <b>Win32Check</b>-Funktion eingekapselt werden, dann erhält man sofort den Fehlertext

    Comment


    • #3
      Vielen Dank. Hat funktioniert.<p>
      Mit welcher Funktion bekonne ich eine Liste mit allen Diensten und Geräten die auf der Maschine installiert sind?<p&gt

      Comment


      • #4
        Hallo,

        das kommt darauf an, welche Erweiterungen für das Betriebssystem installiert wurden. Wurde <b>Windows Management Instrumentation</b> (WMI) installiert, so stehen unter NT 4 und Windows 2000 spezielle Objekte zur Verfügung. Mit einem von Microsoft zur Verfügung gestellten VBScript kann man das schnell nachprüfen:

        <pre>
        ' ENUM.VBS
        set WMI = GetObject("WinMgmts:")

        'Show description of all services
        set objs = WMI.InstancesOf("Win32_Service")
        for each obj in objs
        WScript.Echo obj.Description
        next

        'Show description of all printers
        set objs = WMI.InstancesOf("Win32_Printer")
        for each obj in objs
        WScript.Echo obj.Description
        next

        'Show description of all processes
        set objs = WMI.InstancesOf("Win32_Process")
        for each obj in objs
        WScript.Echo obj.Description
        next

        'Show description of all processors
        set objs = WMI.InstancesOf("Win32_Processor")
        for each obj in objs
        WScript.Echo obj.Description
        next
        </pre>

        Alternativ zu WMI gibt es aber auch noch <b>ADS</b> bzw. die COM-Schnittstelle dazu (ADSI). Auch hier stehen die Informationen über spezielle Objekte zur Verfügung. Das folgende Delphi-Beispiel liest Infos zu den Benutzern aus:
        <pre>
        uses ActiveDs_TLB, ActiveX, ComObj;

        function GetObject(const Name : string): IDispatch;
        var
        Moniker : IMoniker;
        Eaten : integer;
        BindContext : IBindCtx;
        Dispatch : IDispatch;
        begin
        OleCheck(CreateBindCtx(0, BindContext));
        OleCheck(MkParseDisplayName(BindContext, PWideChar(WideString(Name)), Eaten, Moniker));
        OleCheck(Moniker.BindToObject(BindContext, NIL, IDispatch, Dispatch));
        Result := Dispatch;
        end;

        procedure TForm1.Button1Click(Sender: TObject);
        var
        sADSPath : String;
        Usr : IADsUser;
        l : Longint;
        Grp : IAdsGroup;
        lst : IEnumVariant_D4;
        o : OleVariant;
        begin
        sADSPath := 'WinNT://' + EditDomain.Text + '/' + EditPC.Text;
        Memo1.Lines.Add(sADSPath);
        Memo1.Lines.Add('---');
        Usr := GetObject(sADSPath) as IADsUser;
        memo1.lines.add('User: ' + Usr.FullName);
        Lst := usr.Groups._NewEnum as IEnumVariant_D4;
        while Lst.next(1,o,@l) = 0 do begin
        grp:=IUnknown(o) as IAdsGroup;
        if l = 1 then begin
        memo1.lines.add(o.name);
        memo1.lines.add(grp.name);
        end
        else
        memo1.lines.add( '(Fehler)');
        end;
        end;
        </pre>

        Stehen die neuen Sachen nicht zur Verfügung, so muss man auf den Aufruf von OpenSCManager mit dem Flag SC_MANAGER_ENUMERATE_SERVICE zurückgreifen. Über <b>EnumServicesStatus</b> kann man sich dann alle Services auflisten lassen.
        &#10

        Comment


        • #5
          Wie wende ich die Funktion EnumServicesStatus richtig an

          Comment

          Working...
          X