为什么在控制台应用程序中使用 CommonOpenFileDialog 时会出现此异常?

Why am I getting this exception when using CommonOpenFileDialog in a Console Application?

问题

我正在尝试使用 CommonOpenFileDialog 的文件夹选择器,如 this answer 中所述。问题是,即使是一个非常精简的示例项目,我在尝试使用 CommonOpenFileDialog 的 ShowDialog() 函数时也会遇到异常。

代码

using Microsoft.WindowsAPICodePack.Dialogs;

namespace DialogTest
{
    class Program
    {
        public static void Main(string[] args)
        {
            CommonOpenFileDialog dialog = new CommonOpenFileDialog();
            dialog.InitialDirectory = "C:\Users";
            dialog.IsFolderPicker = true;

            CommonFileDialogResult result = dialog.ShowDialog();

            if (result == CommonFileDialogResult.Ok)
            {
                //Do Stuff
            }
        }
    }
}

我还使用了以下 nuget 包,作者 Microsoft:

异常

此代码在 dialog.ShowDialog(); 处产生以下异常:

System.Runtime.InteropServices.COMException was unhandled
  ErrorCode=-2147023116
  HResult=-2147023116
  Message=A null reference pointer was passed to the stub. (Exception from HRESULT: 0x800706F4)
  Source=Microsoft.WindowsAPICodePack.Shell
  StackTrace:
       at Microsoft.WindowsAPICodePack.Dialogs.IFileDialog.SetFileName(String pszName)
       at Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialog.ApplyNativeSettings(IFileDialog dialog) in c:\projects\Windows API Code Pack 1.1\source\WindowsAPICodePack-NuGet\Shell\CommonFileDialogs\CommonFileDialog.cs:line 768
       at Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialog.ShowDialog() in c:\projects\Windows API Code Pack 1.1\source\WindowsAPICodePack-NuGet\Shell\CommonFileDialogs\CommonFileDialog.cs:line 609
       at DialogTest.Program.Main(String[] args) in c:\users\obscerno\documents\visual studio 2015\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 13
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

其他一些相关细节

  1. 我正在使用 Visual Studio 2015.
  2. 这个错误的一个奇怪之处在于这段代码在一年前就可以工作了。我刚刚重新打开项目计划进行一些小改动,但它不再运行了。
  3. 在创建新测试项目时,第一个 运行 Visual Studio 提示我找到一个名为 CommonFileDialog.cs.[=18= 的文件]

    它检查文件的初始目录是 "c:\projects\Windows API Code Pack 1.1\source\WindowsAPICodePack-NuGet\Shell\CommonFileDialogs\CommonFileDialog.cs",它在我的计算机上不存在。

    如果我 select "cancel" 提示在以后的调试中不会 return。我怀疑这个丢失的文件是问题的根源,但不知道如何处理这些信息。

我试过的

  1. 除了 this amusing but irrelevant question.

  2. 之外,搜索异常并没有发现任何东西
  3. 从多个来源安装相同的 nuget 包并没有给我任何不同的结果。因为for a while Microsoft made them unavailable.

  4. 所以包的份数不少
  5. 我尝试在我的计算机中搜索文件 "CommonFileDialog.cs",但无处可寻。

,解决这个问题的方法是在Main前面加上[STAThread]

工作代码如下所示。请注意,它需要调用 System.

using System;
using Microsoft.WindowsAPICodePack.Dialogs;

namespace DialogTest
{
    class Program
    {
        [STAThread]
        public static void Main(string[] args)
        {
            CommonOpenFileDialog dialog = new CommonOpenFileDialog();
            dialog.InitialDirectory = "C:\Users";
            dialog.IsFolderPicker = true;

            CommonFileDialogResult result = dialog.ShowDialog();

            if (result == CommonFileDialogResult.Ok)
            {
                //Do Stuff
            }
        }
    }
}

有关 STAThread 是什么的更多信息,此答案详细介绍了它:What does [STAThread] do?

The STAThreadAttribute is essentially a requirement for the Windows message pump to communicate with COM components. Although core Windows Forms does not use COM, many components of the OS such as system dialogs do use this technology.