[C#] Custom Installer in .Net zeigt das Formular hinter dem Installer an


Answers

Obwohl ich nicht sicher bin, was genau Sie fragen, ist die Verwendung von WiX zum Erstellen von Windows-Installern der bevorzugte Weg. Dort können Sie Ihre Formulare und benutzerdefinierten Aktionen und so ziemlich alles andere erstellen.

Question
[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();
  } }

Ich muss das TopmostForm vor der Windows Installer-Standardbenutzeroberfläche anzeigen. Das obige Beispiel ist Beispielcode in meiner CustomAction, die ich zum Erstellen eines Formulars verwende. Das Festlegen der TopMost-Eigenschaft oder das Verwenden von ShowDialog ist nicht hilfreich. Gibt es eine andere Lösung, um meine Form am besten und fokussiert zu machen?







Dialoge, die mit benutzerdefinierten Aktionen erstellt wurden, werden bei neueren Windows-Versionen (Vista und Windows 7) immer hinter den Installationsdialogen angezeigt. Dies liegt daran, dass Windows verhindert, dass Anwendungen ein Fenster über alle anderen Fenster verschieben. Denken Sie daran, wie Virus-Popups den Bildschirm bei älteren Windows-Versionen füllen würden.

Stattdessen wird ein neu erstellter Dialog im Hintergrund angezeigt und die Titelleistenschaltfläche (falls vorhanden) blinkt.

Die richtige Lösung für das, was Sie möchten, besteht darin, einen Dialog in Ihrem MSI-Paket zu erstellen und ihn anstelle der benutzerdefinierten Aktion zu verwenden.




Call Minimize und Restore / show Methoden des Formulars, das behebt Ihr Problem.




Sie können die Formularoption TopMost und die Focus-Methode verwenden. Aber es gibt viel besseren Weg. Sie können den Installer-Prozess aufrufen, dann den Fenster-Handler holen und ihn dann als Parameter in der ShowDialog-Methode verwenden:

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 ist etwa so:

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