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

时间:2019-07-04 17:59:38

标签: c# dialog openfiledialog windows-api-code-pack

问题

我正在尝试使用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
            }
        }
    }
}

我还与作者Microsoft一起使用了以下nuget软件包:

  • Microsoft.WindowsAPICodePack-Core
  • Microsoft.WindowsAPICodePack-Shell

例外

此代码在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的文件。

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

    如果我选择“取消”,则在以后的调试过程中不会返回提示。我怀疑此丢失的文件是问题的根源,但不知道如何处理此信息。

我尝试过的东西

  1. 除了this amusing but irrelevant question之外,搜索异常并没有带来任何好处。

  2. 从多个来源安装相同的nuget软件包并没有给我任何不同的结果。这些软件包有很多副本,因为for a while Microsoft made them unavailable

  3. 我尝试在计算机上搜索文件“ CommonFileDialog.cs”,但找不到该文件。

1 个答案:

答案 0 :(得分:0)

trykyn mentioned in the comments一样,解决此问题的方法是在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?

  

STAThreadAttribute本质上是Windows消息泵与COM组件进行通信的要求。尽管核心Windows窗体不使用COM,但操作系统的许多组件(例如系统对话框)仍使用此技术。