In welchem ​​Verzeichnis wird ein Windows-Dienst ausgeführt?

81

Ich habe einen sehr einfachen .NET Windows-Dienst erstellt und ihn mit dem Dienstprogramm InstallUtil.exe installiert.

Im Service habe ich einen Code als solchen:

if (File.Exists("test_file.txt"))
{
   // Do something clever
}

Ich habe eine Datei mit dem Namen test_file.txt im selben Verzeichnis wie der Dienst erstellt, aber der kommentierte Teil des Codes wird nie ausgeführt ...?

Kerl
quelle
Verfügt der Benutzer, der den Dienst ausführt, über die richtigen Berechtigungen für die Datei?
CSharpAtl

Antworten:

77

Dienste werden über eine Anwendung namens Service Control Manager gestartet. Diese Anwendung befindet sich im Systemverzeichnis % WinDir% \ System32

Unter Windows 7 Ultimate - 64 Bit lautet dieser Pfad tatsächlich: % WinDir% \ SysWOW64

Weitere Informationen finden Sie unter Service Control Manager bei MSDN .

Vielen Dank an Harper Shelby für den Hinweis auf ein Problem mit dem ursprünglichen Beitrag.

Jeff
quelle
1
svchost.exe ist ein Diensthost für die meisten internen Windows-Dienste. Dienste können und im Fall von Nicht-Windows-Diensten höchstwahrscheinlich auf einem anderen exe-Host ausgeführt werden.
Michael
1
Danke - wenn Sie die Datei dort ablegen, funktioniert sie, sodass ich diesen Speicherort bestätigen kann: c: \ windows \ system32
Guy
1
@ Guy - Ich habe versucht, das zu erforschen. Ich kann keinen "guten" Grund finden, obwohl ich vermute, dass dies das Verzeichnis ist, aus dem der SCM (Service Control Manager) ausgeführt wird, und daher aus der Umgebung des übergeordneten Prozesses an den untergeordneten Prozess (den Dienst) übergeben wird.
Harper Shelby
Dienste werden vom Service Control Manager (services.exe) gestartet, der sich ebenfalls in% WINDIR% \ system32 befindet. Siehe en.wikipedia.org/wiki/Service_Control_Manager
Dirk Vollmar
2
Für mich (unter 64-Bit-Windows 7) ist es %WinDir%\SysWOW64stattdessen
Strigoides
97
System.Diagnostics.Trace.WriteLine(Directory.GetCurrentDirectory());

gibt das aktuelle Verzeichnis aus. Fügen Sie diesen Code in die Startmethode Ihres Dienstes ein und überprüfen Sie die Ausgabe mit einem Tool wie DebugView . Dann kennen Sie den Startordner Ihres Dienstes.

Diese einfache Technik ist bei vielen Problemen bei der Dienstentwicklung hilfreich, insbesondere beim Debuggen des Dienststarts.

Sie haben wahrscheinlich erwartet, dass der Arbeitsordner Ihres Dienstes der Ordner ist, in dem sich die ausführbare Dienstdatei befindet (ich auch). Sie können mit den folgenden Codezeilen zu diesem Ordner wechseln:

System.IO.Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);
Dirk Vollmar
quelle
14

Sie können es so machen:

string cwd = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
Directory.SetCurrentDirectory(cwd ?? ".");
yantaq
quelle
1
+1, damit der Rest der Anwendung so funktioniert, als wäre es eine normal aufgerufene EXE-Datei, in der das aktuelle Verzeichnis der Pfad ist. Danke, genau das habe ich gebraucht! Es wurde vermieden, Code neu schreiben zu müssen, der relative Pfade verwendete.
Paul
2

Wollte auch wissen, in welchem ​​Ordner ein Windows-Dienst ausgeführt wurde, aber der Quellcode gehörte nicht mir und konnte daher nicht geändert werden. sc qc <service name>Wenn Sie die Eingabeaufforderung eingeben, wird der Ordner in BINARY_PATH_NAME angezeigt.

C:\>sc qc
DESCRIPTION:
        Queries the configuration information for a service.
USAGE:
        sc <server> qc [service name] <bufferSize>

bei Abfrage MyService erhalten:

C:> sc qc MyService

[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: MyService
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 3   DEMAND_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : "D:\Routines\MyService\MyService.exe"
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : MyService
        DEPENDENCIES       :
        SERVICE_START_NAME : LocalSystem
Riga
quelle
Dies ist der Pfad, in dem sich die Dienstbinärdatei befindet, der nicht garantiert dem "aktuell funktionierenden" Verzeichnis des Dienstes entspricht, das sich während der Betriebszeit des (Dienst-) Prozesses mehrmals ändern kann. Relative Dateinamen (wie im Beispiel des OP) werden für das aktuelle Arbeitsverzeichnis aufgelöst, nicht für das Verzeichnis, in dem sich die ausführbare Binärdatei befindet.
Christian.K
sc qc apache2.4zeigt ...BINARY_PATH_NAME : "E:\root\Public Cache\Apache Httpd\httpd-2.4.20-x86-vc11\Apache24\bin\httpd.exe" -k runservice, aber das Arbeitsverzeichnis ist stattdessen%WinDir%\System32
Pacerier