的 问题 强> :先问一些问题。
的 重启经理 强> 你熟悉吗? 该 的 重启经理 强> MSI的特色 ?旨在帮助关闭和重新启动 应用程序无需重新启动。我会快点给它 撇去?我认为这是你真正的解决方案吗?
的 ARP Applet与MSI对话 强> :The 的 ARPNOREPAIR property 强> 在MSI中设置 - 在属性表中。它只影响Windows中的内容 的 Add / Remove Programs 强> 小程序( 的 ARP = Add / Remove Programs 强> ),而不是通过命令行调用MSI时看到的内容。 的 然后你会看到MSI本身定义的对话框 强> (可以改变 - 不是完全无关紧要的)。
ARPNOREPAIR property
Add / Remove Programs
ARP = Add / Remove Programs
的 ARP /添加删除程序小程序 强> :快速浏览下面这个小程序:
appwiz.cpl
Add /Remove Programs Applet
在列表中选择不同的包条目以查看不同的设置 的 ARPNOREPAIR 强> , 的 ARPNOMODIFY 强> 等等......
ARPNOREPAIR
ARPNOMODIFY
Repair entry
Change entry
ARPNOREMOVE
Remove entry
ARPSYSTEMCOMPONENT property
的 链接 强> :
所以,有一个“丑陋的黑客”解决了确切的问题:
首先 - 我们需要一个不受安装程序影响的可执行文件。这个很简单,我们只需将一个安装的exe复制到一个 TEMP 目录并从那里运行它。
TEMP
下一步是该文件必须等待卸载阶段完成。有几种方法可以做到这一点。您可以观察安装程序进程,如果删除了主程序文件,则可以观察文件系统。考虑到常见安装程序操作的速度,每秒轮询一次是一个足够好的选择。
下一步是可选的 - 删除由应用程序,空目录等创建的剩余文件。
下一步是重启, MessageBox.Show() 从 PresentationFramework 可以问用户,当用户回答OK或YES时,我可以通过多种方式重启自己 ExitWindowsEx() 从 user32.dll 因为它可能是什么 msiexec 内部呼叫。
MessageBox.Show()
PresentationFramework
ExitWindowsEx()
user32.dll
msiexec
这是示例代码:
if (MessageBox.Show(RestartPromptMsg, "", MessageBoxButton.OKCancel, MessageBoxImage.Exclamation) == MessageBoxResult.OK) { NativeMethods.ExitWindowsEx( NativeMethods.Flags.Reboot, NativeMethods.Reason.MajorApplication | NativeMethods.Reason.MinorInstallation | NativeMethods.Reason.FlagPlanned ); }
当然,一些参数可以传递给我们的特殊清理可执行文件,因此它可以做一些额外的事情,比如跳过重启提示,如果不是真的需要它。
最后一步是删除我们的可执行文件。这很容易,但它很棘手。我再次希望我的示例代码可以提供帮助:
var cleanUpTempPath = Path.Combine(Path.GetTempPath(), CleanUpExe); File.Copy(CleanUpPath, cleanUpTempPath, overwrite: true); Process.Start(new ProcessStartInfo { FileName = "cmd", Arguments = $"/c (\"{cleanUpTempPath}\" -purge \"{InstallerDir}\") & (del \"{cleanUpTempPath}\")", UseShellExecute = false, CreateNoWindow = true });
我们用 cmd.exe 特色,力量 & 和 () 。命令用。分隔 & 在上一个命令退出时执行。因此,当我们的clen up exe完成时,它会被删除 cmd 叫它的实例。记得引用所有路径,它们可以包含空格。请记住在括号中包含带参数的命令,否则请使用括号 & 运算符将被视为前一个命令的参数,而不是 cmd.exe 。
cmd.exe
&
()
cmd
我在我的大型制作应用程序中进行了测试,它起到了魅力。代码示例在粘贴时不起作用,如果您正在寻找完整的代码,只需google for it,在pinvoke.net和StackOverflow上有很多有用的示例。