W jakim katalogu działa usługa systemu Windows?

86

Stworzyłem bardzo prostą usługę .NET Windows i zainstalowałem ją za pomocą narzędzia InstallUtil.exe.

W serwisie mam taki fragment kodu:

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

Utworzyłem plik o nazwie test_file.txt w tym samym katalogu co usługa, ale skomentowana część kodu nigdy nie jest wykonywana ...?

Chłopak
źródło
Czy użytkownik uruchamiający usługę ma odpowiednie uprawnienia do pliku?
CSharpAtl

Odpowiedzi:

80

Usługi są uruchamiane z aplikacji o nazwie Service Control Manager. Ta aplikacja znajduje się w katalogu systemowym % WinDir% \ System32

W systemie Windows 7 Ultimate - 64 bity ta ścieżka to w rzeczywistości: % WinDir% \ SysWOW64

Aby uzyskać więcej informacji, zobacz Service Control Manager w witrynie MSDN .

Dzięki Harper Shelby za wskazanie problemu z oryginalnym postem.

Jeff
źródło
1
svchost.exe jest usługodawcą hostingowym większości wewnętrznych usług systemu Windows. Usługi mogą, aw przypadku usług innych niż Windows najprawdopodobniej działają, na innym hoście exe.
Michael
1
Dzięki - upuszczenie tam pliku sprawia, że ​​działa, więc mogę potwierdzić lokalizację: c: \ windows \ system32
Guy
1
@Guy - próbowałem to zbadać. Nie mogę znaleźć `` dobrego '' powodu, chociaż podejrzewam, że jest to katalog, z którego działa SCM (Service Control Manager), a więc jest przekazywany do procesu podrzędnego (usługi) ze środowiska procesu nadrzędnego.
Harper Shelby
Usługi są uruchamiane przez Menedżera sterowania usługami (services.exe), który również znajduje się w% WINDIR% \ system32. Zobacz en.wikipedia.org/wiki/Service_Control_Manager
Dirk Vollmar
2
Dla mnie (w 64-bitowym systemie Windows 7) jest %WinDir%\SysWOW64zamiast tego
Strigoides
97
System.Diagnostics.Trace.WriteLine(Directory.GetCurrentDirectory());

wyświetli bieżący katalog. Umieść ten kod w metodzie uruchamiania usługi i użyj narzędzia takiego jak DebugView, aby sprawdzić dane wyjściowe. Wtedy poznasz folder startowy swojej usługi.

Ta prosta technika będzie przydatna przy wielu problemach w rozwoju usług, szczególnie w przypadku debugowania uruchamiania usług.

Prawdopodobnie spodziewałeś się, że folder roboczy twojej usługi będzie folderem, w którym znajduje się plik wykonywalny usługi (tak samo jak ja). Możesz przejść do tego folderu, używając następujących wierszy kodu:

System.IO.Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);
Dirk Vollmar
źródło
16

Możesz to zrobić tak:

string cwd = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
Directory.SetCurrentDirectory(cwd ?? ".");
yantaq
źródło
1
+1, pozwala to reszcie aplikacji działać tak, jakby była normalnie wywoływanym plikiem .exe, gdzie bieżący katalog jest jego ścieżką. Dzięki, właśnie tego potrzebowałem! Uniknięto konieczności przepisywania kodu używającego ścieżek względnych.
Paul
3

Chciał również wiedzieć, w którym folderze działa usługa systemu Windows, ale kod źródłowy nie był mój, więc nie mogłem go zmodyfikować. Wpisanie sc qc <service name>w wierszu polecenia powoduje wyświetlenie folderu w postaci BINARY_PATH_NAME.

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

gdy zapytanie MyService otrzyma:

C:> sc qc Moja usługa

[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
Ryga
źródło
Jest to ścieżka, w której znajduje się plik binarny usługi, co nie gwarantuje, że jest równe „bieżącemu” katalogowi usługi, który może zmieniać się wiele razy w czasie działania procesu (usługi). Względne nazwy plików (jak w przykładzie OP) są rozpoznawane w odniesieniu do bieżącego katalogu roboczego, a nie katalogu, w którym znajduje się plik wykonywalny.
Christian.K
sc qc apache2.4pokazuje ...BINARY_PATH_NAME : "E:\root\Public Cache\Apache Httpd\httpd-2.4.20-x86-vc11\Apache24\bin\httpd.exe" -k runservice, ale katalog roboczy jest zamiast tego%WinDir%\System32
Pacerier