调试利用 Vista API 中的 FileDialog 的 Visual Studio 2010 解决方案的问题
Posted
技术标签:
【中文标题】调试利用 Vista API 中的 FileDialog 的 Visual Studio 2010 解决方案的问题【英文标题】:Issue with debugging Visual Studio 2010 solution that utilises FileDialog from the Vista API 【发布时间】:2011-07-20 03:04:25 【问题描述】:我有一个 WinForms C# Visual Studio 2008 (.NET 3.5) 解决方案,该解决方案将升级到 Visual Studio 2010(.NET 保持在 3.5 版)。该解决方案利用 Vista API 中的 FileDialog 有两个原因:
-
在 Windows XP 中运行应用程序时,期望为用户提供一个 Windows XP 外观文件对话框。在 Windows Vista 和 7 中运行相同的应用程序时,文件对话框将具有 Vista 的外观。
更重要的是,我们的应用程序允许用户打开项目文件,该文件可以是本地文件(存储在用户的机器或 USB 设备上),也可以是服务器项目(托管在 MS SQL Server 中)。为此,我们使用 Vista API,因为我们可以访问文件类型下拉列表控件的事件处理程序。因此,实现方式是向用户显示打开文件对话框,当他们从文件类型下拉列表中选择“服务器”选项时,打开文件对话框关闭,并打开一个不同的对话框,允许用户选择他们希望连接的服务器和服务器项目。
在 Visual Studio 2008 中调试应用程序时,Vista API 没有问题。当解决方案升级到 Visual Studio 2010(在 Windows 7 中运行)时,用户尝试调试应用程序,并且用户希望访问 Vista API 打开文件对话框,应用程序崩溃并抛出 ArgumentException 并显示以下消息: “值不在预期范围内”。奇怪的是,当用户从 Visual Studio 2010 运行解决方案而不进行调试 (Ctrl + F5) 时,不会发生异常。 “违规”代码是:
internal void DoFolderChange(IFileDialog dialog)
IShellItem ppsi = null;
string ppszName = string.Empty;
dialog.GetFolder(out ppsi);
// Exception occurs here
ppsi.GetDisplayName(NativeMethods.SIGDN.SIGDN_FILESYSPATH, out ppszName);
OnFolderChange(ppszName);
我尝试了一些谷歌搜索,但无济于事。我有一个带有 Vista API 的示例 Visual Studio 2010 解决方案,这个问题也出现在这个解决方案中。可以从here 下载示例项目(ZIP 格式)。重现问题:
-
在 Visual Studio 2010 中调试解决方案。
“Vista Api Demo”启动后,单击“对话框”选项卡。
从位于“对话框”选项卡右侧的“Vista Look”列中,单击“打开文件”按钮。
将出现一个对话框,其中包含“文件类型已更改为 1”消息。点击确定按钮。
观察到此时应用程序崩溃了,但 clsFileDialog.cs 中的 DoFolderChange(IFileDialog) 方法抛出了异常。
对于这篇冗长的帖子,我深表歉意,但我需要解释为什么需要 Vista API 文件对话框实现的整个背景。感谢您为解决此问题提供的任何帮助,因为我的开发团队正在考虑使用 Visual Studio 2010,我们开发人员不想为了绕过此问题而摆弄附加和分离调试器。
【问题讨论】:
【参考方案1】:我遇到了这个问题,我想出了一个解决办法。
原代码:
OpenFileDialog fdlg = new OpenFileDialog();
string tempDirectoryName = @"..\SomeFolder\"; /* Note, the use of a relative directory*/
fdlg.InitialDirectory = tempDirectoryName ;
Nullable<bool> result = fdlg.ShowDialog();
然后我将其更改为:
OpenFileDialog fdlg = new OpenFileDialog();
string tempDirectoryName = @"..\SomeFolder\"; /* Note, the use of a relative directory*/
string massagedDirectoryName = System.IO.Path.**GetFullPath**(tempDirectoryName);
fdlg.InitialDirectory = massagedDirectoryName; /*Note, this is now the full folder name */
Nullable<bool> result = fdlg.ShowDialog();
它不再轰炸我了。
我的情况几乎相同。
我的场景:
代码是 VS2008 下的 WPF 应用程序并且可以工作。 (3.5 框架是目标框架) 我将代码向上转换为 VS2010(4.0 框架是目标框架)。然后出现了这个新问题。
两个代码库都在 Windows 7 x64 上运行。
.......
我的完整错误是:
Value does not fall within the expected range.
at MS.Internal.Interop.HRESULT.ThrowIfFailed(String message)
at MS.Internal.AppModel.ShellUtil.GetShellItemForPath(String path)
at Microsoft.Win32.FileDialog.PrepareVistaDialog(IFileDialog dialog)
at Microsoft.Win32.FileDialog.RunVistaDialog(IntPtr hwndOwner)
at Microsoft.Win32.CommonDialog.ShowDialog()
【讨论】:
感谢您的回复 granadaCoder。老实说,我已经有一段时间没有研究这个问题了,但是我的一位同事也找到了解决我问题的方法。虽然我还没有看到他修复的确切性质,但他发现代码中有我们没有使用的事件,所以他取消了这些事件的注册并且没有发生崩溃。当我下次有机会时,我会看看我同事的解决方案以及你的解决方案。再次感谢!以上是关于调试利用 Vista API 中的 FileDialog 的 Visual Studio 2010 解决方案的问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 Debugger.Break() 将调试器附加到 Vista 或 Windows 7 上正在运行的进程