Forum: PC-Programmierung Windows-Service / Applikation : Unterscheidung Startart (System / Konsole)


von debugger (Gast)


Lesenswert?

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
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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".

von debugger (Gast)


Lesenswert?

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 ?

von Reinhard Kern (Gast)


Lesenswert?

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

von debugger (Gast)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Axel H. (axelh)


Lesenswert?

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

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Axel H. (axelh)


Lesenswert?

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

von Peter (Gast)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das scheint eine Möglichkeit zu sein. Allerdings heißt das Ding 
services.exe, mit einem s mehr.

von ... (Gast)


Lesenswert?

Man kann auch die Servicemanager-API benutzen um den Status abzufragen 
(QueryServiceStatusEx/ControlService[Ex]).
Wenn SERVICE_START_PENDING ==> Service, sonst Konsole

von Axel H. (axelh)


Lesenswert?

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
Noch kein Account? Hier anmelden.