Debugging .NET Windows Services That Fail to Auto-Start After Reboot: Timeout and Dependency Issues


4 views

When .NET Windows services mysteriously fail to auto-start after system reboot while working perfectly during manual starts, we're typically dealing with one of these underlying issues:

// Classic symptom pattern in Event Viewer
Event ID 7036: "The YourServiceName service entered the stopped state."
Event ID 7022: "A timeout (30000 milliseconds) was reached while waiting for...slsvc"

The SCM (Service Control Manager) attempts to start services in parallel, but certain system services (like slsvc - Software Licensing Service) create implicit dependencies. Your service might be getting blocked by:

  • Delayed system service initialization
  • Missing explicit dependencies in service configuration
  • Resource contention during boot phase

First, confirm the actual dependencies using PowerShell:

Get-Service -Name "YourService" -RequiredServices
Get-Service -Name "YourService" -DependentServices

# Check for start failures
Get-WinEvent -FilterHashtable @{
    LogName='System'
    ProviderName='Service Control Manager'
    ID=7000,7022,7031
} | Where-Object {$_.Message -like "*YourService*"}

For .NET services, we need to modify both the service implementation and installation configuration:

// Add in your ServiceBase implementation
protected override void OnStart(string[] args)
{
    // Implement retry logic for dependent services
    var retryCount = 0;
    while (!IsDependencyReady() && retryCount < 5)
    {
        Thread.Sleep(5000);
        retryCount++;
    }
    
    if (!IsDependencyReady())
    {
        throw new Exception("Dependencies not available");
    }
    
    // Proceed with normal startup
    base.OnStart(args);
}

private bool IsDependencyReady()
{
    try 
    {
        using (var sc = new ServiceController("slsvc"))
        {
            return sc.Status == ServiceControllerStatus.Running;
        }
    }
    catch
    {
        return false;
    }
}

When installing via InstallUtil or sc.exe, explicitly declare dependencies:

sc config "YourService" depend= "RpcSs/Netman/slvc"

# Or in C# installation code:
using (var serviceInstaller = new ServiceInstaller())
{
    serviceInstaller.ServicesDependedOn = new string[] { "RpcSs", "Netman", "slsvc" };
}

For stubborn cases, modify the service's registry key to increase timeout:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\YourService]
"DelayedAutostart"=dword:00000001
"ServicesPipeTimeout"=dword:000ea600  // 60 seconds timeout

Remember to restart the service after making these changes:

sc failure "YourService" reset= 86400 actions= restart/60000/restart/60000/restart/60000

Simulate the reboot sequence without actually rebooting:

# Force service stop
Stop-Service -Name "YourService" -Force

# Start with dependencies
Start-Service -Name "RpcSs"
Start-Service -Name "Netman"
Start-Service -Name "slsvc"

# Now attempt your service start
Start-Service -Name "YourService"

When working with Windows Services built using .NET framework, a particularly frustrating scenario occurs when services marked as Automatic fail to initialize during system startup. The event logs typically show:

Event 7036: The xyz service entered the stopped state.
Event 7011: A timeout (30000 milliseconds) was reached while waiting for a transaction response from the slsvc service.

Through extensive troubleshooting, we've identified these primary culprits:

  • Dependency Chain Issues: The service might depend on other components that aren't ready
  • Time Synchronization Problems: Particularly in virtualized environments
  • Service Control Manager (SCM) Timeout: Default 30-second limit being exceeded

The core problem stems from how Windows handles service initialization order. The SCM has a strict timeout policy:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
   WaitToKillServiceTimeout = 20000 (default value in milliseconds)

For .NET services, we can implement better startup handling:

public class MyService : ServiceBase
{
    protected override void OnStart(string[] args)
    {
        ThreadPool.QueueUserWorkItem(_ => 
        {
            // Immediate response to SCM
            RequestAdditionalTime(30000);
            
            // Actual initialization logic
            InitializeServiceComponents();
        });
    }
}

Here are three approaches that have consistently worked in production environments:

1. Service Dependency Configuration

sc config "YourService" depend= "RpcSs/DcomLaunch"

2. Registry Modification

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control]
"ServicesPipeTimeout"=dword:000493e0

3. Implementing Recovery Options

sc failure "YourService" reset= 86400 actions= restart/60000/restart/60000/restart/60000

For particularly stubborn cases:

  1. Enable service debug logging:
    [DllImport("advapi32.dll", SetLastError=true)]
    private static extern bool ReportEvent(
        IntPtr hEventLog, short wType, ushort wCategory,
        uint dwEventID, byte[] lpUserSid, ushort wNumStrings,
        uint dwDataSize, IntPtr lpStrings, byte[] lpRawData);
  2. Analyze with Process Monitor (ProcMon) filters:
    Operation: CreateFile
    Path: ends-with ".dll" OR ends-with ".config"
    Process Name: YourService.exe
  • Implement proper service health checks
  • Add delayed retry logic for dependent resources
  • Consider using Windows Task Scheduler as fallback