Exception when using FolderBrowserDialog

雨燕双飞 提交于 2019-12-02 19:05:36

A thread is either STA or MTA it can't be specified just for one method so the attribute must be present on the entry point.

From STAThreadAttribute in MSDN :

Apply this attribute to the entry point method (the Main() method in C# and Visual Basic). It has no effect on other methods.

If this code is called from a secondary thread you have 3 choices :

IMPORTANT NOTE: Running (as you seem to do) System.Windows.Forms code inside an MTA thread is unwise, some functionalities like file open dialogs (not only folder) require a MTA thread to work.

Changing your secondary thread apartment

If you create the thread yourself (and don't use the specificity of MTA) you could just change it's apartment before starting it :

var t = new Thread(...);
t.SetApartmentState(ApartmentState.STA);

 

Creating a thread just for it

If you don't control the thread creation you could do it in a temporary thread :

string selectedPath;
var t = new Thread((ThreadStart)(() => {
    FolderBrowserDialog fbd = new FolderBrowserDialog();
    fbd.RootFolder = System.Environment.SpecialFolder.MyComputer;
    fbd.ShowNewFolderButton = true;
    if (fbd.ShowDialog() == DialogResult.Cancel)
        return;

    selectedPath = fbd.SelectedPath;
}));

t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
Console.WriteLine(selectedPath);

 

Invoking in another(STA) thread

If your main thread also contain System.Windows.Forms code you could invoke in it's message loop to execute your code :

string selectedPath = null;
Form f = // Some other form created on an STA thread;
f.Invoke(((Action)(() => {
    FolderBrowserDialog fbd = new FolderBrowserDialog();
    fbd.RootFolder = System.Environment.SpecialFolder.MyComputer;
    fbd.ShowNewFolderButton = true;
    if (fbd.ShowDialog() == DialogResult.Cancel)
        return;

    selectedPath = fbd.SelectedPath;
})), null);
Console.WriteLine(selectedPath);

The STAThread attribute must be in front of main as far as i know.

Eric Mariacher

This fixed my issue. [STAThread] static void Main()

Just an extra question: why can't microsoft make things simple? Are they trying to disgust people to do some coding?

Shankar K Arun

As simple as the below :

using System.Windows.Forms;
namespace fileConverterBaset64
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)

Add the command [STAThread] before your main method. That's it, it would work.

Now, check all dll in Reference and delete dll not use.

That was unbelievable. I could have never imagined those dll's are causing this problem.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!