0

我一直在与这个问题作斗争一天半,但找不到答案。我已将代码简化为用于打开保存对话框的简单代码:

CFileDialog dlg( FALSE, _T("xml"), _T("zzz.xml"), 
    OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR,
        _T("XML Files|*.xml||"), this);

dlg.m_ofn.lpstrInitialDir = ... a string for the initial directory
dlg.DoModal();

CFileDialog 类(也直接使用 GetSaveFileName 验证)保留了所选目录的句柄,但显然仅在 Windows XP(这是我们的部署平台)下。这可以防止在应用程序仍在运行时重命名目录。

在任何人开始谈论 CFileDialog 设置当前目录之前,我知道这一点并且我知道 OFN_NOCHANGEDIR。这不是那个问题。

在循环中运行此代码会导致保留越来越多的句柄,这可以使用 Process Explorer 进行验证,以查看应用程序具有指向该目录的句柄。重复运行对话框会导致额外的句柄,但并非总是如此。如果我每次都更改名称,那么似乎每次都会添加一个新名称,尽管并非 100% 始终如一。

每次我认为我有一些可以解决它的东西时,它都不会成功。像文件对话框这样的基本东西怎么会被破坏?

我不知道还能做什么。这是在我们即将发布新版本之前发现的一个问题。

4

2 回答 2

2

鉴于 MFC 的 CFileDialog 以及底层的 Windows API 已经存在了很长时间,我的第一反应是怀疑它们是否存在明显泄漏句柄的错误。所以我猜你看到的问题来自其他地方。

关于文件对话框的一件事是它加载了外壳扩展。例如,您将在 Windows 资源管理器中看到的各种第三方右键单击功能也将在您在自己的程序中调用的文件对话框中可用。如果外壳扩展表现良好,那没关系,但有些不是。因此,您测试过的系统有可能安装了编写不佳的 shell 扩展,最终在文件对话框使用时导致句柄泄漏。

我以前见过文件对话框加载的这些额外组件导致软件的其他部分出现问题的情况,但仅限于某些人的计算机,因为并非每个人都安装了相同的东西。

当然,我没有足够的信息说这实际上是你的问题。我只能提供这个想法并建议您尝试在不同的 Windows XP 计算机上测试这个问题,这些计算机的设置不同。在安装其他任何东西之前,您也可以尝试在全新安装的 Windows XP 上对其进行测试。如果问题没有出现在某些计算机上,那么这很好地表明某些第三方组件是问题所在。

于 2012-09-22T01:23:15.427 回答
0

我发现了罪魁祸首。有问题的应用程序编写得不是很好,并且经常在主 UI 线程上执行长时间运行的任务。还有其他代码在控制物理设备的同一台机器上运行。其他代码遇到的问题之一是它被相关应用程序阻止,导致它停止。不幸的是,他们不得不关闭超线程来解决另一个问题,这将允许两者共存。

因此,为了让两个应用程序共存并让机器控制程序优先于该应用程序,应用程序的线程优先级被降低到最低优先级。

事实证明,线程优先级的降低是导致它的原因。所以要把另一个创可贴放在创可贴的上面,放在创可贴的上面。我将创建一个 CFileDialog 子类,该子类为文件对话框提高线程优先级,并在它返回时将其降低。

于 2012-09-24T19:45:08.423 回答