179

I have a Windows Service that makes use of a SQL Server database. I don't have control over the installation of the service, but would like to add a dependency on the service to ensure that it starts after SQL server has started. (SQL server is running on the same machine as the service in question)

Is there a tool to add a dependency or possibly editing the registry directly?

squillman
  • 38,163
Rick
  • 1,935

6 Answers6

259

This can also be done via an elevated command prompt using the sc command. The syntax is:

sc config [service name] depend= <Dependencies(separated by / (forward slash))>

Note: There is a space after the equals sign, and there is not one before it.

Warning: depend= parameter will overwrite existing dependencies list, not append. So for example, if ServiceA already depends on ServiceB and ServiceC, if you run depend= ServiceD, ServiceA will now depend only on ServiceD. (Thanks Matt!)

Examples

Dependency on one other service:

sc config ServiceA depend= ServiceB

Above means that ServiceA will not start until ServiceB has started. If you stop ServiceB, ServiceA will stop automatically.

Dependency on multiple other services:

sc config ServiceA depend= ServiceB/ServiceC/ServiceD/"Service Name With Spaces"

Above means that ServiceA will not start until ServiceB, ServiceC, and ServiceD have all started. If you stop any of ServiceB, ServiceC, or ServiceD, ServiceA will stop automatically.

To remove all dependencies:

sc config ServiceA depend= /

To list current dependencies:

sc qc ServiceA
Kip
  • 3,700
47

You can add service dependencies by adding the "DependOnService" value to the service in the registry using the regedit command, services can be found under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\<Service name>.

Details can be found at MS KB article 193888.

To add dependency:

  1. Select the service subkey, right-click the service name, and then select "New" -> "Multi-String Value" (REG_MULTI_SZ)

    enter image description here

  2. Create a new value name "DependOnService" (without the quotation marks), and then click OK.

    enter image description here

  3. When the Data dialog box appears, type the name or names of the services that you prefer to start before this service with one entry for each line, and then click OK.

Ivan Chau
  • 275
pauska
  • 19,766
5

I was looking for a purely PowerShell (no regedit or sc.exe) method that can work on 2008R2/Win7 and newer, and came up with this:

Easy one is do the regedit with PowerShell:

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation' -Name DependOnService -Value @('Bowser','MRxSmb20','NSI')

Or, using WMI:

$DependsOn = @('Bowser','MRxSmb20','NSI','') #keep the empty array element at end
$svc = Get-WmiObject win32_Service -filter "Name='LanmanWorkstation'"
$svc.Change($null,$null,$null,$null,$null,$null,$null,$null,$null,$null,$DependsOn)

The Change method of the Win32_Service class helped point to a solution:

uint32 Change(
[in] string  DisplayName,
[in] string  PathName,
[in] uint32  ServiceType,
[in] uint32  ErrorControl,
[in] string  StartMode,
[in] boolean DesktopInteract,
[in] string  StartName,
[in] string  StartPassword,
[in] string  LoadOrderGroup,
[in] string  LoadOrderGroupDependencies[],
[in] string  ServiceDependencies[]
);
1

I wrote a simple .net application to manage service dependencies, if you are interested. It's free.

http://webpages.charter.net/bushman4/servicedependencymanager.html

1

In C++ (ATL) I did like this

