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:
- Don’t run your build server as a Windows Service. I don’t like this option as it’s harder to maintain.
- 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.
[<img title="Allow service to interact with desktop" src="/content/keithdahlby/uploads/2011/08/AllowServiceToInteractWithDesktop.png" alt=""Allow service to interact with desktop" in Windows Service Properties" width="410" height="461" />](/content/keithdahlby/uploads/2011/08/AllowServiceToInteractWithDesktop.png)
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:
If you’re not a PowerShell person:
$svcName = Get-Service -DisplayName *cruise* | select -Exp Name
Find the name of the Cruise Control service (CCService).
$svcKey = Get-Item HKLM:\SYSTEM\CurrentControlSet\Services\$svcName
Grab the Registry key for the service.
$newType = $svcKey.GetValue('Type') -bor 0x100
Get the Type value with the 9th bit set.
Set-ItemProperty $svcKey.PSPath -Name Type -Value $newType
Set the Type value. The PowerShell Registry provider isn’t particularly intuitive here, IMO.