views:

261

answers:

2

I have created a service which display a sort of splash screen on the desktop of a specific user and only when that user is logged in (kiosk user).

That splash screen, once entered a valid code, will tell that to the service and the service goes to sleep for an x amount of time (depending of the code).

The splash screen simply quits. Now when the service wakes up it sees that the splash is no longer there and so start it up.

This all is working, the only problem is that the launched application does not have focus, i.e. if I am working in notepad and the time is up, the splash screen is displayed (full screen though) behind notepad.

I only have to worry about Windows Vista, I am coding in Python using win32 extensions but I believe this problem lies in CreateProcessAsUser when called from the LocalSystem account.


Update:

The 'problem' is actually an on purpose limitation to prevent 'irritating' applications like mine from stealing focus.

You can change the behaviour by setting: win32gui.SystemParametersInfo(win32con.SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0) which is equivalent in temporarily setting the registry value: HKEY_CURRENT_USER\Control Panel\Desktop\ForegroundLockTimeout This must be done as the user itself, so either build it in the app you are launching or build an launching helper for the app you want to launch.

However an application might want to prevent getting it's focus stolen by using some API call which I don't remember right now.

A probably good solution would be to find all window handles currently from that user and then use each of these handles to use win32gui.ShowWindow(handle, command) to minimize it.

Although for this particular problem setting the locktimeout setting was enough.

If anyone wonders how I managed to launch an application to a desktop from a service, here is a link to the code.

+2  A: 

Have you tried launching another processes than your own from the service to see if it gets focus? Like notepad and see if it steals focus from your browser? If so perhaps its the program that can take back the focus when it starts.

I otherwise beilive it's the wShowWindow attribute from the STARTUPINFO struct the lpStartupInfo points to that should control it. You also need STARTF_USESHOWWINDOW in dwFlags to use nShowWindow. The values should be SW_SHOW i think, they are listed for the ShowWindow function if you want to try other.

Stefan Lundström
Yes I have these flags set, thanks for the heads-up though. I also set the register value of ForegroundLockTimeout in current_user controlpanel desktop to 0. Which has helped somewhat, amusingly it does it work now for most some applications to steal focus except from notepad :-)
Martin P. Hellwig
A: 

For various very legitimated reasons, Microsoft would rather not see a service launching an app and stealing focus, however I found the following work around to still accomplish what I want.

The original intend is to have a kiosk like application hindered by a pass code like splash screen, which upon entering a 8 character code closes the splash screen for a period time as in the pass code defined. Originally the actual application to use was started by the autostart folder.

However I now rewrote it that it is launched from my service, this way I can hide the application by launching an helper application from the service that just hides the program and launches the splash screen, upon exiting the splash screen the program is returned to the previous state.

Martin P. Hellwig