I have two executables, let's call them A and B. As A is terminating, I want it to launch B and then terminate. B is actually an installer, and one of the things it will do is replace the file A.exe, so A really cannot be open (running) when B does it's work.
When I use System.Diagnostics.Process.Start, B appears to be running somehow within the context of A, because if I don't make A wait for B to finish as in:
Process pr = new Process();
pr.StartInfo.FileName = installerPath;
pr.Start();
//pr.WaitForExit();
B dies (rather ungracefully) as A terminates. If I make A wait for B to finish (uncommenting out the WaitForExit), then B cannot update A's file since A is still running.
What I really want is a way for A to start B in such a way that B is completely independent of A. Then A could terminate and B could update A.exe.
Can anyone give me any idea how to accomplish this?
Thanks,
Matt S.
Matt SellersPosted Feb 12, 2008, 4:48 PM
Alan,
Thank you again for all your time and help! I will fall back to my previous scheme. I had a solution before, but it is much less eligant than running from the screensaver. Of course a working solution is preferable to an eligant solution that is impossible. Thanks for stopping me from persuing this further.
Matt
AlanPosted Feb 12, 2008, 10:42 AM
Ah, I think the problem here, Matt, is that once you install the screensaver the OS runs it in a separate desktop from the so called 'default' desktop in which windows display and input normally takes place. Any processes which it spawns will likewise be run in the screensaver desktop and will therefore be automatically shut down when the screensaver ends and the OS switches back to the default desktop.
See, for example, this MSDN link which I've managed to track down:
http://msdn2.microsoft.com/en-us/library/ms682573(VS.85).aspx
In the light of this, I suspect that what you are trying to do is impossible and that you need some other way of launching the installer. What might work is to use a batch file to run the screensaver and then the installer. The only problem is that you'll probably be left with a console window to shut down when the batch file ends.
Matt SellersPosted Feb 11, 2008, 2:27 PM
Alan,
Thanks for all the help. I really appreciate it.
Application A is a screen saver, based on a Microsoft .Net 2.0 sample.
The installer is a complied NSIS script.
At the end of the screensaver's Main() method just before it ends, I added:
Application.Exit();
RunUpdateInstaller();
I can see from my log entries that RunUpdateInstaller is being executed. If I run the screensaver from Visual Studio in debug mode, the installer actually appears when the screensaver ends. If I run it as an installed screensaver, I do not see the installer and I can tell (by deleting a file the installer installs) that the installer is not running in silent mode.
Here's the code for RunUpdateInstaller():
private static void RunUpdateInstaller(){
Registry myRegistry = new Registry();
if (myRegistry.GetKey("RunInstaller") != string.Empty)
{
Log("Screensaver running update installer");
string installerPath = myRegistry.GetKey("InstallDir") + \\Installer.exe;
if (File.Exists(installerPath))
{
Process pr = new Process();
pr.StartInfo.FileName = installerPath;
pr.Start();
//pr.WaitForExit();
}
myRegistry.DeleteKey("RunInstaller");
Log("Screensaver removed update installer indicator in registry");
}
} Thanks again,
Matt
AlanPosted Feb 11, 2008, 6:48 AM
Is Program A by any chance a GUI application?
If it is, then it will be frozen when Program B starts and gets the input focus.
To deal with this you could call Application.Exit() on Program A before you launch Program B and then place the code to launch Program B after the call to Application.Run() in the Main() method which should allow Program A to end naturally whilst Program B is running.
If Program A is a console application then, as I said before, I can't think of any reason why it wouldn't end naturally if you're not calling Process.WaitForExit() and there's no more code of any substance after Program B is launched.
Matt SellersPosted Feb 10, 2008, 2:11 PM
AlanPosted Feb 10, 2008, 12:48 PM
Hi Matt,
I don't think there's any reason why a program spawned using the Process class shouldn't be able to outlive the program which spawned it because I've done this myself many times.
Could you perhaps place a delay in program B so that it waits for a few seconds to allow program A to complete before attempting to replace it?
The delay technique seems to work well when VBScript is used to create a self-deleting executable. See, for example, this thread:
http://www.csharphelp.com/board2/read.html?f=1&i=42249&t=42249