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

I need to display the topmostForm in front of the default Windows Installer UI. The above is sample code inside my CustomAction that I am using to create a Form. Setting the TopMost property or using ShowDialog is not helping. Is there any other solution to make my form the top most and focussed?

Syed Ali
  • 1,817
  • 2
  • 23
  • 44
Manoj Savalia
  • 1,402
  • 3
  • 13
  • 36
  • 1
    Your MessageBox shows behind the installer windows because it does not have the correct owner; and it's not easy to find your installer window. – Alexey Ivanov Jun 02 '11 at 15:14
  • 1
    You should use MSI dialog box to show error message to the user instead of calling MessageBox from your custom action. Consider WiX for creating your install package, it is more flexible. – Alexey Ivanov Jun 02 '11 at 15:16
  • @AlexeyIvanov - I have requirement to display a separate user interface during the install. This is to collect some information from the user. So for example if i try to launch a Windows Form from a CustomAction it does not get focussed. I have tried using ShowDialog, Activate, BringToFront and setting it to TopMost etc but none of these seem to get it focussed. I have also tried to focus one of the controls on the form with no success. Hope there is a solution to this. Thanks – Syed Ali Mar 30 '12 at 14:46
  • @sttaq The solution to this is to use native MSI dialog boxes rather than .Net. They're more limited and could be harder to program but getting info from the user can really be achieved with MSI-only dialogs. See (User Interface)[http://wix.tramontana.co.hu/tutorial/user-interface] section in WiX tutorial for more info. If you need a sophisticated UI, then the solution is to use [external UI](http://stackoverflow.com/questions/5624122/how-to-create-a-installer-similar-to-visual-studio-2008-setup/5625201#5625201), Look at [Burn](http://robmensching.com/blog/posts/2009/7/14/Lets-talk-about-Burn) – Alexey Ivanov Mar 30 '12 at 20:50
  • The Burn looks quite complicated for simple tasks. I have tried to use wix dialogs but they dont seem to appear on uninstall from Add/Remove programs. Now I know that it is not recommended but there could be requirements to prompt the user on uninstall for credentials etc. – Syed Ali Apr 02 '12 at 13:53
  • Hi manoj please join the Casual chat room as soon as possible... and then just miss call me i will join that soon... – Sagar Rawal May 30 '12 at 04:48
  • Hi... Kemnu chale chhe? jalsa chhe ne? – Sagar Rawal Aug 13 '12 at 06:42

10 Answers10

3

You can use form option TopMost and Focus method. But there much better way. You can get installer process, then get it window handler and then use it as parameter in ShowDialog method::

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 is something like this:

public class WindowWrapper : IWin32Window
{
  private readonly IntPtr hwnd;
  public IntPtr Handle {
    get { return hwnd; }
  }
  public WindowWrapper(IntPtr handle) {
    hwnd = handle;
  }
}
  • used your code to show MessageBox with correct owner, works just as expected, the only trick was that MainWindowTitle have "ProductName" property of setup project. Thanks! – user2932688 Dec 11 '17 at 22:41
  • Pavel - what is form? form.ShowDialog doesn't resolve form to anything - it's not defined. (from ? form.ShowDialog(...) – Ben_G Dec 13 '18 at 17:54
3

If you want to show your own UI in the installer, you won't be able to use a setup and deployment project, because it lacks the features necessary to implement that. Consider using an installer toolkit like WiX or Inno Setup instead.

Concerning the first part of your question, are you passing the custom dialog box in the owner argument to MessageBox.Show()?

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • I have already create installer but there is one problem.When i open form like frm.ShowDialog() that time form is open but it display in back side of default installer screen. i Want to show it in front of default screen. Any Idea about this??? – Manoj Savalia Jun 02 '11 at 12:49
  • Write code to force all other windows to the background or your window to the foreground this involves using P/Invoke. – Security Hound Jun 02 '11 at 13:08
2

although i'm not wuite sure what exactly you're asking for, using WiX for building windows installers is the prefered way to go. There you can build your forms and custom actions and pretty much anything else.

Mladen Prajdic
  • 15,457
  • 2
  • 43
  • 51
  • I have done installer but there is one problem.When i open form like frm.ShowDialog() that time form is open but it display in behind of default installer screen. Any Idea about this??? – Manoj Savalia Jun 02 '11 at 12:44
  • without the code you're using there's nothing we can do to help you. – Mladen Prajdic Jun 02 '11 at 14:49
  • My code is like [RunInstaller(true)] public partial class Installer1 : Installer { public Installer1() { InitializeComponent(); } private void Installer1_AfterInstall(object sender, InstallEventArgs e) { Form1 tF = new Form1(); tF.Focus(); tF.BringToFront(); tF.TopMost = true; tF.ShowDialog(); } } When i Call topmostForm.ShowDialog() that time form is shown in back side of default installer screen.I want to it front side.I think you got my idea.... Please help me.... – Manoj Savalia Jun 03 '11 at 05:03
  • 1
    edit your question and put the code in there. this way it's completely unreadable – Mladen Prajdic Jun 03 '11 at 09:43
2

If you want to have complete control over installer user interface for branding or custom dialogs and don't want to use installer builder software like InstallShield then you can create a C++ application to serve as shell for Windows Installer - there is no need to implement installer actions such as copying files by yourself.

Windows Installer has API for such purpose. With function MsiSetExternalUIRecord you can provide a callback to capture installer notifications such as messages and progress updates.

Arunas
  • 918
  • 1
  • 8
  • 20
2

Dialogs created by custom actions are always displayed behind the installation dialogs on newer Windows versions (Vista and Windows 7). This is because Windows prevents applications to move a window on top of all other windows. Think how virus popups would fill up the screen on older Windows versions.

Instead, a newly created dialog is displayed in the background and it's title bar button (if it has one) flashes.

The correct solution for what you want is creating a dialog in your MSI package and using it instead of the custom action.

Cosmin
  • 21,216
  • 5
  • 45
  • 60
2

Top most won't work. Simply make the form to be displayed in the custom action larger than the MSI installer form.

Adam Lear
  • 38,111
  • 12
  • 81
  • 101
milo
  • 21
  • 1
1

I tried the same and I can see the form. The only different I can see is you are missing base.OnAfterInstall(savedState); in your code.

And if it still doesn't show up the try putting just MessageBox to see if your installer is hooked or not with setup project

    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);
    }
1

Call this.focus() in your form.OnLoad method. That makes it show up in front of the installer. Simple fix.

Ralf Bönning
  • 14,515
  • 5
  • 49
  • 67
0

Call Minimize and Restore/show methods of the form, this fix your problem.

Saravanan
  • 41
  • 3