2009-06-26 9 views
20

Mam aplikację WinForms, która ładuje pliki Excel do analizy. Obecnie, aby otworzyć plik Excela, plik nie może być już otwarty w programie Excel, w przeciwnym razie generowany jest wyjątek FileIOException, gdy próbuję załadować plik.Jak otworzyć plik otwarty w innej aplikacji

Chciałbym zezwolić mojej aplikacji na odczyt w pliku, nawet jeśli jest otwarty w programie Excel, zamiast zmuszać użytkownika do zamknięcia arkusza. Zwróć uwagę, że dana aplikacja musi jedynie odczytać plik, a nie pisać do niego.

Czy to możliwe?

Odpowiedz

26

Można spróbować przechodząc FileShare.ReadWrite podczas otwierania pliku:

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

} 
+0

Myślę, że flaga FileShare jest dla drugiego przypadku - kiedy chcesz zezwolić innym aplikacjom na dostęp do pliku – ChrisF

+0

To z metadanych: "Zawiera stałe kontrolujące rodzaj dostępu inne obiekty System.IO.FileStream mogą mieć ten sam plik " – ChrisF

+4

W przypadku przyszłych programów otwierających, FileShare.Read oznacza" przyszły program otwierający może otworzyć plik do odczytu ". W przypadku wcześniejszych programów otwierających FileShare.Read oznacza "otwórz ten plik tylko dla mnie, jeśli ma już otwarte programy otwierające je tylko do odczytu". Dlatego właśnie należy używać FileShare.ReadWrite, ponieważ program Excel otwiera plik do zapisu. –

6

Jak próbujesz otworzyć plik?

Jeśli próbujesz otworzyć go do odczytu/zapisu, otrzymasz wyjątek. Jeśli próbujesz otworzyć go tylko do odczytu, powinieneś być w porządku.

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

To będzie działać tylko wtedy, Excel otwiera plik z FileShare.Read zestaw do umożliwienia inne aplikacje (czyli twoje), aby mieć dostęp do pliku. Jeśli nie zostanie to ustawione, program Excel otworzy plik z wyłącznym dostępem. Uwaga: Nie sądzę, aby tak było, ponieważ możesz otworzyć plik Excel (w programie Excel), aby przeczytać, jeśli ktoś inny ma go otworzyć do edycji.

AKTUALIZACJA - OK Nie przetestowałem tego poprawnie, dopóki nie padną komentarze. Potrzebujesz flagi FileShare.ReadWrite pomimo pomocy wskazującej, że jest ona przeznaczona dla kolejnych programów do otwierania plików. Nawet FileShare.Read nie jest wystarczająco dobre, co jest nawet dziwne.

+0

To nie jest poprawne. Używanie FileShare.Read oznacza: "otwórz ten plik tylko dla mnie, jeśli któryś z poprzednich programów otwierał go do odczytu." co nie jest tak, ponieważ Excel otworzył go do pisania. –

+2

@darin - Nie używam FileShare. – ChrisF

+0

Dobra odpowiedź. Rzeczywiście, pliki Excel nie są otwierane z wyłącznym dostępem, więc ta metoda jest całkiem możliwa. – Noldorin

0

Spróbuj tworzenia kopii już otwartego pliku, przeczytaj go i wyrzucić go. Aby sprawdzić, czy plik jest już otwarty, spróbuj odczytać i obsłużyć wyjątek, wykonując kopię, przeczytaj, odrzuć.

1

może odczytać skoroszyt, podczas gdy program Excel je otwiera. Oto kod używamy to zrobić (zauważ, że możemy zablokować cały plik po otwarciu zachować Excel lub innych aplikacji od pisania, podczas gdy jesteśmy w środku czytanie):

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; 
} 

Zastrzeżenie: Jestem właścicielem SpreadsheetGear LLC