该过程被提升,我确保在 VS 调试器中路径是正确的(我使用的是 Environment.GetFolderPath(Environment.SpecialFolder.System) 而不是硬编码它),但 File.Exists 仍然返回 false。
我需要这个的原因是确保安装某些 3rd 方驱动程序的解决方法,因为它们的注册表设置在卸载时不会被删除。
我知道写入是通过虚拟化重定向的,但这对于检查文件是否存在也是如此?
该过程被提升,我确保在 VS 调试器中路径是正确的(我使用的是 Environment.GetFolderPath(Environment.SpecialFolder.System) 而不是硬编码它),但 File.Exists 仍然返回 false。
我需要这个的原因是确保安装某些 3rd 方驱动程序的解决方法,因为它们的注册表设置在卸载时不会被删除。
我知道写入是通过虚拟化重定向的,但这对于检查文件是否存在也是如此?
是的,虚拟化发生在非常低的水平。File.Exists 方法基本上调用 Win32 CreateFile 方法并检查错误。CreateFile 由 WOW 子系统重定向。
您可以在调用之前暂时禁用虚拟化。
[DllImport( "kernel32", CharSet=CharSet.Unicode, SetLastError=true )]
public static extern bool Wow64DisableWow64FsRedirection( ref IntPtr oldValue );
[DllImport( "kernel32", CharSet=CharSet.Unicode, SetLastError=true )]
public static extern bool Wow64RevertWow64FsRedirection( IntPtr oldValue );
当然,要完整,您必须在虚拟化打开和关闭的情况下检查文件是否存在。这同样适用于检查注册表项。
public static bool FileExists( string path )
{
if( File.Exists( path ) ) return true;
IntPtr oldValue = IntPtr.Zero;
try
{
if( Environment.GetEnvironmentVariable( "PROCESSOR_ARCHITEW6432" ) == null )
return false;
Wow64DisableWow64FsRedirection( ref oldValue );
if( File.Exists( path ) ) return true;
return false;
}
finally
{
if( oldValue != IntPtr.Zero )
Wow64RevertWow64FsRedirection( ref oldValue );
}
}
更新:您可能还需要在禁用 WOW 重定向之前检查操作系统版本,因为早期版本的 XP(我相信是 Pre SP2)不公开这些方法。
更新 2:添加了 64 位操作系统检查。所有 64 位版本的操作系统都实现了这些方法,如果在 64 位操作系统上运行,您只需禁用状态即可。
您的进程是 32 位还是 64 位?驱动程序是 64 还是 32?我要说的是,您的主机操作系统可能会将您重定向到 Wow64 文件夹。
您是否尝试过为您的应用禁用文件夹虚拟化?您需要添加一个清单文件,其中包含:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
但是,如果您需要写入这些文件夹,则必须请求管理员权限。为此,请在 xml 中更改level="asInvoker"
为。level="requireAdministrator"
这是一个虚拟化问题 - 文件不存在。您必须在包含虚拟化文件的文件夹中查找它。
如果您有权限,为什么不尝试在代码中的相同位置创建一个文件,然后看看它在哪里结束?正如另一个人所建议的那样,Windows 可能会根据一些设置重定向您的呼叫。
此外,您可以尝试执行 DirectoryInfo 并枚举其中包含的文件,看看是否有任何熟悉的内容。