我部署了ClickOnce Windows窗体应用程序(App A)
另一个应用程序(App B)以文件名作为参数启动App A. 我使用此代码执行此操作
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);
App A从AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0]
抓取文件名并显示内容。
这就像一个魅力。但是,现在我希望App B等待App A退出。
但是对Process.WaitForExit()
的调用会立即返回。
有没有办法打开ClickOnce App并等待它退出?如果有必要,我可以更改应用程序的运行方式,但要求是我需要将应用程序作为ClickOnce应用程序运行(我知道在我的用户配置文件AppData\Local\Apps\2.0\
文件夹中的某个地方存在exe并且可以启动直接但如果我这样做ApplicationDeployment.IsNetworkDeployed
是false
而ApplicationDeployment.CurrentDeployment
是空的。我放松了ClickOnce更新功能。
答案 0 :(得分:2)
我的建议是在App A中使用Mutex,然后让App B检查并等待它。从我的角度来看,这是最干净的方式。
App A在启动时执行此操作:
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();
}
和App B等待释放互斥锁:
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();
答案 1 :(得分:1)
问题是,启动appref-ms进程实际上并没有启动应用程序它启动部署清单,然后启动应用程序本身,因此您开始的进程会立即退出。
如果您知道名称(我假设您这样做),您可以添加一个检查以查看应用程序何时启动,如下所示:
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");