System.IO 对驱动器根目录中的文件使用 FileInfo 时出现异常
System.IO Exception when using FileInfo on files in the root of the drive
我正在使用 UWP 技术创建一个文件资源管理器。
我原以为我无法看到特定可移动驱动器上的文件,但事实证明,驱动器根文件夹中的任何内容都会抛出 System.IOException
我可以看到其他驱动器并访问它们的属性,但是当我读取其中一个的 Length
时,它抛出以下异常:
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()
这是中断的代码:
Task.Run(() => {
Debug.WriteLine(path);
FileInfo fileInfo = new FileInfo(path);
Debug.WriteLine(fileInfo.FullName);
Debug.WriteLine(fileInfo.Length);
});
输出:
D:\bitmap-machine.html
D:\bitmap-machine.html
(The long error message from above)
更多会触发该问题的代码:
FileInfo f = new FileInfo(@"C:\ReadMe.txt");
Debug.WriteLine(f.Length);
一些不会触发问题的代码:
FileInfo f = new FileInfo(@"C:\PHP\php.gif");
Debug.WriteLine(f.Length);
我启用了可移动设备功能,我可以确认它正在工作,因为我可以看到这些设备。
我预计会出现关于没有驱动器权限的错误,但是在尝试获取文件长度时 "The parameter is incorrect" 肯定很奇怪!
根据我们在上面评论中的讨论,我在这里做了一个回复。
如果您使用 'broadFileSystemAccess' 功能,则需要调用 Windows.Storage API。
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
说来话长。 UWP 不同于 classic 桌面应用程序。 UWP 应用程序使用 Windows 运行时 API,桌面应用程序使用 .Netframework API。如果您很久以前就开始开发 UWP,例如,如果您知道 Universal Windows 8.1 应用程序,我们可以将其称为 UWP8.1 应用程序。在UWP 8.1中,我们只能调用windows 运行time API,FileInfo
class API和其他.Netframework API在UWP 8.1中不支持。我们编程的时候连这个class都找不到
然后,随着 Windows 10(10240) 的发布,引入了 UWP(通用 Windows 平台)。你可以尝试将项目的目标版本切换到10240。此时,受益于.Net Standard,我们可以在编程时找到一些classic .Netframework API,例如FileInfo
class,但仍然无法成功调用此API。这是因为所有 UWP 应用程序 运行 都被沙盒化并且对文件系统的访问权限非常有限。 FileInfo
class API 在 UWP 10240 中仍然不支持。如果您检查 .NET API Browser, you could see that the FileInfo
class is available from .Net Standard 1.6. Looking at it together with this table,在 UWP 16299 之前,UWP 仅支持 .Net Standard 1.4 和之前的版本。
从16299开始,UWP支持.Net Standard 2.0。此版本使 UWP 与支持 .NET Standard 2.0 的其他 .NET 实现相结合。但正如我所说,UWP 应用程序 运行 沙盒化并且对文件系统的访问非常有限。如果你想调用FileInfo
class APIs从应用程序容器外部访问文件,它仍然是不允许的。
鉴于此,从17134开始,引入了限制能力broadFileSystemAccess
。添加此功能后,您可以获得用户有权访问的所有文件,而不仅仅是应用程序容器。例如:文档、图片、照片、下载、桌面、OneDrive等。但前提是你必须使用Windows Storage命名空间API。如果查看文档,FileInfo
class 不包含在 Windows.Stroage
命名空间中。这就是为什么我说这不是一个奇怪的问题。
我正在使用 UWP 技术创建一个文件资源管理器。
我原以为我无法看到特定可移动驱动器上的文件,但事实证明,驱动器根文件夹中的任何内容都会抛出 System.IOException
我可以看到其他驱动器并访问它们的属性,但是当我读取其中一个的 Length
时,它抛出以下异常:
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()
这是中断的代码:
Task.Run(() => {
Debug.WriteLine(path);
FileInfo fileInfo = new FileInfo(path);
Debug.WriteLine(fileInfo.FullName);
Debug.WriteLine(fileInfo.Length);
});
输出:
D:\bitmap-machine.html
D:\bitmap-machine.html
(The long error message from above)
更多会触发该问题的代码:
FileInfo f = new FileInfo(@"C:\ReadMe.txt");
Debug.WriteLine(f.Length);
一些不会触发问题的代码:
FileInfo f = new FileInfo(@"C:\PHP\php.gif");
Debug.WriteLine(f.Length);
我启用了可移动设备功能,我可以确认它正在工作,因为我可以看到这些设备。
我预计会出现关于没有驱动器权限的错误,但是在尝试获取文件长度时 "The parameter is incorrect" 肯定很奇怪!
根据我们在上面评论中的讨论,我在这里做了一个回复。
如果您使用 'broadFileSystemAccess' 功能,则需要调用 Windows.Storage API。
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
说来话长。 UWP 不同于 classic 桌面应用程序。 UWP 应用程序使用 Windows 运行时 API,桌面应用程序使用 .Netframework API。如果您很久以前就开始开发 UWP,例如,如果您知道 Universal Windows 8.1 应用程序,我们可以将其称为 UWP8.1 应用程序。在UWP 8.1中,我们只能调用windows 运行time API,FileInfo
class API和其他.Netframework API在UWP 8.1中不支持。我们编程的时候连这个class都找不到
然后,随着 Windows 10(10240) 的发布,引入了 UWP(通用 Windows 平台)。你可以尝试将项目的目标版本切换到10240。此时,受益于.Net Standard,我们可以在编程时找到一些classic .Netframework API,例如FileInfo
class,但仍然无法成功调用此API。这是因为所有 UWP 应用程序 运行 都被沙盒化并且对文件系统的访问权限非常有限。 FileInfo
class API 在 UWP 10240 中仍然不支持。如果您检查 .NET API Browser, you could see that the FileInfo
class is available from .Net Standard 1.6. Looking at it together with this table,在 UWP 16299 之前,UWP 仅支持 .Net Standard 1.4 和之前的版本。
从16299开始,UWP支持.Net Standard 2.0。此版本使 UWP 与支持 .NET Standard 2.0 的其他 .NET 实现相结合。但正如我所说,UWP 应用程序 运行 沙盒化并且对文件系统的访问非常有限。如果你想调用FileInfo
class APIs从应用程序容器外部访问文件,它仍然是不允许的。
鉴于此,从17134开始,引入了限制能力broadFileSystemAccess
。添加此功能后,您可以获得用户有权访问的所有文件,而不仅仅是应用程序容器。例如:文档、图片、照片、下载、桌面、OneDrive等。但前提是你必须使用Windows Storage命名空间API。如果查看文档,FileInfo
class 不包含在 Windows.Stroage
命名空间中。这就是为什么我说这不是一个奇怪的问题。