2

Since I need to format "pretty" XML using MSXML, I am using the trick referenced here to add indentation to my code. Since all I want is to save a file, I open an IStream using SHCreateStreamOnFile(). The file gets saved, I can open it in a text editor and the XML content is there. Then I call Release() on the IStream interface so that the IStream and the file handle get closed.

Or so I tought, however Process Explorer tell me that my process still has a reference to my file once my save function exits (despite the release). I tried calling Release() a second time, but still no result, the handle doesn't get closed. All Google and MSDN could tell me was that I should call Release... But it isn't clear if Release() releases only the COM object or the file handle also.

So, is there a special way to force the close of a file handle created by SHCreateStreamOnFile()? Or is there a better way to obtain an IStream on a file? Do I need to call Release() on the IMXWriter, ISAXXMLReader and IStream in a specific order?

Thank you in advance.

Community
  • 1
  • 1
Laurent Bourgault-Roy
  • 2,774
  • 1
  • 30
  • 36
  • 1
    What all are you doing with that `IStream`? You must be passing it to something that holds on to it for a while.... – ildjarn May 31 '11 at 22:14
  • Check this http://social.msdn.microsoft.com/Forums/en/vcmfcatl/thread/8863657f-b4b2-4491-b667-26df4897e134 - related to your problem - using of smart pointers, and not releasing additional reader object – malkia May 31 '11 at 23:56
  • Hum, I am not using the CComPtr class, but I do however use a custom one. I'll check that out. Also, SHCreateStreamOnFile() use an "out" parameter, instead of a return value like in the blog post you mentionned. And I did tried to Release the pointer 2 times... – Laurent Bourgault-Roy Jun 01 '11 at 13:57

2 Answers2

1

ildjarn was right, I was passing it to an object that didn't get deleted, because I didn't knew that QueryInterface incremented the reference count ( I tought it was kind of a "COM" way of casting a pointer ). Releasing that object released the file at the same time.

A beginner mistake from someone not used to COM programming.

Laurent Bourgault-Roy
  • 2,774
  • 1
  • 30
  • 36
0

I met this problem before:

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);

You must wait execution on the destructor of pXMLDoc and spStream.Release(); , the handle on the file will be closed.

RickeyShao
  • 65
  • 1
  • 1
  • 7