RestartManager 在更新期间无法重新启动应用程序
我正在使用 c#、.net 4、WIX 3.5、Windows Vista。 我通过 p/invoking RegisterApplicationRestart 方法并处理 WM_QUERYENDSESSION 和 WM_ENDSESSION 窗口消息(我返回 new IntPtr(1);)使我的应用程序与 RestartManager 兼容。
如果我尝试手动更新我的应用程序,那么一切都会按预期进行:
- 启动应用程序;
- 启动包含新应用程序版本的 msi 文件;
- 在安装/更新过程中,系统提示我关闭正在运行的应用程序;
- 继续后,正在运行的应用程序将关闭,安装完成,并且应用程序将重新启动;
如果我尝试从应用程序本身更新我的应用程序,那么我会遇到问题:
1)启动应用程序;
2)下载新的msi文件;
3) 启动 msi 文件:
using (System.Diagnostics.Process p = new System.Diagnostics.Process())
{
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "msiexec";
p.StartInfo.Arguments = "/i \"" + downloadPath + "\" /passive";
p.StartInfo.UserName = "Administrator";
p.StartInfo.Password = securePassword;
p.Start();
}
4) 因为我使用的是被动模式,所以应用程序会自动关闭;
5)安装后,我的应用程序没有重新启动,并且在事件查看器下我有一个
事件 10007 - 无法重新启动应用程序或服务“MyApp”。
我尝试过:
- 不使用 msiexec 的被动模式;
- 通过 cmd.exe 启动 msiexec (cmd.exe /C "msiexec /i ....") - 希望从另一个进程启动 msiexec 能够解决问题;
- 在启动 msi 更新之前等待 60 秒以上(在我的场景中应该不相关,但 MSDN 文档有相关内容...)
但是上述方法都不起作用(始终是相同的结果)。
必须使用提升的权限启动安装程序可能与该问题有关,因为在手动更新期间,我在事件查看器中收到警告 - 应用程序 MyApp (pid 3220) 无法重新启动 - 应用程序 SID 与 Conductor 不匹配SID。
尽管如此,重新启动应用程序仍然有效。谷歌搜索该警告没有产生好的/具体结果,只是该警告可能是由于在提升的提示符下运行 msi 引起的。
如何解决(或解决)此问题,以便我可以从应用程序本身更新我的应用程序并随后重新启动我的应用程序?
编辑 - 额外测试:
- 似乎不需要响应 WM_QUERYENDSESSION 和 WM_ENDSESSION 消息,因为手动升级期间应用程序重新启动无需它们,因此我们可以排除它们;
- 如果我没有向应用程序启动的升级提供管理员凭据,而是在升级过程中输入它们,则应用程序重新启动将起作用;
- 如果我运行提升的命令提示符并从那里启动应用程序升级(手动),则应用程序重新启动仍然有效;
- 为了使应用程序升级能够在标准用户帐户下正常工作(到目前为止,我在具有 UAC 的管理员帐户下进行了测试),我还必须设置
p.StartInfo.LoadUserProfile = true;
。否则什么也不会发生。 (应用程序重新启动仍然不起作用); - 我尝试了我可以设置的所有其他进程 StartInfo 参数-WorkingDirectory、Redirect、Verb
(= "runas") - 结果没有变化; - 我在我一直在测试的虚拟机上安装了 Vista SP2(到目前为止运行的是 SP1),但没有任何变化;
- 我使用详细日志记录执行了“自动”应用程序升级。最后出现错误消息 - RESTART MANAGER: 重新启动应用程序时失败。错误:352。该错误代码非常通用(http://msdn.microsoft.com/cs-cz/ Library/aa373665),为了获得更详细的信息,我必须编写自己的安装程序,在错误后调用RmGetList,然后我可能会得到更多细节(虽然这是我不愿意做的事情);
编辑2 - msi日志文件:
http://mommi.planet.ee/muu/log.txt
I'm using c#, .net 4, WIX 3.5, Windows Vista.
I have made my application compatible with RestartManager by p/invoking the RegisterApplicationRestart method and by handling the WM_QUERYENDSESSION and WM_ENDSESSION window messages (I return new IntPtr(1);
).
If I try to update my application manually, then everything works as it should:
- Launch application;
- Launch msi file containing new app version;
- During the installation/update, I'm prompted to close the running application;
- Upon continuing the running app is closed, install completes, and the app is restarted;
If I try to update my application from the application itself, then I run into problems:
1) Launch application;
2) Download the new msi file;
3) Launch msi file with:
using (System.Diagnostics.Process p = new System.Diagnostics.Process())
{
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "msiexec";
p.StartInfo.Arguments = "/i \"" + downloadPath + "\" /passive";
p.StartInfo.UserName = "Administrator";
p.StartInfo.Password = securePassword;
p.Start();
}
4) Because I'm using passive mode, the application is closed automatically;
5) After the installation, my application is not restarted and under Event Viewer I have an
Event 10007 - Application or service 'MyApp' could not be restarted.
I have tried:
- Not to use passive mode for msiexec;
- Launch msiexec via cmd.exe (cmd.exe /C "msiexec /i ....") - in the hopes that launching msiexec from another process would solve the problem;
- Wait for 60+ seconds before launching the msi update (shouldn't be relevant in my scenario, but MSDN documentation has something about it...)
But none of the above has worked (always the same result).
Having to launch the setup with elevated permissions might have something to do with the issue, because during the manual update I get a warning in the Event Viewer - Application MyApp (pid 3220) cannot be restarted - Application SID does not match Conductor SID.
Despite this, restarting the app still works. Googleing the warning yields no good/specific results, only that this warning is probably caused by running the msi in an elevated prompt.
How do I fix (or workaround) this issue, so that I can update my application from the application itself and restart my application afterwards?
Edit - extra testing:
- There doesn't seem to be a need to respond to WM_QUERYENDSESSION and WM_ENDSESSION messages, because application restart during a manual upgrade works without them, so we can rule them out;
- If I don't provide administrator credentials to the application initiated upgrade and instead I type them in during the upgrade, then app restarting works;
- If I run an elevated command prompt and initiate an application upgrade from there (manually), then app restarting still works;
- In order for application upgrade to work at all under Standard user accounts (so far I tested under an Administrator account with UAC), then I also have to set
p.StartInfo.LoadUserProfile = true;
. Otherwise nothing happens. (application restart still doesn't work though); - I tried all other process StartInfo parameters that I could set - WorkingDirectory, Redirect, Verb
(= "runas") - no change in results; - I installed Vista SP2 onto the virtual machine that I have been testing on (so far ran SP1), but no change;
- I performed an "automatic" application upgrade with verbose logging. In the end there was an error message - RESTART MANAGER: Failed while restarting applications. Error: 352. That error code is very generic (http://msdn.microsoft.com/cs-cz/library/aa373665), inorder to get more detailed info I would have to write my own installer that would call RmGetList after the error, then I might get more details (this though is something I'm not willing to do);
Edit 2 - msi log file:
http://mommi.planet.ee/muu/log.txt
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
假设手动过程确实没有任何问题,那么您对管理员权限的需求与“更新本身”的结合似乎导致了这些问题。我看到以下选项:
创建批处理文件来执行更新
当您想更新调用此批处理文件(具有提升的权限)时,使应用程序自行关闭...批处理文件应等待几秒钟,然后检查应用程序是否仍在运行(并在情况下关闭它),然后运行您需要运行
msiexec
的命令行 - 不要从 msiexec 中重新启动应用程序,而是在从批处理文件成功运行msiexec
后。创建一个始终用于启动应用程序的批处理文件
当需要更新时,您只需结束应用程序即可。批处理文件检查可用更新并应用它,在成功更新后启动应用程序,或者应用程序设置一些环境变量,然后由批处理文件的其余部分进行相应处理。
Assuming that the manual process indeed works without any problem it seems that your need for Administrator privileges in combination with the "updating itself" leads to these problems. I see the following options:
create a batch file to execute the update
When you want to update call this batch file (with elevated privileges), make the app close itself... the batch file should wait some seconds, then check whether the app is still running (and close it in case) and then run the commandline you need to run
msiexec
- don't restart the app from within msiexec but after a successfull run ofmsiexec
from the batch file.create a batch file which is always used to start the app
When the time comes to update you just end the app. Either the batch file check for an available update and applies it, starting the app after successfull update OR the app set some environment variable which is then accordingly processed by the rest of the batch file.