Wixsharp: Custom WixDialog with OpenFileDialog possible?

Created on 25 Sep 2017  路  4Comments  路  Source: oleg-shilo/wixsharp

For enabling my installer's users to conveniently select the service's output folder, I tried to add an OpenFileDialog button to my customized WixCLRDialog class via WinForms designer.

Unfortunately, no dialog opens, the form just freezes. Is this _per design_ (maybe due to a limitation of the used technologies), a bug or is it just me who broke something by doing it wrong?

Currently used code:

private void btnOutputPath_Click(object sender, EventArgs eventArgs)
{
  var outputFolder = new OpenFileDialog
  {
    CheckFileExists = false,
    CheckPathExists = true,
    FileName = string.Empty,
    Filter = string.Empty,
    InitialDirectory = txtOutputPath.Text
  };
  MessageBox.Show("Debug"); // Shows.
  outputFolder.ShowDialog(this); // Never opens the dialog, seems to freeze the form.
  MessageBox.Show(outputFolder.FileName); // Is never shown.
}

Commenting (read: removing) the object initializer's properties doesn't change anything.

question

All 4 comments

You cannot do this as OpenFileDialog is an ActiveX control and it cannot be used from the thread that is not initialized for hosting COM objects (e.g. [STAThread]). I guess MSI didn't initialized the UI thered correctly. :(

Below is the work around:

```C#
void button1_Click(object sender, EventArgs e)
{
ShowOpenFolder();
}

void ShowOpenFolder()
{
var t = new Thread(ThreadProc);
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
}

public static void ThreadProc()
{
var outputFolder = new OpenFileDialog
{
CheckFileExists = false,
CheckPathExists = true
};
outputFolder.ShowDialog();
}
```

@oleg-shilo, thanks for the perfect workaround and the informative explanation. 馃憤

And of course if you want it to be more elegant then:
C# string SelectFolder() { string result = null; var t = new Thread(()=> { using (var dialog = new OpenFileDialog()) { dialog.CheckFileExists = false; dialog.CheckPathExists = true; if (dialog.ShowDialog() == DialogResult.OK) result = dialog.FileName; }; }); t.SetApartmentState(ApartmentState.STA); t.Start(); t.Join(); return result; }

@oleg-shilo, once again: thanks a lot! :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marcobeninca71 picture marcobeninca71  路  4Comments

yfnfif picture yfnfif  路  3Comments

mgkeeley picture mgkeeley  路  5Comments

mattias-symphony picture mattias-symphony  路  3Comments

meytes picture meytes  路  3Comments