Win32程序在Windows 8上调用GetSaveFileName()或SHBrowseForFolder()时崩溃



我正在维护一个使用Win32的C++程序。多年来,它一直运行良好,但现在我在两台运行Windows 8的计算机上遇到了"选择文件"或"选择文件夹"功能问题,而在另外两台运行Windows8的计算机中却没有。

问题是,该程序在Microsoft代码深处的"选择文件"或"选择文件夹"功能中崩溃。显示对话框后,在用户有机会触摸任何东西之前,它会立即崩溃。

我做了很多实验,我让它随机工作,但重新编译相同的代码会使错误再次出现。最后,我制作了一个小程序,它连续调用该函数10次,没有任何其他代码,第一次总是成功,但第二次程序崩溃。与我的完整程序相连,它有时在第一次通话时崩溃,有时在第二次通话时。我的代码如下:

#include <windows.h>
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance,
LPSTR args, int nCmdShow)
{   
for (int i=0; i < 10; i++) {
OPENFILENAME OFN;
char buf[1024];
memset(&OFN, 0, sizeof(OFN));
OFN.lStructSize = sizeof(OFN);
OFN.hwndOwner = NULL;
OFN.hInstance = NULL;
OFN.lpstrFilter = "PTN files*.ptn";//overkill
OFN.lpstrCustomFilter = NULL;
OFN.nMaxCustFilter = 0;
OFN.nFilterIndex = 1;
OFN.nMaxFile = sizeof(buf);
OFN.lpstrFileTitle = NULL;
OFN.nMaxFileTitle = 0;
OFN.lpstrTitle = NULL;
OFN.nFileOffset = 0;
OFN.nFileExtension = 0;
OFN.lpstrDefExt = "ptn";
OFN.lCustData = 0;
OFN.lpfnHook = 0;
OFN.lpTemplateName = NULL;
OFN.lpstrInitialDir = NULL;
strcpy(buf, "");//overkill
OFN.lpstrFile = buf;
OFN.Flags = OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_EXPLORER;
//NB: tried both with and without OFN_EXPLORER
GetSaveFileName(&OFN);
}
return 0;
}

有什么想法吗?

我在您的代码中看不到任何错误。我怀疑是否有人能回答你的问题。

只是一些想法:

1.)你把你的项目编译成MBCS?Windows8还支持Ansi的东西吗?如果Unicode版本也发生同样的情况,你试过了吗?

2.)我在WindowsXP中也遇到过很多关于这些功能的问题。它们肯定是有缺陷的,而且在Windows8中它们似乎仍然存在,甚至更多。例如,我发现lpstrFile的无效值可能会导致对话框无法打开。其他参数也是至关重要的。

3.)您为_WIN32_WINNT定义了什么值?我建议至少0x0502或更高版本,以确保OPENFILENAME结构不是Windows NT时代的版本,而Windows 8可能不支持该版本。

4.)如果您尝试MFC版本:会发生什么

CFileDialog dlg(FALSE);
dlg.DoModal();

将所有参数设为默认值。如果这是有效的,你知道这不是Windows8的错误。然后研究OFN中的哪些参数与您的代码不同。还可以看看sizeof(OFN)的值,它可能会影响Windows 8的行为。

5.)可能需要您的应用程序/Dll具有Shell32的嵌入式清单才能正常工作。

#pragma comment(linker,""/manifestdependency:type='win32' processorArchitecture='X86'   name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*'"")

6.)如果所有这些都没有帮助,你必须进行实验,直到你发现是什么参数导致了问题:在Windows 8上需要hwndOwner吗?Windows 8上需要hInstance吗?有一面旗帜不见了吗?是否需要lpstrInitialDir?

7.)我不时发生非常非常奇怪的撞车事故,很难再现。经过数周令人沮丧的搜索,我终于发现这是Visual Studio中的一个错误。避免错误代码的解决方案是在Visual Studio的菜单中选择"*Re*build solution"。我只在我的一个项目中有这种效果。

我正在写David Heffernan的回答,他将其作为问题注释提供。(大卫,如果你提供一个正确的答案,我会投赞成票,并尝试删除这个)。

"试着在出现故障的机器上禁用shell扩展。有一些工具可以让你暂时禁用shell扩展,例如:nirsoft.net/utils/shexview.html这只是一种预感,shell扩展正在干扰你的程序。">

相关内容

  • 没有找到相关文章

最新更新