Question

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?

thanks

Mario

Was it helpful?

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.

OTHER TIPS

The issue is the custom action waits (infinitely) for user input, but its runs under SYSTEM account.

Custom action that needs UI access, must be scheduled to the UI sequence with Immediate execute which impersonates the user account.

WiX example:

<CustomAction Id='FooAction' 
              BinaryKey='FooBinary' 
              DllEntry='FooEntryPoint' 
              Execute='immediate'
              Return='check'/>

<Binary Id='FooBinary' SourceFile='foo.dll'/>

<InstallUISequence>
  <Custom Action='FooAction' After='AppSearch'></Custom>
</InstallUISequence>

I had a similar issue today. I had the following code:

using System;
using System.Windows.Forms;

class dummy{

    public static void Main() {
        FolderBrowserDialog f = new FolderBrowserDialog();
        f.SelectedPath = System.Environment.CurrentDirectory;
        f.Description= "Select a folder, for great justice.";
        f.ShowNewFolderButton = true;
        if(f.ShowDialog() == DialogResult.OK) {
            Console.Write(f.SelectedPath);
        }
    }
}

Looks fine, right? It compiled and linked with no errors, but the resulting executable just hangs without ever displaying a folder chooser.

What fixed it for me was to add [STAThread] before Main().

using System;
using System.Windows.Forms;

class dummy{
    [STAThread]
    public static void Main() {
        FolderBrowserDialog f = new FolderBrowserDialog();
        f.SelectedPath = System.Environment.CurrentDirectory;
        f.Description= "Select a folder, for great justice.";
        f.ShowNewFolderButton = true;
        if(f.ShowDialog() == DialogResult.OK) {
            Console.Write(f.SelectedPath);
        }
    }
}

And now the folder browser window renders properly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top