【参考1】https://www.cnblogs.com/iamlucky/p/5998086.html
【参考2】https://www.bbsmax.com/A/mo5kj04KJw/
问题描述
vs1027在X64应用程序下执行process.start()
时,OK;但是在X86应用程序下执行process.start()
,报错:找不到系统文件
if (kbpr.HasExited)
{
kbpr = Process.Start(@"C:\Windows\System32\osk.exe");
}
网上搜索良久,发现原因为:windows重定向搞得鬼
在64位的Windows操作系统中,为了兼容32位程序的运行,64位的Windows操作系统采用重定向机制。目的是为了能让32位程序在64位的操作系统不仅能操作关键文件文夹和关键的注册表并且又要避免与64位程序冲突;因此,32位应用程序的运行是通过WOW64的模拟器来实现的。WOW64 是一个由操作系统提供的兼容性环境,它使得 32 位应用程序能够在 Windows 64 位操作系统上运行,在系统的Windows目录下,存在System32和SysWOW64两个文件夹:
System32文件夹下存放的是64位DLL
SysWOW64文件夹下存放的是32位DLL
因此,如果我们用32位程序去访问c:\windows\system32,不管我们用硬编码还是其它的方式,系统都会自动地给我们转向到C:\windows\syswow64下面。
禁止系统的重定向的解决办法是调用下面的API函数
禁用系统重定向用下面的函数:
BOOL Wow64DisableWow64FsRedirection(PVOID OldValue);
恢复系统重定向用下面的函数:
BOOL Wow64RevertWow64FsRedirection(PVOID OldValue);
解决办法
具体代码如下:
// 关闭64位(文件系统)的操作转向
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
// 开启64位(文件系统)的操作转向
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);
IntPtr oldWOW64State = new IntPtr();
Wow64DisableWow64FsRedirection(ref oldWOW64State); // 关闭64位(文件系统)的操作转向
Wow64RevertWow64FsRedirection(oldWOW64State); // 开启64位(文件系统)的操作转向
注1
网上还有中办法,将路径c:\windows\system32\
改为c:\windows\sysnative\
,但是我尝试,好像不管用;可能是需要注册表或者哪里设置过吧
注2
当然最简单的办法,是将应用程序改为64位,就不存在以上问题了。