Search code examples
.netinstallationfolderbrowserdialog

FolderBrowserDialog hangs in .Net installer project


I wrote a tool that should be called as part of a .Net installer project.

It should ask the user for a directory and then update my config.

I use the following code to show the file-chooser dlg:

{
    FolderBrowserDialog dlg = new FolderBrowserDialog();

    dlg.Description = "Trace-Verzeichnis auswählen";
    dlg.ShowNewFolderButton = true;

    if (DialogResult.OK ==  dlg.ShowDialog( this ))
    {
        tbTraceDir.Text = dlg.SelectedPath;
    }
}

If I run the tool from the command line, the FolderBrowserDialog shows OK. If it is called as part of the installer package, from the installer class, it hangs indefinitely at ShowDialog()

Edit: Same behaviour when I run it form VStudio or from the command line. I am running .Net 4 (not the client profile).

Any hints what I might be doing wrong?


Solution

  • Seems I missed the boat on this one, but I was looking for something similar and found an excellent answer that actually works, and I'll explain why as well. You should add a new custom action to your installer project. Then, all you would need to do is:

    [CustomAction]
    public static ActionResult SpawnBrowseFolderDialog(Session session)
    {
        Thread worker = new Thread(() =>
        {
            FolderBrowserDialog dialog = new FolderBrowserDialog();
            dialog.SelectedPath = session["INSTALLFOLDER"];
            DialogResult result = dialog.ShowDialog();
            session["INSTALLFOLDER"] = dialog.SelectedPath;
        });
        worker.SetApartmentState(ApartmentState.STA);
        worker.Start();
        worker.Join();
        return ActionResult.Success;
    }
    

    Or, you can just do anything you want inside of the new thread...really, the reason why this works is because you need to allocate a new thread which must have an STA apartment state. UI components in Windows generally need to be run in a single threaded (STA) apartment state because this enforces proper concurrency on the UI component since just one thread is allowed to modify the UI at a time.