C# &引用;找不到路径的一部分,";在确实存在的路径上

C# &引用;找不到路径的一部分,";在确实存在的路径上,c#,C#,我正在尝试更新锁屏背景,如下所示: string filename = @"C:\app\screenshot.temp.jpg"; string finalLocation = @"C:\Windows\System32\oobe\info\backgrounds\backgroundDefault.jpg"; File.Move(filename, finalLocation); 很遗憾,这会引发System.IO.DirectoryNotFoundException异常: An

我正在尝试更新锁屏背景,如下所示:

 string filename = @"C:\app\screenshot.temp.jpg";
 string finalLocation = @"C:\Windows\System32\oobe\info\backgrounds\backgroundDefault.jpg";
 File.Move(filename, finalLocation);
很遗憾,这会引发System.IO.DirectoryNotFoundException异常:

 An unhandled exception of type 'System.IO.DirectoryNotFoundException' occurred in mscorlib.dll
 Additional information: Could not find a part of the path.

但是,当我在Windows资源管理器、CMD或Powershell中浏览到C:\Windows\System32\oobe\info\backgrounds时,它确实存在。我还可以安全地写入、重命名和删除该位置的文件(并且C#进程正在我的上下文中运行)。发生了什么事?

如果您遇到这种情况,我猜您是在64位版本的Windows上执行此过程

背景

在Windows 32位上,有一个名为“System32”的System32文件夹,用于存储所有32位DLL。在64位Windows上,有两个“System32”文件夹,一个仍称为System32,另一个称为SysWOW64

这两个文件夹存储的内容与其名称的含义相反:

  • System32存储64位DLL
  • SysWOW64存储32位DLL
SysWOW64代表“Windows 64位上的Windows 32位”。因此,它是一个与32位for 32位进程向后兼容的文件夹

为什么这会破坏事物?

微软沉迷于向后兼容性,因此当他们在64位Windows上添加32位仿真时,他们想让运行的32位进程看不到系统的位,并引入了一系列兼容性垫片(修复)

其中一个垫片将仅在32位模式下运行的进程的%WINDIR%\System32的IO请求重定向到%WINDIR%\SysWOW64

因此,当您请求从以下位置移动时:

 C:\Windows\System32\oobe\info\backgrounds\backgroundDefault.jpg    
Windows实际上可能会从以下位置请求移动:

 C:\Windows\SysWOW64\oobe\info\backgrounds\backgroundDefault.jpg
这是不存在的。从而解释了你看到的错误

修复程序

最简单的修复方法是将程序更改为64位进程。您可以通过以下方式完成此操作:

右键单击项目->属性->构建[Tab]->平台目标->x64

现在,当您运行时,针对%WINDIR%\System32的请求实际上应该达到%WINDIR%\System32

或者,如果您需要在32位模式下运行进程(例如,由于库兼容性),您可以要求Windows禁用垫片,如下所示:

 [DllImport("kernel32.dll", SetLastError = true)]
 public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);

 private static void Main(string[] args)
 { 
   IntPtr ptr = new IntPtr();
   bool isWow64FsRedirectionDisabled = Wow64DisableWow64FsRedirection(ref ptr); 
  }
在任何一种情况下,请求都应该由操作系统更直接地处理,您可以更新锁屏背景(或System32中的任何其他操作)