凌云的博客

行胜于言

抓虫日志 - 文件无法访问

分类:debug| 发布时间:2022-04-01 10:47:00

问题

最近写了个程序用于访问 Windows 系统下的文件,发现无法访问

C:\Windows\System32\Tasks\Microsoft\Windows\SoftwareProtectionPlatform

这个目录,返回错误码 ERROR_PATH_NOT_FOUND 或者 ERROR_FILE_NOT_FOUND。

最初以为是权限不足,为文件添加相关访问权限,最后 Chrome 浏览器都能访问其内容了,我写的程序还是报一样的错误。

原因

这个问题查了很久都无果,突然想到我写的程序是编写成 32 位版本的,运行在 64 位 Windows 下,会不会是 Windows 对这个目录进行了重定向,一查果然是这个原因,对于运行在 64 位 Windows 的 32 位程序,Windows 会重定向以下目录:

Original Path Redirected Path for 32-bit x86 Processes Redirected Path for 32-bit ARM Processes
%windir%\System32 %windir%\SysWOW64 %windir%\SysArm32
%windir%\lastgood\system32 %windir%\lastgood\SysWOW64 %windir%\lastgood\SysArm32
%windir%\regedit.exe %windir%\SysWOW64\regedit.exe %windir%\ SysArm32\regedit.exe

解决方案

  1. 在 64 位系统使用 64 位版本程序,这个方法是最直观的,也是最推荐的,在 64 位系统使用 64 位程序,可以避免这些奇怪的问题,同时程序运行效率也会比较高,在可以将程序编译成 64 位的情况下,这个方法是最推荐的
  2. 32 位程序可以通过使用 %windir%\Sysnative 替代 %windir%\System32 来访问 64 位系统中的 %windir%\System32 目录
  3. 使用 Wow64DisableWow64FsRedirection 方法来禁用重定向,注意这个函数只会在当前调用线程禁用文件系统的重定向

一点思考

下面是我的一点思考,不一定正确,欢迎拍砖。

Windows 为什么不提供一个对整个进程生效的禁用重定向的方法?

禁用整个进程的重定向行为,影响太大,如果其他线程有动态加载 DLL 的情况,可能会导致系统到 %windir%\System32 而不是 %windir%\SysWOW64 寻找依赖库,从而导致失败

64 位系统为什么不新建一个 %windir%\System64 文件夹,64 位相关内容放里面?

照我的理解,这是更优的方案,可能是历史遗留问题导致微软没有这样设计。

注册表也有类似的重定向行为,详情查看 Registry Redirector

参考