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?
You could try passing FileShare.ReadWrite when opening the file:
using (var stream = new FileStream(
@"d:\myfile.xls",
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
}
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.
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
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.