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

标签 c++ winapi windows-8

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

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

我做了很多实验,我让它随机工作,但是重新编译相同的代码会使错误再次出现。最后我制作了一个小程序,连续调用该函数 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;
}

有什么想法吗?

最佳答案

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

只是一些想法:

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 具有嵌入式 list ,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”。我只在我的一个项目中有这种效果。

关于c++ - Win32 程序在调用 GetSaveFileName() 或 SHBrowseForFolder() 时在 Windows 8 上崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22193583/

相关文章:

c++ - 哪个 DLL 有 PathCchAppend?

javascript - 在 Windows 8 和 Windows Phone 8 上使用 F# 可移植库和 HTML5/Javascript

c# - Windows 8 上 App.Config 的路径访问被拒绝。如何更新 App.Config?

c++ - 如何在 Windows 控制台中禁用用户选择

c++ - 如何检查按钮是否被按下

c# - 如何使应用程序适应 Windows 8 中的多种分辨率

c++ - 真的有 Flex++ 扫描仪吗?

c++ - 摆脱警告消息 - 正确的方法

c++ - 是否可以从 C++ 创建 Qml 组件?

c++ - 如果有更多重复键,则快速排序算法改进