views:

424

answers:

3

I'm building a rather specialized screen saver application for some kiosks running Windows XP. Users tend to leave the kiosks without returning the browser to the homepage, so the screen saver does the following:

  1. Launches via the standard screen saver mechanism
  2. Notifies the user that there has been no recent activity, and that the browser will close in X seconds.
  3. If X seconds passes without user activity, the screen saver kills all current browser instances (via Process.GetProcessesByName) and starts a new instance of the browser that points to the configured web site (via Process.Start).
  4. The screen then "blanks out" until a user moves the mouse or presses a key - at this point the screen saver application exits.

When this runs on Windows Vista or 2008, everything works as expected.

However, on Windows XP (which is what the kiosks are running), when the screen saver application exits, the browser process is killed. If I add a Thread.Sleep just before the screen saver exists, I can see and interact with the browser up until the point at which the screen saver exits.

To make matters more confusing, Windows XP does NOT exhibit this behavior when I run the screen saver by clicking the "Preview" button in the settings area - that is, it behaves as expected. The exact same code is run in this case.

I tested this under the .NET 2.0 framework, and later installed .NET 2.0 SP1. On the Windows 2008 workstation, I have 3.5 SP1.

Is there some difference between these versions of .NET with respect to dependencies on launched processes? Is there some flag I can set to make sure that the launched browser process is not "attached" to the screen saver application?

A: 

Try setting Process.StartInfo.UseShellExecute to False (it is True by default) before calling Process.Start(). That way, CreateProcess() is used internally instead of ShellExecute().

Remy Lebeau - TeamB
A: 

Windows XP runs the screen saver on its own virtual desktop. Any process you start from there would inherit the virtual desktop as its own, unless you specify otherwise. When the screen saver exits, the virtual desktop goes away to be replaced by the real one, and poof!

Edit: For more information, see these Microsoft MSDN pages:

Desktops (Windows)
CreateProcess function (Windows)
STARTUPINFO Structure

Mark Ransom
That sounds like it could be the problem - how do you specify which desktop to run the child process in?
+1  A: 

There's some code at CodeProject that wraps the Windows Desktop API. It includes a function to open a new process in a different desktop that you might at least be able to look at if not use directly. (Basically there's a parameter to the Windows API CreateProcess function that allows you to specify which desktop to start the process on.)

If that doesn't work you might also try out my answer to your other question (about using SendMessage inter-process to get another process besides the screen saver process to actually do the launching). It's not the best answer to the process tree issue, but it might actually work if the process tree is not the problem.

Eric Rosenberger
I had to do your second suggestion (IPC). I ended up using the new (to .NET 3.5) NamedPipeServerStream and NamedPipeClientStream classes to implement it, and it works well.I tried the first suggestion first, but from testing it seems like Windows XP follows a "belt and suspenders" rule: it seems to do both kill the process tree and run in a different desktop, and in the end the IPC approach was simpler to implement.