Posted tagged ‘desktop interaction’

Desktop interaction from a Windows Service using DCOM in Vista

April 17, 2009

In one of my recent work I was faced with a situation where desktop interaction was needed from a service. In legacy systems all you have to do was to enable the desktop interaction flag but this will not work in the future releases from the Microsoft.

In windows vista; services are run in a seperate session which is different than the interactive user sessions. It means services can only interact with session zero which elminiates the possibility of service interacting with any of the logged on users. Vista does provide option to enable this interaction but this is allowed only to support legacy services and will be excluded in the future service packs or new OS releases.  Here is the link for the white paper explaining it in detail.

So only way forward is to have a user process communicating with the service using Inter Process Communication methods which include MessgaeQueues, Pipes, Sockets and DCOM. I already had a DCOM ‘out of process’ component so I decided to add a new interface to it which will be used by the service to communicate with the desktop user. At startup service CoCreates the DCOM object and uses the returned Interface pointer to call interface methods.

This approach will work for all the scenarios except where DCOM component has singleton class factory i.e. it will have one instance alive at all times and will return the same object for each new CoCreate call by the client(s). The default behavior for the DCOM component is to acquire the identity of the launching application. If Service running under SYSTEM account instantiate it then this singleton DCOM component (.exe as out of proc in my case) will be running under SYSTEM account. After this if one of the user process needs to access this component and calls CoCreate. This will create another singleton instance running under CURRENT_USER. So component will no longer remain singleton. 

Add the following code snippet under NoRemove AppID block in the DCOM server .rgs file to change the identity to ‘interactive user’.

val RunAs = s 'Interactive User'

Following is the complete file to view as sample.

HKCR
{
NoRemove AppID
{
ForceRemove {2B38654A-8574-4676-AEBB-2E48E3945346} = s 'Name of the exe'
{
val RunAs = s 'Interactive User'
}

'%APPID%' = s 'Name of the exe'
'Name of the exe'
{
val AppID = s '%APPID%'
}
}
}

This way the DCOM server will run as current interactive user even if instantiated by the Service running under SYSTEM in session 0 and we can have a singleton instance independent of the client identities.

Advertisements