2018 EDIT: As indicated below and by other sources, targeting the Creator's Update or higher allows for read-only file access of a file opened for write by another process. Hooray!
I seem to have hit a brick wall when trying to develop a Windows Store app for the desktop. I'm trying to open a large (100+ MB) log file that another application has open and do real time processing on the latest events as they're written to the file.
With regular, non-sandboxed C#, this is pretty straightforward:
System.IO.FileStream stream = File.Open("LOGFILE PATH HERE", System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Unfortunately, in a UWP, I get "UnauthorizedAccessException" whenever I try to open a file that's in use by another app. I've tried every API in every combination I could find, but have had zero luck, so I've come here for some suggestions.
Some of what I've tried:
Windows.Storage.Pickers.FileOpenPicker picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.List;
//Prompt the user to open the log file:
Windows.Storage.StorageFile logFile = await picker.PickSingleFileAsync();
picker.FileTypeFilter.Add(".txt");
//This won't work in any case, because it doesn't use the handle that the user picked,
// so the UWP sandboxing blocks it:
new FileStream(logFile.Path, FileMode.OpenOrCreate, FileAccess.Read);
//EDIT: These don't work if the file is open either, I must have made a mistake earlier
await FileIO.ReadBufferAsync(logFile);
await FileIO.ReadLinesAsync(logFile);
//These work if the file is not open by another app, but fail if another app has the file open
await logFile.OpenAsync( Windows.Storage.FileAccessMode.Read);
await logFile.OpenStreamForReadAsync();
Quick Repro:
Open a PowerShell window, and run this command to hold open "test.txt" in your home directory:
$f = [System.IO.File]::Open("test.txt", [System.IO.FileMode]::OpenOrCreate, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite);