C# 程序以 32 位运行时在 System32 中找不到文件的解决方案
问题描述
最近使用C#开发windows应急响应信息收集的工具,发现获取不到系统中的事件日志的文件。
在ide中下断点调试。
报错提示:ERROR 3 (0x00000003) Accessing Source Directory C:\Windows\System32\WINEVT\LOGS\
The system cannot find the path specified.
而在本地的cmd中执行确定没有任何问题,一开始以为是C#程序的执行权限不够,后来给了管理员权限执行也无法解决。
解决方案
以 64 位运行程序没有问题,当以 AnyCPU 或 32 位运行时,程序只在 SysWOW64 中查找,即使要求在 System32 中查找。
使用以下命名空间:
using System.Runtime.InteropServices;
在类文件的顶部添加以下内容。
[DllImport("kernel32.dll", SetLastError = true)] public static extern int Wow64DisableWow64FsRedirection(ref IntPtr ptr); [DllImport("kernel32.dll", SetLastError = true)] public static extern int Wow64EnableWow64FsRedirection(ref IntPtr ptr);
在执行cmd之前,使用如下:
IntPtr val = IntPtr.Zero; Wow64DisableWow64FsRedirection(ref val);
cmd执行完成后,还原更改:
Wow64EnableWow64FsRedirection(ref val);
重新下断点调试后正常执行。
代码实现
修改后的完整代码如下:
using System; using System.Diagnostics; using System.Runtime.InteropServices; namespace GetInfo { public class Cmd { [DllImport("kernel32.dll", SetLastError = true)] public static extern int Wow64DisableWow64FsRedirection(ref IntPtr ptr); [DllImport("kernel32.dll", SetLastError = true)] public static extern int Wow64EnableWow64FsRedirection(ref IntPtr ptr); [DllImport("kernel32.dll", SetLastError = true)] public static extern int Wow64RevertWow64FsRedirection(ref IntPtr ptr); private Process proc = (Process) null; public Cmd() => this.proc = new Process(); public string RunCmd(string cmd) { IntPtr val = IntPtr.Zero; Wow64DisableWow64FsRedirection(ref val); //禁用重定向 this.proc.StartInfo.CreateNoWindow = true; this.proc.StartInfo.FileName = "cmd.exe"; this.proc.StartInfo.UseShellExecute = false; this.proc.StartInfo.RedirectStandardError = true; this.proc.StartInfo.RedirectStandardInput = true; this.proc.StartInfo.RedirectStandardOutput = true; this.proc.Start(); this.proc.StandardInput.WriteLine(cmd); this.proc.StandardInput.WriteLine("exit"); string end = this.proc.StandardOutput.ReadToEnd(); this.proc.Close(); Wow64RevertWow64FsRedirection(ref val); //开启重定向 return end; }
原因分析
32位程序存在文件系统重定向的问题,64位程序则不会。在代码中禁用重定向即可。
因为%windir%\System32
专为 64 位应用程序保留,所以在 64 位版本的 Windows 上,尝试访问该%windir%\System32
目录的 32 位应用程序会自动且透明地重定向到 32 位%windir%\SysWOW64
目录。
首先,确保程序确实属于 64 位系统文件夹。Windows 执行此自动重定向是有原因的。32 位的东西不在%windir%\System32
64 位版本的 Windows 上的文件夹中。
微信赞赏支付宝赞赏
发表评论