Allowing a Windows Service to Interact with Desktop without LocalSystem

One of the biggest roadblocks with getting automated browser tests (we use WatiN) running in a Windows Continuous Integration environment is figuring out how to let the build server interact with the desktop. Typically there have been two options:

  1. Don’t run your build server as a Windows Service. I don’t like this option as it’s harder to maintain.
  2. Run the build service as Local System with “Allow service to interact with desktop”. This limits your ability to manipulate the context in which builds run, for example it’s quite tricky (I believe it’s possible with PsExec) to configure Internet Explorer settings (turn off Auto-Complete, etc) for LocalSystem.
    "Allow service to interact with desktop" in Windows Service Properties

A third option now is to run the build service as a user of your choice and set “Allow service to interact with desktop” through the Windows Registry. A Code Project article identified the necessary Registry setting, but still suggested the account must be LocalSystem. However, the same setting appears to work for other accounts as well. I’ve put together a simple PowerShell script to make the change; just run it with administrative privileges:

$svcName = Get-Service -DisplayName *cruise* | select -Exp Name
$svcKey = Get-Item HKLM:\SYSTEM\CurrentControlSet\Services\$svcName

# Set 9th bit, from
$newType = $svcKey.GetValue('Type') -bor 0x100
Set-ItemProperty $svcKey.PSPath -Name Type -Value $newType

If you’re not a PowerShell person:

  1. $svcName = Get-Service -DisplayName *cruise* | select -Exp Name
    Find the name of the Cruise Control service (CCService).
  2. $svcKey = Get-Item HKLM:\SYSTEM\CurrentControlSet\Services\$svcName
    Grab the Registry key for the service.
  3. $newType = $svcKey.GetValue('Type') -bor 0x100
    Get the Type value with the 9th bit set.
  4. Set-ItemProperty $svcKey.PSPath -Name Type -Value $newType
    Set the Type value. The PowerShell Registry provider isn’t particularly intuitive here, IMO.

About Keith Dahlby

I'm a .NET developer, Git enthusiast and language geek from Cedar Rapids, IA. I work as a software guru at J&P Cycles and studied Human-Computer Interaction at Iowa State University.
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Jason Jarrett

    Thanks for this post. I’ve referenced it in my StatLight documentation.

  • Great article on a topic that seems hard to find information on! Thanks for the script.

    Now, for me this works as far as setting the bitmask in the registry key, but it doesn’t appear to actually have an effect when the service is started on my Windows Server 2008 R2 environment.  If I do `sc interrogate servicename` the type column shows “10  WIN32_OWN_PROCESS” instead of the “110  WIN32_OWN_PROCESS  (interactive)” that it shows when running as the Local System account with the “Allow service to interact with the desktop” checkbox checked.

    EDIT: Scratch that – the server had to be restarted completely in order for the registry change to be picked up. Seems to be working as expected now.

  • Seb


    I have a similiar problem, maybe you have an idea:

    I have a service which schedules a task. This task should run, whether a user is logged on or not and should display a progresswindow, when the user is logged on.

    Do you know, if it is possible to achieve that?

    Thank you

    • I don’t know how to have an app detect if the current user is logged in, no. Good luck!

  • Phil

    I realise it’s an old post but I ended up here when trying to solve a problem so for the benefit of others who may do too, It’s also worth noting this wont work unless service interaction is enabled. Recent versions of Windows Server globally disable service interaction out of the box meaning the settings above are ignored. See for details on how to change this setting in the registry.