2009-05-26 69 views
7

这个过程被提升了,我确保了路径在VS调试器中是正确的(我使用的是Environment.GetFolderPath(Environment.SpecialFolder.System)而不是硬编码)但是File.Exists仍然返回false。.NET File.Exists在Windows System32 Drivers文件夹中不起作用?

我需要这个的原因是确保安装某些第三方驱动程序的解决方法,因为它们的注册表设置在卸载时不会被删除。

我知道写入是通过虚拟化重定向的,但这对于检查文件是否存在也是正确的?

+0

适合我。你的环境是什么? – Noldorin 2009-05-26 21:04:15

回答

10

是的,虚拟化发生在非常低​​的水平。 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重定向之前检查OS版本,因为早期版本的XP(SP2之前的我相信)不公开这些方法。

更新2:增加了64位的操作系统检查。所有64位版本的操作系统都实现这些方法,并且只需要在64位操作系统上运行即可禁用状态。

+0

因此,尝试/最后我还需要检查操作系统版本?如果它不被支持,我想finally块也会抛出。 – Davy8 2009-05-27 14:29:57

2

你的进程是32位还是64位?并且是司机64或32?我得到的是,也许你的主机操作系统将你重定向到Wow64文件夹。

0

这是一个虚拟化问题 - 该文件不存在。您将不得不在包含虚拟化文件的文件夹中查找它。

0

如果您有权利,为什么不尝试在代码中的相同位置创建文件,并查看它结束的位置?正如另一个人所建议的那样,Windows可能会根据一些设置重定向您的呼叫。

此外,你可以尝试做一个DirectoryInfo并枚举它包含的文件,看看是否有什么看起来很熟悉。

2

您是否试过disabling folder virtualization为您的应用程序?你需要添加含有清单文件:

<?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> 

然而,如果你需要写你必须request admin ability这些文件夹。为此,请在xml中将level="asInvoker"更改为level="requireAdministrator"

相关问题