24

I have an winforms application that loads in excel files for analysis. Currently, in order to open the excel file the file must not be already open in excel otherwise a FileIOException is thrown when I try and load in the file.

What I would like to do is allow my application to read in the file even if it is open in excel rather than forcing the user to close down the worksheet first. Note that the application in question only needs to read the file, not write to it.

Is this possible?

Calanus
  • 25,619
  • 25
  • 85
  • 120

4 Answers4

31

You could try passing FileShare.ReadWrite when opening the file:

using (var stream = new FileStream(
       @"d:\myfile.xls", 
       FileMode.Open, 
       FileAccess.Read, 
       FileShare.ReadWrite))
{

}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I think the FileShare flag is for the other case - when you want to allow other applications to have access to the file – ChrisF Jun 26 '09 at 09:43
  • This from the meta data: "Contains constants for controlling the kind of access other System.IO.FileStream objects can have to the same file" – ChrisF Jun 26 '09 at 09:44
  • 4
    In the case of future openers, a FileShare.Read means "future openers can open the file for reading". In the case of past openers, FileShare.Read means "open this file for me only if it has past openers that opened it for reading only". That's why FileShare.ReadWrite needs to be used here, because Excel opens the file for writing. – Darin Dimitrov Jun 26 '09 at 09:46
7

How are you trying to open the file?

If you are trying to open it for read/write then you'll get the exception. If you are trying to open it for read only then you should be OK.

var file = File.Open("file.xls", FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

This will only work if Excel has opened the file with FileShare.Read set to allow other applications (i.e. your's) to have access to the file. If this isn't set then Excel will have opened the file with exclusive access. Note: I don't think this is the case as you can open an Excel file (in Excel) for read if someone else has it open for edit.

UPDATE - OK I didn't test this properly until after darin's comments. You need the FileShare.ReadWrite flag despite the help indicating that it's for subsequent file openers. Not even FileShare.Read is good enough, which I find even odder.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
1

SpreadsheetGear for .NET can read workbooks while Excel has them open. Here is the code we use to do it (note that we lock the entire file after opening to keep Excel or any other app from writing while we are in the middle of reading):

stream = new System.IO.FileStream(path,
    System.IO.FileMode.Open,
    System.IO.FileAccess.Read,
    System.IO.FileShare.ReadWrite,
    SG.CompoundDocumentIO.Storage.OpenBufferLength);
try
{
    stream.Lock(0, stream.Length);
}
catch
{
    // .NET 1.1 requires cast to IDisposable
    ((IDisposable)stream).Dispose();
    throw;
}

Disclaimer: I own SpreadsheetGear LLC

Joe Erickson
  • 7,077
  • 1
  • 31
  • 31
0

Try making a copy of the already opened file, read it and discard it. In order to check if the file is already opened, try reading and handle the exception by doing the copy, read, discard.

tzup
  • 3,566
  • 3
  • 26
  • 34