.Net中的自定义安装程序显示安装程序后面的表单

[RunInstaller(true)] public partial class Installer1 : Installer { public Installer1() { InitializeComponent(); } public override void Install(System.Collections.IDictionary stateSaver) { base.Install(stateSaver); } private void Installer1_AfterInstall(object sender, InstallEventArgs e) { Form1 topmostForm = new Form1(); topmostForm.BringToFront(); topmostForm.TopMost = true; topmostForm.ShowDialog(); } } 

我需要在默认的Windows Installer UI前面显示topmostForm。 以上是我用于创建表单的CustomAction中的示例代码。 设置TopMost属性或使用ShowDialog没有帮助。 有没有其他解决方案可以使我的表格成为最顶级和最集中的?

如果要在安装程序中显示自己的UI,则无法使用设置和部署项目,因为它缺少实现该function所需的function。 请考虑使用WiX或Inno Setup等安装工具包。

关于问题的第一部分,您是否将owner参数中的自定义对话框传递给MessageBox.Show() ?

虽然我不确定你究竟要求的是什么,但使用WiX构建Windows安装程序是首选的方法。 在那里,您可以构建表单和自定义操作以及其他任何操作。

如果您想完全控制用于品牌或自定义对话框的安装程序用户界面,并且不想使用InstallShield等安装程序构建器软件,那么您可以创建一个C ++应用程序作为Windows Installer的shell – 无需实现安装程序自己复制文件等操作。

Windows Installer具有用于此目的的API。 使用MsiSetExternalUIRecord函数,您可以提供回调以捕获安装程序通知,例如消息和进度更新。

自定义操作创建的对话框始终显示在较新的Windows版本(Vista和Windows 7)上的安装对话框后面。 这是因为Windows阻止应用程序在所有其他窗口之上移动窗口。 想想病毒弹出窗口如何填满旧版Windows上的屏幕。

相反,新创建的对话框显示在后台,它的标题栏按钮(如果有)闪烁。

您想要的正确解决方案是在MSI包中创建一个对话框,并使用它而不是自定义操作。

最重要的是不行。 只需将表单显示在大于MSI安装程序表单的自定义操作中即可。

我尝试了同样的,我可以看到表格。 我能看到的唯一不同就是你缺少base.OnAfterInstall(savedState); 在你的代码中。

如果它仍然没有显示尝试只是放置MessageBox以查看您的安装程序是否与安装项目挂钩

  protected override void OnAfterInstall(IDictionary savedState) { // message box to test MessageBox.Show("test"); Verify topmostForm = new Verify(); topmostForm.BringToFront(); topmostForm.TopMost = true; topmostForm.ShowDialog(); //this line is missing in your code base.OnAfterInstall(savedState); } 

您可以使用表单选项TopMost和Focus方法。 但还有更好的方法。 您可以获取安装程序进程,然后获取它的窗口处理程序,然后将其用作ShowDialog方法中的参数::

 var proc = Process.GetProcessesByName("msiexec").FirstOrDefault(p => p.MainWindowTitle == "Name of product"); var formResult = proc != null ? form.ShowDialog(new WindowWrapper(proc.MainWindowHandle)) : form.ShowDialog(); 

WindowWrapper是这样的:

 public class WindowWrapper : IWin32Window { private readonly IntPtr hwnd; public IntPtr Handle { get { return hwnd; } } public WindowWrapper(IntPtr handle) { hwnd = handle; } } 

调用最小化和恢复/显示表单的方法,这可以解决您的问题。

在你的form.OnLoad方法中调用this.focus() 。 这使它出现在安装程序前面。 简单的修复。