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

时间:2014-03-05 09:28:33

标签: c++ winapi windows-8

我正在维护一个使用Win32的C ++程序。它已经运行了好几年了,但是现在我在运行Windows 8的两台计算机上的“选择文件”或“选择文件夹”功能出现问题,而在其他两台运行Windows 8的计算机上却没有。

问题是程序在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\0*.ptn\0\0\0";//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, "\0");//overkill
    OFN.lpstrFile = buf;
    OFN.Flags = OFN_LONGNAMES | OFN_HIDEREADONLY | OFN_EXPLORER;
    //NB: tried both with and without OFN_EXPLORER
    GetSaveFileName(&OFN);
}
return 0;
}

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

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

只是一些想法:

1)。 您将项目编译为MBCS? Windows 8是否仍然支持Ansi的东西? 您是否尝试过使用Unicode版本?

2)。 我在Windows XP中已经遇到过很多关于这些功能的麻烦。 它们肯定是错误的,似乎在Windows 8中它们仍然是甚至更多。我发现例如lpstrFile的无效值可能导致对话框无法打开。其他参数也很关键。

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

4)。 如果你试用MFC版本会发生什么:

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

让所有参数都保持默认值。如果这有效,您就会知道它不是Windows 8错误。然后从代码中研究OFN中哪些参数不同。另请查看可能影响Windows 8行为的sizeof(OFN)的值。

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中的一个错误。避免代码崩溃的解决方案是选择&#34; * Re * build Solution&#34;在Visual Studio的菜单中。我只在我的一个项目中有这个效果。

答案 1 :(得分:0)

我正在写David Heffernan的答案,他提供了一个问题评论。 (大卫,如果你提供了正确的答案,我会投票并尝试删除这个答案)。

“尝试在失败的机器上禁用shell扩展。有一些工具允许你暂时禁用shell扩展。例如:nirsoft.net/utils/shexview.html这只是一个预感,一个shell扩展正在拧紧你的计划。“