【问题标题】:How to close a file handle opened with SHCreateStreamOnFile如何关闭使用 SHCreateStreamOnFile 打开的文件句柄
【发布时间】:2011-09-05 20:23:10
【问题描述】:

因为我需要使用 MSXML 格式化“漂亮”的 XML,所以我使用 trick referenced here 为我的代码添加缩进。因为我只想保存一个文件,所以我使用SHCreateStreamOnFile() 打开一个IStream。文件被保存,我可以在文本编辑器中打开它,XML 内容就在那里。然后我在IStream 接口上调用Release(),这样IStream 和文件句柄就会关闭。

我还是这么说,但是 Process Explorer 告诉我,一旦我的保存功能退出(尽管已发布),我的进程仍然引用我的文件。我尝试第二次调用Release(),但仍然没有结果,句柄没有关闭。 Google 和 MSDN 能告诉我的只是我应该调用 Release... 但不清楚 Release() 是否只释放 COM 对象或文件句柄。

那么,有没有一种特殊的方法可以强制关闭SHCreateStreamOnFile() 创建的文件句柄?还是有更好的方法来获取文件上的IStream?我需要按特定顺序拨打IMXWriterISAXXMLReaderIStream 上的Release() 吗?

提前谢谢你。

【问题讨论】:

  • 你在用IStream 做什么?您必须将它传递给可以保留一段时间的东西....
  • 检查这个social.msdn.microsoft.com/Forums/en/vcmfcatl/thread/… - 与您的问题有关 - 使用智能指针,而不是释放额外的阅读器对象
  • 嗯,我没有使用 CComPtr 类,但我确实使用了自定义类。我会检查一下。此外, SHCreateStreamOnFile() 使用“out”参数,而不是您提到的博客文章中的返回值。而且我确实尝试过两次释放指针...

标签: c++ windows com


【解决方案1】:

ildjarn 是对的,我将它传递给一个没有被删除的对象,因为我不知道 QueryInterface 增加了引用计数(我认为这是一种“COM”投射指针的方式) .释放该对象的同时释放了文件。

一个不习惯 COM 编程的初学者犯的错误。

【讨论】:

  • 对 COM 使用 ATL。 CComPtr 和 CComQIPtr 可以帮助您避免很多头痛。
  • 谢谢,我去看看那些课!
【解决方案2】:

我之前遇到过这个问题:

CComPtr<IStream> spStream;
HRESULT hr = SHCreateStreamOnFileEx(L"my.xml",
    STGM_READWRITE | STGM_SHARE_DENY_WRITE | STGM_FAILIFTHERE,
    FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_HIDDEN,
    TRUE, NULL, &spStream);

SOMSXML::IXMLDOMDocumentPtr pXMLDoc;
hr = pXMLDoc.CreateInstance(__uuidof(SOMSXML::DOMDocument));
pXMLDoc->async = false;
hr = pXMLDoc->load(spStream.p);

您必须等待 pXMLDoc 和 spStream.Release() 的析构函数执行; , 文件的句柄将被关闭。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 2016-09-24
    相关资源
    最近更新 更多