Windows Service: Can I configure the current working directory?

35,651

Solution 1

You could use DLL injection to call SetCurrentDirectory after the process has already launched. This would require you to build an injector application, plus the DLL to inject. Some tutorials exist; probably the two best ones I've found are:

You'll need a decent amount of C++ programming background (and a working build environment) to get through that.

However, this assumes that the service is looking at the current directory. Another possibility is that it's using %path%. You say that it "starts at system32, tries a few more locations, and eventually its own directory", so this seems more likely to me.

Compare the directories you see in procmon with your %path%. If they're the same, consider modifying either the SYSTEM %path% or the %path% of the user running the service, so that the directory you want it to search is first.

I believe Fred is right, though -- you're unlikely to see any significant performance benefit by doing any of this, unless it's happening very frequently. Simple file open operations are not particularly expensive, especially if it's a local path and the file doesn't actually exist.

Solution 2

Do this within the Service main function:

  • Make a call to GetModuleFilename. It will retrieve the module (the exe) filename including path, in the form C:\path\to\exe\your_service.exe.
  • Use string manipulations (maybe using std::string function find_last_of()), to find the last backslash. Strip/trim the string from there on to obtain the path to your module and therefore the directory of your exe.
  • Make a call to the function SetCurrentDirectory and voila!

Solution 3

Add an "AppDirectory" string value to the Parameters Key and set the value to your desired working directory.

Solution 4

Like MattB, I don't know of any way to change the service's working directory w/o access to the source code. For this specific scenario, it's likely that the extra directory checks don't impose that much unnecessary disk activity relative to the amount of i/o required for the full text indexing operation. Even if you could optimize them away, the full text index will be disk intensive by the nature of the beast.

Share:
35,651

Related videos on Youtube

Tomalak
Author by

Tomalak

I know a bit about SQL, Regular Expressions, XSLT, ColdFusion, JavaScript, scripting in general.

Updated on September 17, 2022

Comments

  • Tomalak
    Tomalak almost 2 years

    By default, Windows services start in the sytem32 directory (usually C:\WINDOWS\system32).

    Is there a way to set up a different working directory? I am thinking of some registry parameter beneath HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SomeService.

    So - can this be done?

    • Admin
      Admin over 14 years
      @Tomalak: Is it a service you wrote? You can do it through code, but I don't think there is a way through the service settings.
    • Admin
      Admin over 14 years
      No, it isn't a service I wrote. I was hoping some little-known registry setting here.
    • Admin
      Admin over 14 years
      What is the purpose of doing it?
    • Admin
      Admin over 14 years
      @user35115: Well, to be honest… While tracking down an unrelated problem with procmon, I noticed that a certain I/O-heavy service (a full text indexer) consistently checks for its own files in the wrong locations (pretty dumb). It starts at system32, tries a few more locations, and eventually its own directory. I figured when it would run in its own directory right away, it would do less unnecessary file checks. Not that it would not work currently, yet it made me wonder if there was room for improvement.
    • Admin
      Admin about 8 years
      @user35115, To avoid having to mass change configuration settings of a certain app (say Apache, etc), which are all relative to the working directory.
  • Marnix van Valen
    Marnix van Valen over 14 years
    The system PATH environment variable was the first thing that came to mind for me. Inserting the service's path at the start of the PATH variable will however have a negative effect on the performance of just about every other application so I wouldn't advise that.
  • fission
    fission over 14 years
    I don't have hard numbers to back this up either way, but my intuition tells me that no practical performance gain or loss would occur from modifying the path. This is a fairly common scenario; nobody blames, say, the Windows Support Tools, or SQL Server, for negatively impacting system performance when it modifies the path during installation. This isn't the first time I've seen someone look at procmon and go "omg, look at all those file accesses!", not realizing that it's typical for most applications.
  • Tomalak
    Tomalak over 14 years
    +1 for creativity. :-) I fully understand that these file operations do not impact performance measurably, so I'm not going to actually bother writing a DLL injection solution. Modifying %PATH% for the user account the service runs under is a decent idea, though.
  • Sunny
    Sunny over 14 years
    Creating a special user to run this service only and modifying the %PATH% for this user sounds as a very good way to go. +1
  • Tomalak
    Tomalak over 14 years
    @fission: Yes, it does mean I accept your answer. ;) It's not what I had hoped for, but it is as close as it gets, I guess.
  • Tomalak
    Tomalak over 13 years
    Hm. Just tested, does not seem to work (On Windows 7, used REG_EXPAND_SZ data type). Can you re-confirm this actually works for you, please?
  • uprightech
    uprightech over 13 years
    do not forget to pass null to the HMODULE parameter in the GetModuleFilename function call :)
  • Konstantin Spirin
    Konstantin Spirin over 13 years
    This works when using srvany. Not sure about normal services.