Announcement

Collapse
No announcement yet.

ASP COM+ Komponente soll WINNT-Dienst Stoppen und Starten

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

  • ASP COM+ Komponente soll WINNT-Dienst Stoppen und Starten

    Hallo Leute !

    Meine ASP Komponente soll WINNT Dienste starten und stoppen können. Zuerst dachte ich, dies mit einem .vbs Script zu lösen. Allerdings bekomme ich immer den Fehler 80005000. Dieser steht für ADSI Pfadname war ungültig. Ich hatte den Namen verwendet, den mir ein anderes Script aufgelistet hatte. Wer weiß Rat ? Mit welchem Namen muß ich die Dienste ansprechen ??? Wenn ich zum Beispiel ein Script starte, das fragt on DHCP läuft bekomme ich vom Script mit dem Namen "DHCP" die Antwort Wahr. Will ich nun mit diesem Namen den Dienst stoppen oder starten, sagr das Script, der ADSI Pfadname sei ungültig. Wo finde ich die gültigen ADSI Pfadnamen ????

    Eine andere Alternative wäre, den Dienst direkt mit Delphi zu starten/stoppen, allerdings habe ich keinen blassen Schimmer, welche API Aufrufe dazu nötig sind.

    Vielen Dank für jeden Hinweis !

  • #2
    Hallo,

    im Win32-API stehen einige Funktionen für den direkten Zugriff auf den Service Control Manager zur Verfügung. Das folgende Beispiel für einen eigenen Dienst-Guardian demonstriert, wie man programmgesteuert andere Dienste starten und stoppen kann:
    <pre>
    procedure TOSSrvGuard.ServiceExecute(Sender: TService);
    resourcestring
    cExecServiceName = 'OSServiceTest';
    var
    aSrvHdl : SC_HANDLE;
    aSCM : SC_HANDLE;
    aStatus : TServiceStatus;
    Argv : PChar;
    begin
    ServiceThread.ProcessRequests(False);
    aSCM := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
    if (aSCM <= 0) then
    begin
    LogMessage('OSSrvGuard OpenSCManager-Fehler',
    EVENTLOG_ERROR_TYPE, 0, cID_ERROR);
    Exit;
    end;
    ServiceThread.ProcessRequests(False);
    try
    aSrvHdl := OpenService(aSCM, PChar(cExecServiceName),
    SERVICE_ALL_ACCESS);
    if (aSrvHdl <= 0) then
    begin
    LogMessage('OSSrvGuard OpenService-Fehler',
    EVENTLOG_ERROR_TYPE, 0, cID_ERROR);
    Exit;
    end;
    ServiceThread.ProcessRequests(False);
    // überwachten Dienst starten
    Winsvc.StartService(aSrvHdl, 0, Argv);
    // überwachten Dienst kontrollieren
    while not Terminated do
    begin
    ServiceThread.ProcessRequests(False);
    if not QueryServiceStatus(aSrvHdl, aStatus) or
    ((aStatus.dwCurrentState <> SERVICE_RUNNING) and
    (aStatus.dwCurrentState <> SERVICE_START_PENDING)) then
    begin
    CloseServiceHandle(aSrvHdl);
    aSrvHdl := OpenService(aSCM, PChar(cExecServiceName),
    SERVICE_ALL_ACCESS);
    if (aSrvHdl <= 0) then
    begin
    LogMessage('OSSrvGuard OpenService-Fehler',
    EVENTLOG_ERROR_TYPE, 0, cID_ERROR);
    Exit;
    end;
    Winsvc.StartService(aSrvHdl, 0, Argv);
    LogMessage('OSSrvGuard StartService', EVENTLOG_INFORMATION_TYPE, 0, 6);
    end
    else
    Sleep(2000);
    end;
    // überwachten Dienst stoppen
    ServiceThread.ProcessRequests(False);
    if ControlService(aSrvHdl, SERVICE_CONTROL_STOP, aStatus) then
    begin
    while (QueryServiceStatus(aSrvHdl, aStatus)) do
    begin
    if aStatus.dwCurrentState = SERVICE_STOP_PENDING then
    begin
    ServiceThread.ProcessRequests(False);
    Sleep(1000);
    end
    else
    Break;
    ServiceThread.ProcessRequests(False);
    end;
    if aStatus.dwCurrentState <> SERVICE_STOPPED then
    begin
    LogMessage('OSSrvGuard SERVICE_STOPPED-Fehler',
    EVENTLOG_ERROR_TYPE, 0, cID_ERROR);
    Exit;
    end
    else
    LogMessage('OSSrvGuard SERVICE_STOPPED',
    EVENTLOG_INFORMATION_TYPE, 0, cID_STOP);
    end;
    CloseServiceHandle(aSrvHdl);
    finally
    CloseServiceHandle(aSCM);
    end;
    end;
    </pre&gt

    Comment


    • #3
      Hallo Herr Kosch und andere Profis !

      Sorry - aber ich bin zu dämlich. Das Beispiel läßt sich bei mir (XP, D5 Enterprise) nicht kompilieren, was aber bestimmt ursächlich in der Art des Projektes liegt. Ich habe in der Hilfedatei gelesen, das die Unit Forms sich nicht mit der Unit SvcMgr verträgt, weswegen Sie vermutlich an anderer Stelle in diesem Forum zu 2 Applikationen (eine für den Dienst, eine Andere für die Oberfläche) geraten haben. Wie muß denn das Projekt aussehen ? Ich sehe bei anderen Programmen gelegentlich bei der Installation oder Deinstallation ein Command-Fenster auftauchen, meist wenn Treiber installiert werden. Ich komme einfach nicht weiter, obwohl das Problem sicher relativ einfach lösbar ist. Bitte helft mir auf die Sprünge ! Hat jemand ein vollständies Beispiel mit Source für mich ? Bitte senden an [email protected] <B>DANKE</B> - natürlich auch für einfache Antworten und Hilfestellungen

      Comment


      • #4
        Hallo,

        das folgende Beispiel demonstriert, wie man aus einer normalen Anwendung heraus (TForm) die Dienste startet und stoppt. Es muss nur die Unit <b>WinSvc</b> eingebunden werden:
        <pre>
        procedure TFormMain.StartStopService(bStart: Boolean);
        var
        hSCM : THandle;
        hSrv : THandle;
        aSrvStatus : TServiceStatus;
        pSrvArgs : PChar;
        const
        cSRV_NAME = 'Service-Name';
        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>
        Damit der Aufruf erfolgreich ist, muss das Benutzerkonto das NT-Privileg SE_PROF_SINGLE_PROCESS_NAME (alias 'SeProfileSingleProcess') besitzen

        Comment


        • #5
          *prust*
          Ich habe hier einen Dienst der mit zwei Parametern gestartet werden muß. Wie muß ich denn dann die Parameter-Struktur (hier pSrvArgs) aufbauen?? Die Beschreibung das ein PChar ein Zeiger auf ein Array von Zeigern zu Null-terminierten Strings sein muß ist etwas "schwammig".

          GV

          Comment


          • #6
            Hallo,

            &gt;..Array von Zeigern zu Null-terminierten Strings ..

            dies ist eine im Win32 sehr häufig genutzte Technik. Der Datenblock muss dabei so aussehen: <br>
            1. Jeder einzelne Eintrag wird nurch ein Null-Zeichen abgeschlossen. <br>
            2. Der nächste Eintrag schließt an das Nullzeichen seines "Vorgängers" an<br>
            3. Das Ende des Datenblocks wird durch <b>2 aufeinanderfolgende</b> Nullzeichen gekennzeichnet:
            <pre>
            <i>Wert1</i>#0<i>Wert2</i>#0#0
            </pre>
            Ein Beispiel für diese Technik kann über die Suche nach der Zeichenkette <b>AddStringToMULTI_SZ</b> hier im FORUM abgerufen werden (Bsp: <i><a href="/webx?13@@.ee872eb/0">Andreas Kosch "Registry übers Netz von anderem Rechner lesen/schreiben" 10.09.2001 15:10</a></i>)

            Comment

            Working...
            X