2
votes

I'm just referring back to my question here (not yet resolved):

c# Exception The process cannot access the file

The exception is not happening when I'm running in Debug mode, it's only doing it when I'm running from the exe.

Can someone put a reason to it, why it's giving the exception when running the exe and not in debug mode.

The first time I run the exe, it works successfully and give's me the xml output I need. But for the second find for the watcher. It give me this exception: The process cannot access the file.

4
If you dont need to write to the xml file itself, in its original form, you can try opening it as a ReadOnly/shared filestream and then loading the XmlDocument object from there, rather than using the XmlDocument base, which might not give you as many options...Nevyn
@Nevyn: I'm using XMLDocument to validate if the XML if perfect, if not I use a catch to add the missing tags, because sometimes I get the xml without those missing tags as you can see in the catch right after the xdoc XMLDOCUMENT. Is there any other way to do ituser726720
Im not saying to use something other than XmlDocument, Im saying to open the file using FileStream originally...which gives you more options like ReadOnly and/or Shared, then load the XmlDocument from the FileStream. This might let you get around the initial problem. Now, you still have the issue with malformed xml and having to repair the original file, but that can be taken care of once we get the first issue fixed. One thing at a time :-)Nevyn
@user726720 +1 for your question.RajeshKdev
You are welcome Dude @user726720RajeshKdev

4 Answers

3
votes

I took a look over that complete code set....the issue you are having has to do with events and timing. Your event is firing from the FileWatcher object before whatever process is saving the file lets it go. Try putting a Thread.Sleep right at the top of the Convert method...doesn't need to be too long, start with maybe 1 second or so...see what happens.

    private static void convert(object source, FileSystemEventArgs f)
    {
        string FileName;
        FileName = f.FullPath;
        string FilePath;
        FilePath = f.Name;
                 var watcher = source as FileSystemWatcher;
             string destinationFile = @"D:/GS/" + FilePath;

        Thread.Sleep(1000);

        //...
3
votes

I think you have made your lock wrong, and therefore multiple threads try to get your file

Try to do as follows:

if (Monitor.TryEnter(lockObject))
{
    try{
    //Your actual code
    }
}
else
    return;
1
votes

Your EXE process is running continuously. The process of your exe should be stopped probably. Then "The Process cannot Access the file" error will never come. Use proper Error handling techniques to your codes. Your code has continuous communications with the XML file. So, if you try to access second time, the access error is coming if i'm not wrong.

0
votes

Here is the final convert() that works properly. Thanks to all of you who have helped me here. I really appreciate your time and effort in helping me out. I wish I could accept both the solutions above. But I'm giving my vote to both of you. Thank you once again.

private static void convert(object source, FileSystemEventArgs f)
{
    string FileName;
    FileName = f.FullPath;
    string FilePath;
    FilePath = f.Name;
    var watcher = source as FileSystemWatcher;
    string destinationFile = @"D:/GS/" + FilePath;
    System.Threading.Thread.Sleep(1000);
    if (Monitor.TryEnter(lockObject)) **
    {
        try
        {
            watcher.EnableRaisingEvents = false;
            XmlDocument xdoc = new XmlDocument();
            try
            {
                xdoc.Load(FileName);
                xdoc = null;
            }
            catch (XmlException xe)
            {
                xdoc = null;
                using (StreamWriter w = File.AppendText(FileName))
                {
                    Console.WriteLine(xe);
                    w.WriteLine("</title>");
                    w.WriteLine("</titleContent>");
                    Console.WriteLine("1st");
                }
            }
            System.Threading.Thread.Sleep(2000);
            XPathDocument myXPathDoc = new XPathDocument(new StreamReader(FileName, System.Text.Encoding.GetEncoding("windows-1256")));
            XslCompiledTransform myXslTrans = new XslCompiledTransform();
            myXslTrans.Load("D:/GS/xsl/test.xsl");
            XmlTextWriter myWriter = new XmlTextWriter(destinationFile, null);
            myWriter.Formatting = Formatting.Indented;
            myWriter.Indentation = 4;
            myXslTrans.Transform(myXPathDoc, null, myWriter);
            myWriter.Close();
            Console.WriteLine("2nd");

        }
        catch (Exception e)
        {
            Console.WriteLine("The process failed: {0}", e.ToString());
        }
        finally
        {
            Monitor.Exit(lockObject);
            watcher.EnableRaisingEvents = true;
            Console.WriteLine("Finally");
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
        }
    }
}

}