.NET File.Exists не работает в папке Windows \ System32 \ Drivers? - PullRequest
7 голосов
/ 27 мая 2009

Процесс повышен, и я гарантировал, что путь был правильным в отладчике VS (я использую Environment.GetFolderPath (Environment.SpecialFolder.System), а не жестко его кодирую), но File.Exists по-прежнему возвращает false.

Причина, по которой мне это нужно, - это обходной путь для обеспечения установки некоторых сторонних драйверов, поскольку их параметры реестра не удаляются при удалении.

Я знаю, что записи перенаправляются через виртуализацию, но верно ли это для проверки существования файла?

Ответы [ 5 ]

10 голосов
/ 27 мая 2009

Да, виртуализация происходит на очень низком уровне. Метод 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 (я полагаю, до SP2) не предоставляют эти методы.

Обновление 2: Добавлена ​​проверка ОС для 64-битных. Все 64-разрядные версии ОС реализуют эти методы, и вам нужно только отключить состояние, если он работает на 64-разрядной ОС.

2 голосов
/ 27 мая 2009

Вы пытались отключить виртуализацию папок для своего приложения? Вам нужно добавить файл манифеста, содержащий:

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

Однако, если вам нужно записать в эти папки, вам нужно запросить права администратора . Для этого измените level="asInvoker" на level="requireAdministrator" в xml.

2 голосов
/ 27 мая 2009

Ваш процесс 32-битный или 64-битный? а драйверы 64 или 32? Я понимаю, что, возможно, ваша хост-система перенаправляет вас в папку Wow64.

0 голосов
/ 27 мая 2009

Если у вас есть права, почему бы вам не попытаться создать файл в том же месте в вашем коде и посмотреть, где он заканчивается? Как предполагает другой, Windows может перенаправить ваш вызов на основе нескольких настроек.

Кроме того, вы можете попробовать выполнить DirectoryInfo и перечислить содержащиеся в нем файлы, чтобы проверить, не выглядит ли что-нибудь знакомым.

0 голосов
/ 27 мая 2009

Это проблема виртуализации - файла просто нет. Вам придется искать его в папке, содержащей виртуализированные файлы.

...