What directory does a Windows Service run in?
Asked Answered
S

5

100

I've created a very simple .NET Windows Service and installed it using InstallUtil.exe utility.

In the service I have a piece of code as such:

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

I've created a file called test_file.txt in the same directory as the service but the commented part of the code is never being executed...?

Supercharger answered 19/5, 2009 at 20:53 Comment(1)
Does the user that runs the service have correct permissions on the file?Bring
S
93

Services are started from an application called Service Control Manager. This application lives in the system directory %WinDir%\System32

On 64-bit versions of Windows 7+ this path is actually: %WinDir%\SysWOW64

For more information see Service Control Manager at MSDN.

Spacial answered 19/5, 2009 at 20:59 Comment(4)
svchost.exe is a service host for most internal windows services. Services can, and in the case of non-Windows services most likely do, run in a different exe host.Bolduc
Thanks - dropping the file in there makes it work so I can confirm that location: c:\windows\system32Supercharger
@Supercharger - I was trying to research that. I can't find a 'good' reason, though I suspect it's because that's the directory that the SCM (Service Control Manager) runs from, and so it gets passed to the child process (the service) from the parent process's environment.Enesco
Services are started by the Service Control Manager (services.exe) which also resides in %WINDIR%\system32. See en.wikipedia.org/wiki/Service_Control_ManagerCaesarism
C
111
System.Diagnostics.Trace.WriteLine(Directory.GetCurrentDirectory());

will output the current directory. Put that code in the startup method of your service and use a tool like DebugView to check the output. Then you will know the startup folder of your service.

This simple technique will be useful with many problems in service development, especially to debug service startup.

You probably expected the working folder of your service to be the folder where the service executable is in (so did I). You can change to that folder using the following lines of code:

System.IO.Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);
Caesarism answered 19/5, 2009 at 21:19 Comment(0)
S
93

Services are started from an application called Service Control Manager. This application lives in the system directory %WinDir%\System32

On 64-bit versions of Windows 7+ this path is actually: %WinDir%\SysWOW64

For more information see Service Control Manager at MSDN.

Spacial answered 19/5, 2009 at 20:59 Comment(4)
svchost.exe is a service host for most internal windows services. Services can, and in the case of non-Windows services most likely do, run in a different exe host.Bolduc
Thanks - dropping the file in there makes it work so I can confirm that location: c:\windows\system32Supercharger
@Supercharger - I was trying to research that. I can't find a 'good' reason, though I suspect it's because that's the directory that the SCM (Service Control Manager) runs from, and so it gets passed to the child process (the service) from the parent process's environment.Enesco
Services are started by the Service Control Manager (services.exe) which also resides in %WINDIR%\system32. See en.wikipedia.org/wiki/Service_Control_ManagerCaesarism
S
18

You can make it work like so:

string cwd = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
Directory.SetCurrentDirectory(cwd ?? ".");
Sihun answered 15/1, 2013 at 23:41 Comment(3)
+1, this allows the rest of the application to function as if it were a normally-invoked .exe where the current directory is it's path. Thanks, this is exactly what I needed! Avoided having to rewrite code that used relative paths.Warmongering
@Warmongering I would note that “normally invoked” means double-click from the explorer. When an .exe is invoked from console, link, script or another application, the current directory can be anything. So this is appropriate for finding application resources in many other contexts too.Belfort
@JanHudec I did not expect a response nearly 10 years later, but I agree! :-)Warmongering
F
2

Wanted also to know in which folder a Windows service was running but source code was not mine so could not modify it. Typing in Command Prompt sc qc <service name> displays the folder in BINARY_PATH_NAME.

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

when query MyService get:

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
Finite answered 30/11, 2015 at 12:54 Comment(2)
That is the path where the service binary is located, which is not guaranteed to be equal to the "current working" directory of the service which can change multiple times during the uptime of the (service) process. Relative filenames (as in the OPs example) are resolved against the current working directory, not the directory where the executable binary is located.Conventual
sc qc apache2.4 shows ...BINARY_PATH_NAME : "E:\root\Public Cache\Apache Httpd\httpd-2.4.20-x86-vc11\Apache24\bin\httpd.exe" -k runservice, but the working directory is instead %WinDir%\System32Croquette
T
0

From SC start service in folder /Start in:/: One simple alternative is to use nssm.cc - this gives you the option of specifying a directory to start in.

Tearoom answered 23/11, 2020 at 15:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.