代码之家  ›  专栏  ›  技术社区  ›  Davy8

.NET文件.exists在Windows\System32\Drivers文件夹中不起作用?

  •  7
  • Davy8  · 技术社区  · 15 年前

    进程被提升,我确保在vs调试器中路径是正确的(我使用的是environment.getfolderpath(environment.specialfolder.system)而不是硬编码),但file.exists仍返回false。

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

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

    5 回复  |  直到 15 年前
        1
  •  10
  •   Paul Alexander    15 年前

    是的,虚拟化发生在一个非常低的水平上。file.exists方法基本上调用win32 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(我相信是sp2之前的版本)不会公开这些方法。

    更新2: 增加了64位操作系统检查。所有64位版本的操作系统都实现了这些方法,如果在64位操作系统上运行,您只需要禁用SATE。

        2
  •  2
  •   Remus Rusanu    15 年前

    您的进程是32位还是64位?司机是64还是32?我想知道的是,主机操作系统可能会将您重定向到wow64文件夹。

        3
  •  2
  •   Wilka    15 年前

    你试过了吗? 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 . 为此,改变 level="asInvoker" level="requireAdministrator" 在XML中。

        4
  •  0
  •   Daniel Brückner Pradip    15 年前

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

        5
  •  0
  •   SqlRyan    15 年前

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

    另外,您可以尝试执行directoryInfo并枚举它包含的文件,以查看是否有任何内容看起来熟悉。