我正在维护一个使用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;
}
有什么想法吗?
答案 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扩展正在拧紧你的计划。“