【问题标题】:C# file not found in System32 when running in 32 bit以 32 位运行时在 System32 中找不到 C# 文件
【发布时间】:2015-08-12 13:50:20
【问题描述】:

我正在尝试运行 quser 并获取结果字符串。当我运行下面的代码时,我看到以下消息,结果字符串为空:

'quser' 不是内部或外部命令、可运行程序或批处理文件。

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c quser /server:SomeServer";
p.Start();

string output = p.StandardOutput.ReadToEnd();

p.WaitForExit();
Console.WriteLine(output);

所以运行的完整命令是

cmd.exe /c quser /ser:SomeServer

当我直接执行时运行良好,但从 C# 失败。

我在这里找到了一个没有答案的类似问题:Executing Quser windows command in C#; Returning result to String。不过,这个问题没有quser not recognized 消息。

为什么从代码运行时无法识别命令?

我尝试像这样直接运行quser 命令,但我得到一个文件未找到...奇怪

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = @"c:\Windows\System32\quser.exe";
p.StartInfo.Arguments = @"/server:SomeServer";
p.Start();

string output = p.StandardOutput.ReadToEnd();

p.WaitForExit();
Console.WriteLine(output);

我们发现以 64 位运行它,它会找到它。当以 AnyCPU 或 32 位运行时,它似乎在 SysWOW64 中查找,即使我直接告诉它在 System32 中查找

【问题讨论】:

  • 它在谁下运行?这可能是PATH 环境变量问题。
  • 您是否尝试过前面带有@ 的参数字符串,就像在您的链接问题中一样?
  • @MattJones 添加 @ 没有区别
  • @Dleh 另外,你确定这不是魔兽世界64相关的问题吗?我的意思是 x64 Windows 上 x86 程序的路径重定向。
  • @EugenePodskal 我在这里工作的 64 位 Windows 8.1 PC 上运行了相同的代码。

标签: c#


【解决方案1】:

好的,所以我找到了解决方案。

基本上,正如我们在 chat 中发现的那样,System32 文件夹在某些版本上重定向到 SysWOW64,导致 quser 看起来存在。

我已成功应用解决方法。

解决方法:

  1. 使用以下命名空间:

     using System.Runtime.InteropServices;
    
  2. 在类文件的顶部添加以下内容。

     [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);
    
  3. 在拨打quser 之前,请拨打以下电话:

     IntPtr val = IntPtr.Zero;
     Wow64DisableWow64FsRedirection(ref val);
    
  4. 拨打quser 电话后,还原更改:

     Wow64EnableWow64FsRedirection(ref val);
    

完整示例:

using System.Runtime.InteropServices;

...
namespace CSharpTests
{
    public class Program
    {
        [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);

        static void Main(string[] args)
        {
            IntPtr val = IntPtr.Zero;
            Wow64DisableWow64FsRedirection(ref val);
            Process p = new Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = "/c quser";
            p.Start();

            string output = p.StandardOutput.ReadToEnd();

            p.WaitForExit();
            Console.WriteLine(output);
            Wow64RevertWow64FsRedirection(ref val);
            p = new Process();
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = "/c quser";
            p.Start();

            output = p.StandardOutput.ReadToEnd();

            p.WaitForExit();
            Console.WriteLine(output);
        }
    }
}

结果:

USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
ebrown                console             1  Active      none   05/18/2015 09:2
1
'quser' is not recognized as an internal or external command,
operable program or batch file.

如您所见,第一次quser 调用成功,因为我们告诉操作系统停止重定向到SysWOW64,一旦我们重新启用它,调用就失败了。

我确信这种保护是有原因的,但有时你不需要它。

其他注意事项:

实施此模式的人最好先检测是否需要应用变通方法。这种检测可以通过使用以下布尔值来完成:

Environment.GetFolderPath(Environment.SpecialFolder.SystemX86).Contains("System32")

如果是假布尔值,则需要检查:

File.Exists(@"c:\windows\System32\FILENAMEHERE")

在这种情况下:

File.Exists(@"c:\windows\System32\qdisk.exe")

改编自:

http://blog.airesoft.co.uk/2010/09/wow-disabling-wow64-fs-redirection-can-cause-problems-who-knew/

https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx

【讨论】:

  • @dleh 没问题。总是乐于助人。我建议您修改标题,以便其他用户更容易找到实际问题。
  • 确实,我已经对其进行了修改以更好地描述真正的问题。
猜你喜欢
  • 1970-01-01
  • 2021-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-02
相关资源
最近更新 更多