tags:

views:

542

answers:

5

I have an application where I open a log file for writing. At some point in time (while the application is running), I opened the file with Excel 2003, which said the file should be opened as read-only. That's OK with me.

But then my application threw this exception:

System.IO.IOException: The process cannot access the file because another process has locked a portion of the file.

I don't understand how Excel could lock the file (to which my app has write access), and cause my application to fail to write to it!

Why did this happen?

(Note: I didn't observe this behavior with Excel 2007.)

A: 

How do you write the log? Have your own open/close or use some thirty party product?

I thing that the log is opened and locked only when it writes something. Once the data writing is finished, the code closes the file and, of course, releases the lock

FerranB
I open a System.IO.FileStream and keep it open until I finish processing some input data. In the case described above, the stream was still open.
Hosam Aly
+1  A: 

Here is a logger which will take care of sync locks. (You can modify it to fit to your requirements)

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Owf.Logger
{
    public class Logger
    {
        private static object syncContoller = string.Empty;
        private static Logger _logger;
        public static Logger Default
        {
            get
            {
                if (_logger == null)
                    _logger = new Logger();

                return _logger;
            }
        }

        private Dictionary<Guid, DateTime> _starts = new Dictionary<Guid, DateTime>();

        private string _fileName = "Log.txt";

        public string FileName
        {
            get { return _fileName; }
            set { _fileName = value; }
        }

        public Guid LogStart(string mesaage)
        {
            lock (syncContoller)
            {
                Guid id = Guid.NewGuid();

                _starts.Add(id, DateTime.Now);

                LogMessage(string.Format("0.00\tStart: {0}", mesaage));

                return id;
            }
        }

        public void LogEnd(Guid id, string mesaage)
        {
            lock (syncContoller)
            {
                if (_starts.ContainsKey(id))
                {
                    TimeSpan time = (TimeSpan)(DateTime.Now - _starts[id]);

                    LogMessage(string.Format("{1}\tEnd: {0}", mesaage, time.TotalMilliseconds.ToString()));
                }
                else
                    throw new ApplicationException("Logger.LogEnd: Key doesn't exisits.");
            }
        }

        public void LogMessage(string message)
        {
            lock (syncContoller)
            {
                string filePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

                if (!filePath.EndsWith("\\"))
                    filePath += "\\owf";
                else
                    filePath += "owf";

                if (!Directory.Exists(filePath))
                    Directory.CreateDirectory(filePath);

                filePath += "\\Log.txt";

                lock (syncContoller)
                {
                    using (StreamWriter sw = new StreamWriter(filePath, true))
                    {
                        sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.sss") + "\t" + message);
                    }
                }
            }
        }
    }
}
Ramesh Soni
Thanks, but that's not what I was asking about. I'm opening a simple file to write on it. Now when Excel opens the same file for reading my application fails to write to it, because *Excel* locked it. I'm wondering why.
Hosam Aly
A: 

Did you found any solution to this problem? It seems that i have the exact same issue..

I cannot actually replicate it at home, since my home machine has Windows Vista with Excel 2007 installed, and the issue does not occur in my setup. So unfortunately no! If you find one, I would be thankful if you tell me!
Hosam Aly
A: 

I believe I'm having the same type of locking issue, reproduced as follows:

User 1 opens Excel2007 file from network (read-write) (WindowsServer, version unkn). User 2 opens same Excel file (opens as ReadOnly, of course). User 1 successfully saves file many times At some point, User 1 is UNABLE to save the file due to message saying "file is locked". Close down User 2's ReadOnly version...lock is released, and User 1 can now save again.

How could opening the file in ReadOnly mode put a lock on that file?

So, it seems to be either an Excel2007 issue, or a server issue.

Allen
A: 

This seems like a .NET issue. (Well; a Bug if you ask me).

Basically I have replicated the problem by using the following multi-threaded code:

  Dim FS As System.IO.FileStream
  Dim BR As System.IO.BinaryReader

  Dim FileBuffer(-1) As Byte

  If System.IO.File.Exists(FileName) Then
   Try
    FS = New System.IO.FileStream(FileName, System.IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
    BR = New System.IO.BinaryReader(FS)

    Do While FS.Position < FS.Length
     FileBuffer = BR.ReadBytes(&H10000)

     If FileBuffer.Length > 0 Then
      ... do something with the file here... 
     End If
    Loop

    BR.Close()
    FS.Close()

   Catch
    ErrorMessage = "Error(" & Err.Number & ") while reading file:" & Err.Description
   End Try


Basically, the bug is that trying to READ the file with all different share-modes (READ, WRITE, READ_WRITE) have absolutely no effect on the file locking, no matter what you try; you would always end up in the same result: The is LOCKED and not available for any other user.

Microsoft won't even admit to this problem.

The solution is to use the internal Kernel32 CreateFile APIs to get the proper access done as this would ensure that the OS LISTENs to your request when requesting to read files with a share-locked or locked access.

Heider Sati