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%\System3264 位版本的 Windows 上的文件夹中。
微信赞赏
支付宝赞赏
发表评论