#Google Analytic Tracker


Apr 8, 2008

Process cannot access the file! Please close your XmlReader!

At work, we have many scripts and utility programs to aid us in testing and developing our product.

After upgraded to VS 2008, I notice that one of utilities that I run regularly no longer working.

Here is the error that I got:

The process cannot access the file 'c:\xxx\yyy.xml' because it is being used by another process.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, Fil
eOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
   at System.Xml.XmlDocument.Save(String filename)
   at GenRes.GenRes.Main(String[] args) in C:\xxx\GenRes.cs:line 191

I asked all my colleges, and they don't have any problem running this utility.

Struggling with the fact why my computer doesn't run the utility properly, I start debugging line by line in VS.

Looking into the GenRes.cs file, it is what it tries to do.

// Load Data to XmlDocument
XmlDocument xmlStringsdoc = new XmlDocument();
xmlStringsdoc.Load(XmlReader.Create(args[0] + ".xml", settings));
// Save Data back to the xml file
xmlStringsdoc.Save(args[0] + ".xml");

Strangely, when I run the utility in the debugger, I don't get any error.

Not really sure why (which I hope I eventually find out), I decided to see if I can fix the code so that it will work on my machine, and hopefully it will works on others too.

By analyzing the code, most likely I get this error because XmlReader isn't close when xmlStringdoc try to save the data.

Looking into the revision of the file. I notice that one of my college changed the following:

//FROM xmlStringsdoc.Load(args[0] + ".xml"); // TO
settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
xmlStringsdoc.Load(XmlReader.Create(args[0] + ".xml", settings));

It turns out that we don't want to prohibit DTD when process the file.

Here is the simple fix

   1: XmlReader l_oXmlReader = XmlReader.Create(args[0] + ".xml", settings);
   2: xmlStringsdoc.Load(l_oXmlReader);
   3: // Close the reader since it is no longer needed
   4: l_oXmlReader.Close(); 

All I have done is CLOSE the reader! After testing the code, it works.

Here is the reminding questions I want to know:

  1. Does XmlDocument.Load(string) automatically close the file?
  2. Why this issue only happen on my machine and not others, is there some kind of  windows or .net framework setting?
  3. How can you write a unit test to ensure this utility work on all developers machine?
  4. How come I don't get an error when running the code in Debugger?
  5. Why does the error message say the file is being used by another process (but in fact, it is the same process that accessing it)?

Hopefully I can answer this question in the future.

No comments: