AlgoRythm
AlgoRythm

Reputation: 1389

System.IO Exception when using FileInfo on files in the root of the drive

I am creating a file explorer using UWP technologies.

I originally thought that I was unable to see files on a specific removable drive, but as it turns out, anything in the root folder of a drive will throw a System.IOException

I can see the other drives and access their properties, but when I read the Length of one, it throws the following exception:

System.IO.IOException: The parameter is incorrect at System.IO.WinRTIOExtensions.d__2`1.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.IO.WinRTFileSystem.WinRTFileSystemObject.d__25.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.IO.WinRTFileSystem.WinRTFileSystemObject.EnsureItemInitialized() at System.IO.WinRTFileSystem.WinRTFileSystemObject.get_Attributes() at System.IO.FileInfo.get_Length() at Traverse.MainPage.<>c__DisplayClass9_0.b__0()

Here's the code that breaks:

Task.Run(() => {
    Debug.WriteLine(path);
    FileInfo fileInfo = new FileInfo(path);
    Debug.WriteLine(fileInfo.FullName);
    Debug.WriteLine(fileInfo.Length);
});

Output:

D:\bitmap-machine.html
D:\bitmap-machine.html

(The long error message from above)

Some more code that will trigger the issue:

FileInfo f = new FileInfo(@"C:\ReadMe.txt");
Debug.WriteLine(f.Length);

Some code which will NOT trigger the issue:

FileInfo f = new FileInfo(@"C:\PHP\php.gif");
Debug.WriteLine(f.Length);

I have the removable devices capability enabled, and I can confirm it is working because I can see the devices.

I would expect an error about not having permission to the drive, but a "The parameter is incorrect" when trying to get file length is certainly odd!

Upvotes: 1

Views: 812

Answers (1)

Xie Steven
Xie Steven

Reputation: 8611

According to our discussion in above comment, I made a reply here.

If you use 'broadFileSystemAccess' capability, you need to call Windows.Storage APIs.

System.IO is available with no note of deprecation, and it works everywhere except the root of the drive. I'd say just because there are working alternatives doesn't mean this isn't an odd issue, unless this behavior is intentional

It's a long story. UWP is different from the classic desktop app. UWP apps use Windows Runtime APIs, the desktop apps use .Netframework APIs. If you started developing UWP a long time ago, for example, if you know the Universal Windows 8.1 app, we could call it UWP8.1 app. In UWP 8.1, we could only call windows runtime APIs, the FileInfo class APIs and other .Netframework APIs do not support in UWP 8.1. We cannot even find this class when programming.

Then, with the release of Windows 10(10240), the UWP(Universal Windows Platform) is introduced. You could try to switch your project's target version to 10240. At this time, benefit from the .Net Standard, we could find some classic .Netframework APIs when programming, for example, the FileInfo class, but you still cannot call this APIs successfully. It's because all UWP apps run sandboxed and have very limited access to the file system. The FileInfo class APIs still do not support in UWP 10240. If you check .NET API Browser, you could see that the FileInfo class is available from .Net Standard 1.6. Looking at it together with this table, before the UWP 16299, UWP only supports .Net Standard 1.4 and previous versions.

From the 16299, UWP supports .Net Standard 2.0. This release brings UWP to partity with the other .NET implementations that support .NET Standard 2.0. But as I said, UWP apps run sandboxed and have very limited access to the file system. If you want to call FileInfo class APIs to access files from outside the app container, it's still not allowed.

In view of this, from the 17134, the restricted capability broadFileSystemAccess is introduced. When you add this capability, you could get all files that the user has access to, not only the app container. For example: documents, pictures, photos, downloads, desktop, OneDrive, etc. But the premise is that you would have to use Windows Storage namespace APIs. If you check the document, the FileInfo class is not included in the Windows.Stroage namespace. That's the reason why I say It's not an odd issue.

Upvotes: 1

Related Questions