bool ModifyDependOnService(void)
{
  CRegKey R;
  if (ERROR_SUCCESS == R.Open(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\services\\MyService"))
  {
    bool depIsThere = false;

    // determine if otherservice is installed, if yes, then add to dependency list.
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
    if (hSCManager)
    {
      SC_HANDLE hService = OpenService(hSCManager, L"OtherService", SERVICE_QUERY_STATUS);
      if (hService)
      {
        depIsThere = true;
        CloseServiceHandle(hService);
      }
      CloseServiceHandle(hSCManager);
    }

    std::wstring key = L"DependOnService";
    if (depIsThere )
    {
      const wchar_t deps[] = L"RPCSS\0OtherService\0";
      R.SetValue(key.c_str(), REG_MULTI_SZ, deps, sizeof(deps));
    }

    R.Close();
    return true;
  }
  return false;
}
AndersK
  • 111
0

Made a batch "svcDependDelAdd.BAT" to delete and/or add a dependency to a service, it won't add if it doesn't exist. Can be called. The advantage over accepted answer is that it won't delete other dependencies, just delete (or add) the one you need. Help included:

@echo off
set PARAM=%* _& REM _ avoid PARAM being empty if no param passed, %* are rest of parameters passed
rem https://serverfault.com/questions/24821/how-to-add-dependency-on-a-windows-service-after-the-service-is-installed/1165202#1165202

IF not "%PARAM:/noh=%"=="%PARAM%" goto :noHelp echo . echo . svcDependDelAdd v24.0915 echo . Removes and/or adds a dependency service, "none" may be specified: echo . echo . svcDependDelAdd targetSvc [[dependSvcToDelete] dependSvcToAdd] [/switches] echo . echo . echo . switches: echo . /noHelp: don't show this echo . /noPause: at end echo . echo . Examples: echo . svcDependDelAdd nlaSvc /noh/nop (list of nlaSvc depends separated by \0^) echo . svcDependDelAdd nlaSvc eventLog (Removes eventLog dependency from nlaSvc^) echo . svcDependDelAdd none eventLog (Adds eventLog dependency to nlaSvc^) echo . echo . :noHelp

setlocal enableextensions enableDelayedExpansion & REM to get var value at exec with !varNm! rem Target service, ie: "nlaSvc"; or "aelookupsvc" has no dependenies set "targSvc=%1" rem set to "none" if it is empty, or if it has a slash {/ switch} IF not "!targSvc:/=!"=="!targSvc!" set "targSvc=none" rem Dependency to del, may be blank/invalid/undef, ie: "Eventlog" set "delDep=%2" IF not "!delDep:/=!"=="!delDep!" set "delDep=none" rem dependency to add, may be blank/none/undef, won't add unexistant service set "addDep=%3" IF not "!addDep:/=!"=="!addDep!" set "addDep=none" rem echo "%targSvc%" "%delDep%" "%addDep%"

rem check service existance if not "!targSvc:none=!"=="" ( rem not "none" and not empty sc qc "!targSvc!" >nul 2>&1 if errorlevel 1 ( set errMsg=Svc "%targSvc%" not found & goto :error ) ) else ( set errMsg=No service specified & goto :error )

rem Get dependencies list of %targSvc% set depList=\0 for /f "usebackq tokens=1,2,*" %%x in (reg query HKLM\System\CurrentControlSet\Services\%targSvc% /v DependOnService) do ( if "%%y"=="REG_MULTI_SZ" set "depList=%%z\0" ) & rem endList

rem delete: find it and set newDep list set "newDep=!depList!" & rem newDep list to set if "!depList!"=="\0" ( echo %targSvc% no dependencies found! ) else ( echo "%targSvc%" dependencies list: "!depList!" rem remove dependency from newDep if not "!delDep:none=!"=="" ( set "newDep=!depList:%delDep%\0=!" rem set "newDep=!newDep:\0\0=\0!" if "!newDep!"=="!depList!" ( echo "%delDep%" not found in "%targSvc%" ) else echo del "%delDep%" found ) & rem delDep )

rem add: find and set newDep list if not "!addDep:none=!"=="" if "!newDep:%addDep%\0=!"=="!newDep!" ( rem not none/empty, and not already present on newDep list reg query HKLM\System\CurrentControlSet\Services%addDep% 1>nul 2>&1 if errorlevel 1 ( echo add "%addDep%" not found ) else ( echo add "%addDep%" found set "newDep=!newDep!%addDep%\0" & rem add to list if "!depList!"=="\0" set "newDep=%addDep%" & rem original list was empty ) ) else echo add "%addDep%" already present

rem write newDep list if "!newDep!"=="!depList!" ( echo Nothing to do... ) else ( echo newDep List "!newDep!" ... reg add HKLM\System\CurrentControlSet\Services%targSvc% /v DependOnService /t REG_MULTI_SZ /d "!newDep!" /f if errorlevel 1 ( set errMsg=couldn't update "%targSvc%" DependOnSevice key & goto :error ) )

echo -DONE- goto :fin

:error echo\ Error: !errMsg!

:fin echo
IF "%PARAM:/nop=%"=="%PARAM%" pause