Hallo, ich habe hier ein C-Programm (srvdemo.exe, geschrieben mit GCC / G++ unter Eclipse), das sich selbst als Windows-Service installieren, als Service laufen und sich auch wieder als Service deinstallieren kann. Jetzt bräuchte ich noch eine Möglichkeit, wie das Programm / der Service gleich am Anfang erkennen kann, ob es / er von der Konsole ("DOS-Fenster") oder vom Windows-System aus gestartet worden ist. Wenn Kommandozeilenparameter angegeben sind, ist das ja kein Problem, die kann man ja z.B. mit "lpCmdLine" auswerten und in diesem Fall ist der Start von der Konsole aus erfolgt. Aber wie geht das, wenn das Programm / der Dienst ohne Kommandozeilenparameter gestartet worden sind ? Der Programmstart erfolgt mit "int WINAPI WinMain()", nicht mit "main()"
:
Verschoben durch Moderator
Wird der Dienst als Dienst gestartet, funktioniert die Verknüpfung mit dem SCM per StartServiceCtrlDispatcher, die schlägt fehl, wenn der Dienst als normales Exe-File gestartet wird. Irgendwo in Deinem Code hast Du ein Array mit Einträgen vom Typ SERVICE_TABLE_ENTRY, mit der Du den Einsprungpunkt für die eigentliche Servicefunktion bekanntgibst. Diese Tabelle wird mit obiger Funktion an den SCM übergeben, der daraufhin diese Funktion aufruft. Der Aufruf von StartServiceCtrlDispatcher erfolgt üblicherweise in main, bzw. müsste bei Dir in WinMain erfolgen. PS. Die Windows-Konsole ist kein "DOS-Fenster".
Hallo, danke, diese Möglichkeit ist mir bekannt. Allerdings kann es relativ lange dauern, bis die Funktion "StartServiceCtrlDispatcher()" beim Konsolenaufruf den Fehler "ERROR_FAILED_SERVICE_CONNECT" zurückgibt. Ich habe noch einen Hinweis auf eine andere Möglichkeit gefunden, allerdings werde ich daraus nicht ganz schlau : "A better way is to query the console mode for the standard output device. When running as a service the console are not availible and this operation will fail." Habt ihr eine Idee, wie das funktionieren soll ?
debugger schrieb: > Jetzt bräuchte ich noch eine Möglichkeit, wie das Programm / der Service > gleich am Anfang erkennen kann, ob es / er von der Konsole > ("DOS-Fenster") oder vom Windows-System aus gestartet worden ist. Hallo, das sind eigentlich 2 Programmsysteme in einem: das eine ist das Konsolenprogramm, das installiert oder deinstalliert, ganz normal wie andere Konsolenprogramme auch. Mit dem Dienst selbst muss das nicht in einer Datei stehen. Der eigentliche Dienst besteht dagegen aus einer Sprungtabelle und den zugehörigen Funktionen, die einzelnen Funktionen werden vom Windows Service Manager aufgerufen. Dazu ist der Konsole Teil nicht nötig. Damit erledigt sich die Frage von selbst. Gruss Reinhard
Sorry, nein. Es ist ein Programm, das sich als Dienst installiert, deinstalliert und auch beim Systemaufruf als Dienst läuft, wenn es als Dienst schon instaliert ist (das prüft es selbständig). Zusätztlich sollte es jetzt am Programmanfang auch noch erkennen können, ob es von der Konsole aus oder vom System aufgerufen wurde.
Eine Alternative wäre es, das Benutzerkonto festzustellen, in dem der Prozess gestartet wird. Das kann nur dann zu Fehlerkennungen führen, wenn Du eine Installation auch in als normalen Konten verwendeten Benutzerkonten vorsiehst.
Früher (TM) war es so, dass die Services auf einem eigenen Service-"Desktop" gestartet werden. Es gab eine eine API Funktion (GetCurrentDesktop? GetCurrentWindowsStation?), mit der man das eifnach rausfinden konnte. Ich weiss aber nicht, ob das noch immer so ist. Letztlich geht das in die gleiche Richtung wieder das Ermitteln, in welchem Benutzer-Kontext das Programm läuft. Services laufen ja unter einem speziellen Konto. Axel
Axel Heider schrieb: > Services laufen ja unter einem speziellen Konto. Können, müssen nicht. Dienste können in beliebigen Konten laufen, sofern diese über das Privileg "logon as service" verfügen.
Tja....dann gibt es da in der Tickkiste vielleicht noch die API Funktionen GetConsoleScreenBufferInfo() und GetStdHandle(). Dait lässt sich zumindest rausfinden, ob eine Konsole da ist Axel
es geht auch noch anders, man kann den parrent von dem eigenen Prozess ermitteln. Wenn es die service.exe ist dann ist man ein Service. Nicht schön geht aber.
Das scheint eine Möglichkeit zu sein. Allerdings heißt das Ding services.exe, mit einem s mehr.
Man kann auch die Servicemanager-API benutzen um den Status abzufragen (QueryServiceStatusEx/ControlService[Ex]). Wenn SERVICE_START_PENDING ==> Service, sonst Konsole
Wie langweilig... :) Axel
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.