Search code examples
c#xmlxelement

C# - Cannot access the file "X" because it is used by another process


if (!File.Exists(signatureFile))
        {

            XElement signature;

            try
            {

                XNamespace ns = "http://www.w3.org/2000/09/xmldsig#";

                signature = new XElement("DocumentSignature", new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"), new XAttribute(XNamespace.Xmlns + "xsd", "http://www.w3.org/2001/XMLSchema"),
                new XElement("Files", new XAttribute("id", "files"),
                        new XElement("File", new XAttribute("file_name", file), new XAttribute("digestmethod", "http://www.w3.org/2000/09/xmldsig#sha1"), new XAttribute("archive_path", "data/" + file), "/E06svX3vAnvYnnGlMT9auuh8uE=")),
                    //new XElement("File", new XAttribute("file_name", file), new XAttribute("digestmethod", "http://www.w3.org/2000/09/xmldsig#sha1"), new XAttribute("archive_path", "data/"  + file), "x5kx5oXhxZ/lLGZ0iLTFLL3XVig=")),
                    new XElement("Attributes",
                        new XElement("Attribute", new XAttribute("id", "ad_ret_policy"), new XAttribute("system_attribute", "false"), new XAttribute("readonly", "false"),
                            new XElement("Value", metadata["Retention Policy"])),
                        new XElement("Attribute", new XAttribute("id", "ad_keepyears"), new XAttribute("system_attribute", "false"), new XAttribute("readonly", "false"),
                            new XElement("Value", metadata["Keep years"])),
                        new XElement("Attribute", new XAttribute("id", "ad_classification"), new XAttribute("system_attribute", "false"), new XAttribute("readonly", "false"),
                            new XElement("Value", metadata["Classification plan"])),
                        new XElement("Attribute", new XAttribute("id", "ad_permanent"), new XAttribute("system_attribute", "false"), new XAttribute("readonly", "false"),
                            new XElement("Value", metadata["Permanent"])),
                        new XElement("Attribute", new XAttribute("id", "ad_keywords"), new XAttribute("system_attribute", "false"), new XAttribute("readonly", "false"),
                            new XElement("Value", metadata["Keywords"])),
                        new XElement("Attribute", new XAttribute("id", "ad_archive"), new XAttribute("system_attribute", "false"), new XAttribute("readonly", "false"),
                            new XElement("Value", metadata["Archive"])),
                        new XElement("Attribute", new XAttribute("id", "ad_is_long_term_format"), new XAttribute("system_attribute", "false"), new XAttribute("readonly", "false"),
                            new XElement("Value", "false"))));                                        //END OF ATTRIBUTES SNIPPET

                signature.Save(signatureFile);
            }
            catch (Exception ex)
            {
                ex.ToString();
                Program.logger.Error(ex);
                throw;
            }
        }
        else
        {
            XDocument doc = XDocument.Load(signatureFile);

            XElement items = doc.Root.Descendants("File").FirstOrDefault();
            items.ReplaceWith(new XElement("File", new XAttribute("file_name", file), new XAttribute("digestmethod", "http://www.w3.org/2000/09/xmldsig#sha1"), 
                new XAttribute("archive_path", "data/" + file), "/E06svX3vAnvYnnGlMT9auuh8uE="));

            doc.Save("C:\\Docs\\modified.xml");
        }

I am having problem with saving the document. It returns me an exception saying that file is being used by another process. I tried using FileStream also, with no success. I need to use the same document as specified. I also tried deleting the file after it's done being used by another method, with the same error. Saving it with date and time makes it unique and it works tho, but its hard to use it in another method in this kind of format. Any ideas?


Solution

  • Based on our conversation with you in the comment section, I believe the problem lies in the method that you use→

    doc.Load(new XmlTextReader(FileName))
    

    Please be aware that XmlTextReader implements IDisposable interface and it uses Stream to read the file you supply in the method by Filename. Since you did not properly dispose new XmlTextReader(FileName) the file stream is still open and it is only natural that you get an exception that the file is being used by another application. I suggest that you use the using like follows, because it will properly dispose of XmlTextReader

    using (var textReader = new XmlTextReader(FILENAME)){
        XDocument doc = XDocument.Load(textReader);
        //DO STUFF
    }