Windows shell32.dll:GetOpenFileName新建线程期间发生访问冲突

Windows shell32.dll:GetOpenFileName新建线程期间发生访问冲突,windows,shell32,getopenfilename,createthread,Windows,Shell32,Getopenfilename,Createthread,GetOpenFileName因访问冲突而失败。文件必须位于桌面上并且具有长名称。 只有在首次成功打开文件后,问题才会出现。当鼠标光标悬停在文件上,工具提示即将显示时,出现问题 见下面的答案。我将原始问题描述留在下面 迈克D ======================= 我正在使用GetOpenFileName。我有时会在shell32的深处遇到访问冲突。第一次使用此代码时不会发生违规,通常需要五到六次尝试。此外,如果在弹出“打开文件”窗口后的一两秒钟内选择了一个文件,则不会发生冲突。此外,调

GetOpenFileName因访问冲突而失败。文件必须位于桌面上并且具有长名称。 只有在首次成功打开文件后,问题才会出现。当鼠标光标悬停在文件上,工具提示即将显示时,出现问题

见下面的答案。我将原始问题描述留在下面

迈克D

=======================

我正在使用GetOpenFileName。我有时会在shell32的深处遇到访问冲突。第一次使用此代码时不会发生违规,通常需要五到六次尝试。此外,如果在弹出“打开文件”窗口后的一两秒钟内选择了一个文件,则不会发生冲突。此外,调试时显示的调用堆栈不包括我的任何代码。就好像某个独立线程正在醒来做某事

非常感谢您对我如何调试此文件的任何见解

我制作了一个“你好”世界应用程序,展示了同样的行为。然而,它需要更多的尝试才能失败。似乎还必须在失败之前切换目录

GOFN是从一个为此目的而创建的线程中完成的。下面是“hello world”应用程序的代码

当它失败时,调用堆栈如下所示

SHELL32! 7ca4e035()
SHELL32! 7cb2dc16()
SHELL32! 7cb2dd5a()
SHELL32! 7cb27361()
SHELL32! 7c9f40a3()
BROWSEUI! 75f81b9a()
SHLWAPI! 77f69548()
NTDLL! 7c927545()
NTDLL! 7c927583()
NTDLL! 7c927645()
NTDLL! 7c92761c()
KERNEL32! 7c80b50b()
对不起,我不能得到这些符号,因为我有一个旧的VisualC++:-(

) 在我看来,当GOFN东西即将打开描述文件的弹出窗口时,问题就出现了,因为鼠标光标悬停在文件名上

导致问题的一系列情况有些奇怪。实验表明,必须在GOFN窗口中执行以下操作:

  • 在桌面上打开一个文件
  • 将鼠标悬停在长文件名上
如果我这样做两次,它总是失败

IMCLOG_20120323_1658_-_20120324_0653_CST_+DST_E2_2_second.TXT


我用记事本做了同样的尝试,但出现了同样的问题!

我发现了许多关于同样问题的报告。例如:



还有一个Google缓存的链接指向一个自删除MS Connect错误报告。正如您所发现的,这个问题似乎是桌面上的文件特有的

我找到的唯一建议解决方案是在线程开始时调用
CoInitializeEx(NULL)
,然后在线程结束时调用
CoUninitialize()
,因此值得一试

此外,
GetOpenFileName()
的MSDN文档中还说明:

从Windows Vista开始,“打开”和“另存为公用”对话框已被“公用项”对话框取代


因此,完全放弃
GetOpenFileName()
可能是值得的。

如果没有符号,这是没有用的。如果您使用的是Visual Studio,您应该能够通过右键单击堆栈并选择“从Microsoft符号服务器加载符号”来获取符号。我会非常仔细地检查您传入的OPENFILENAME结构。特别是与筛选器相关的字段,因为该筛选器可以被函数记住并在将来重复使用。筛选器设置如下char filter[32]=“Text Files\0*.TXT;\0\0”;嘿,你删除了堆栈跟踪。请用符号包含堆栈跟踪。即使这不是问题的答案,这将是有价值的间接知识。+1我希望如此,这太难发表评论了。我没有CoInitializeX,但确实有CoInitialize。我发现了许多文章建议使用#define _WIN32 _DCOM,但这确实为我定义了coinitializex。我尝试添加CoInitialize,但问题仍然存在。感谢您的回答,至少我知道问题不是我造成的。:-)好的,感谢您接受-
CoInitialize()
很好,只是在以后的SDK中不推荐使用,但它做了同样的事情。您必须在调用
GetOpenFileName()
(如果您没有调用)的线程中调用它。我确实从新线程调用它,并检查它是否返回了S_uOK。没有快乐。
SHELL32! 7ca4e035()
SHELL32! 7cb2dc16()
SHELL32! 7cb2dd5a()
SHELL32! 7cb27361()
SHELL32! 7c9f40a3()
BROWSEUI! 75f81b9a()
SHLWAPI! 77f69548()
NTDLL! 7c927545()
NTDLL! 7c927583()
NTDLL! 7c927645()
NTDLL! 7c92761c()
KERNEL32! 7c80b50b()