[python-win32] Interacting with the desktop as a service on Vista

Larry Bates larry.bates at websafe.com
Wed Oct 22 06:41:37 CEST 2008


Matt Herbert (matherbe) wrote:
> Hey all,
> 
> So I have a service that needs to interact with the desktop on a Vista
> machine. I've read multiple articles about Vista's updated security and
> it's restrictions on services. So I realize that in order for the
> service to interact with desktop, I'm going to need to create a new
> process as a "normal" user, and use some form of IPC between the child
> process and my service to get at the information I need.
> 
> I've done some research and found an example program on MSDN titled
> "Starting an Interactive Client Process in C++"
> (http://msdn.microsoft.com/en-us/library/aa379608(VS.85).aspx). With a
> little patience, I translated the program into various win32api calls,
> and got almost everything working. The one thing I can't seem to get
> working, is the new child process I create (via CreateProcessAsUser)
> does not seem to be attached to the winsta0\default desktop. Even though
> I have explicitly created a STARTUPINFO object and set the lpDesktop to
> 'winsta0\\default':
> 
> si = win32process.STARTUPINFO()
> si.lpDesktop = 'winsta0\\default'
> pinfo = win32process.CreateProcessAsUser(
>     hToken,
>     None,
>     command,
>     None,
>     None,
>     False,
>     win32con.NORMAL_PRIORITY_CLASS | win32con.CREATE_NEW_CONSOLE,
>     None,
>     None,
>     si)
> 
> My child process starts up just fine, but is not able to interact with
> the desktop in any way. When I check in task manager, it shows the
> session id for the child process as 0, while my "normal" applications
> (such as firefox) are running under session id 1. (FWIW, the user of the
> child process is my "normal" (non SYSTEM) user in task manager). 
> 
> I've also tried to force my way onto the default desktop in the child
> process:
> 
> hwinsta = win32service.OpenWindowStation(
>                 "winsta0", False, win32con.READ_CONTROL)
> hwinsta.SetProcessWindowStation()
> hdesk = win32service.OpenDesktop('default', 0, False, DESKTOP_ALL)
> hdesk.SetThreadDesktop()
> 
> But when the child tries to do this, it dies with the following
> exception:
> 
> Traceback (most recent call last):
>   File "C:\Spawn.py", line 723, in <module>
>     hdesk.SetThreadDesktop()
> pywintypes.error: (170, 'SetThreadDesktop', 'The requested resource is
> in use.')
> 
> I can't figure out where to go from here, so any hints would be greatly
> appreciated.
> 
> -Matt

What exactly does 'interact with the desktop' mean to you?  If it means that you 
want a desktop application (maybe something setting in the SystemTray) that can 
communicate with the service that is relatively easy.  I think using threading 
is probably over-complicating things.  The first way is to make your service a 
socket server and the desktop application a socket client.  Pass messages 
between the two over a socket that is read by the client.  I've done this and it 
doesn't take a lot of code..  One thing I've been looking at is using logging 
module's socket transport to "feed" a log to a client-side socket server.  Now 
that is the "other way around", but is holds some promise as the logging module 
is a standard and the client application could be a socket server that collected 
and displayed the logging messages (which is mostly what SystemTray applications 
do anyway).  Logging is going on all the time, but when the SystemTray 
application is running/visible it displays the messages to the user.  Hope this 
helps.

-Larry



More information about the python-win32 mailing list