mikrocontroller.net

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


Autor: debugger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: debugger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Reinhard Kern (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: debugger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Axel H. (axelh)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Axel H. (axelh)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

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

Autor: ... (Gast)
Datum:

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

Autor: Axel H. (axelh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie langweilig... :)

Axel

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.