Launch the standalone ClickOnce app and wait for the release

I deployed the ClickOnce Windows Forms application (app A)

Another application (application B) starts application A with the file name as a parameter. I am doing this with this code

var basePath = Environment.GetFolderPath(Environment.SpecialFolder.Programs); var location = String.Format(@"{0}\{1}\{2}\{3}", basePath, "MyCompany", "MyProduct", "MyApp.appref-ms"); var fileName = @"c:\temp\somefile.ext"; var uri = new Uri(fileName).ToString(); Process.Start(location, uri); 

Appendix A captures the file name from AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0] and displays the contents.

It works like a charm. However, now I want App B to wait for application A. to exit. But the call to Process.WaitForExit() returns immediately.

Is there a way to open the ClickOnce application and wait for it to exit? If necessary, I can change the way the application is opened, but the requirement is that I need to run the application as a ClickOnce application (I know that somewhere in my user profile folder AppData\Local\Apps\2.0\ exe exists and maybe running directly, but if I do that ApplicationDeployment.IsNetworkDeployed is false and ApplicationDeployment.CurrentDeployment is null, I lose the ability to update ClickOnce).

+6
source share
2 answers

my suggestion would be to use Mutex in app A, and let App B check and wait for it. This is the cleanest way from my point of view.

Appendix A does this at startup:

  private static Mutex mutex; public static void Main() { // if you want your app to be limited to a single instance // across ALL SESSIONS (multiple users & terminal services), then use the following line instead: // string mutexName = string.Format("Global\\{0}", ProgramInfo.AssemblyGuid); var mutexName = string.Format("Local\\{0}", SOME_SHARED_GUID); mutex = new Mutex(true, mutexName, out singleInstance); if (singleInstance == false) { // that means your app has more than one instance running // you need to decide what to do here. } // rest of initialization code Application.Run(); // release the mutex so App B can continue mutex.ReleaseMutex(); } 

and application B is just waiting for the mutex to exit:

 Process.Start(location, uri); Thread.Sleep(5000); // give it 5 seconds or so to check for updates and start var mutexName = string.Format("Local\\{0}", SOME_SHARED_GUID); mutex = new Mutex(false, mutexName); mutex.WaitOne(); 
+2
source

The problem is that starting the appref-ms process does not actually launch the application, which launches the deployment manifest, which then launches the application itself, so the process you start with exits immediately.

You can add a check to see when the application is running, if you know the name (which I assume you do), for example:

 string myAppName = "YourAppName"; DateTime startTime = DateTime.Now; int newProcessId = 0; List<int> runningProcessIds = new List<int>(); //find all the running processes and record their Ids foreach (void proc_loopVariable in Process.GetProcessesByName(myAppName)) { proc = proc_loopVariable; runningProcessIds.Add(proc.Id); } //start the new process Process.Start(location); //wait for the new application to be started while (!(Process.GetProcessesByName(myAppName).Count != runningProcessIds.Count)) { //timeout if we have not seen the application start if ((DateTime.Now - startTime).TotalSeconds > 30) break; } //loop through all the running processes again to find the id of the one that has just started foreach (void proc_loopVariable in Process.GetProcessesByName(myAppName)) { proc = proc_loopVariable; if (!runningProcessIds.Contains(proc.Id)) { newProcessId = proc.Id; break; } } //wait for the application to finish Process.GetProcessById(newProcessId).WaitForExit(); Debug.WriteLine("Finished"); 
+1
source

All Articles