Не удалось найти системный файл, когда он действительно существует

#delphi #delphi-2010

#delphi

Вопрос:

Система не может найти, alg.exe но он существует — « c:windowssystem32alg.exe «.

Недавно я перешел с Win 7 x86 на x64, и когда я был на x86, у меня не было проблем с этим, попробовал Delphi 7 и XE2.

Код, который я использую:

 if FileExists('c:windowssystem32alg.exe') then
  ShowMessage('fe') else ShowMessage('fne');
  

Пытался стать владельцем файла моего приложения с правами администратора — та же проблема.

Ребята, чтобы проверить, есть ли x64..

 function IsWow64Process(Handle:THandle; var IsWow64 : BOOL) : BOOL; stdcall; external 'kernel32.dll';

function IS64 : Boolean;
var
 xIS64 : Bool;
begin
 if IsWow64Process(GetCurrentProcess, xIS64) then
  Result := xIS64 else RaiseLastOSError;
end;
  

Комментарии:

1. В качестве анекдота (и кое-чего для удаления модами diamond), я могу сказать вам, что это alg.exe не совсем мой любимый файл в System32 каталоге. Причина довольно проста: я привык запускать приложения нажатием клавиши Win, вводить начало имени приложения и нажимать Enter. Теперь одно из приложений, которое я использую чаще всего, называется ‘AlgoSim’. Я думаю, вы поняли суть.

2. Мой английский хуже, чем мой кошелек.. В нем всего ~ 1 $ .. извините

3. @user2200585 Теперь мой ответ касается вопроса, заданного в вашей правке.

4. @Andreas Rejbrand — вы пробовали Launchy? ( launchy.net ) Аналогичная функциональность функции запуска keystoke, представленной в Win7, но более управляемая. Также имеет несколько хороших плагинов.

5. @HMcG: Нет, не люблю ненужное стороннее программное обеспечение. Мне просто нужно не забыть ввести ‘al’ или ‘algo’!

Ответ №1:

Это потому, что WOW64 file system redirection если ваше 32-разрядное приложение хочет получить доступ к собственному каталогу system32, вы должны использовать Wow64DisableWow64FsRedirection функцию или Sysnative псевдоним.

Wow64DisableWow64FsRedirection

Попробуйте этот пример

 {$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows;

Function Wow64DisableWow64FsRedirection(Var Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
  External 'Kernel32.dll' Name 'Wow64DisableWow64FsRedirection';
Function Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection: LongBool): LongBool; StdCall;
  External 'Kernel32.dll' Name 'Wow64EnableWow64FsRedirection';

Var
  Wow64FsEnableRedirection: LongBool;
begin
 try
    if Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection) then
    begin
      if FileExists('c:windowssystem32alg.exe') then
       Writeln('fe')
      else
       Writeln('fne');

      if not Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection) then
       RaiseLastOSError;
    end
    else
    RaiseLastOSError;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;

end.
end.
  

Дополнительно проверьте документацию MSDN по этому разделу.

Приложения могут управлять средством перенаправления файловой системы WOW64, используя функции Wow64DisableWow64FsRedirection, Wow64EnableWow64FsRedirection и Wow64RevertWow64FsRedirection. Отключение перенаправления файловой системы влияет на все файловые операции, выполняемые вызывающим потоком, поэтому его следует отключать только при необходимости для одного вызова CreateFile и повторно включать сразу после возврата функции. Отключение перенаправления файловой системы на более длительные периоды может помешать 32-разрядным приложениям загружать системные библиотеки DLL, что приведет к сбою приложений.

Sysnative

32-разрядные приложения могут получить доступ к собственному системному каталогу, заменив %windir%Sysnative на %windir%System32. WOW64 распознает Sysnative как специальный псевдоним, используемый для указания того, что файловая система не должна перенаправлять доступ. Этот механизм является гибким и простым в использовании, следовательно, это рекомендуемый механизм для обхода перенаправления файловой системы. Обратите внимание, что 64-разрядные приложения не могут использовать псевдоним Sysnative, поскольку это виртуальный каталог, а не реальный.

 {$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils,
  Windows;

begin
 try
    if FileExists('c:windowsSysNativealg.exe') then
     Writeln('fe')
    else
     Writeln('fne');
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;

end.
  

Комментарии:

1. Я рад, что вы отредактировали ответ, включив предупреждения против отключения перенаправления FS. Но в вашем примере кода отсутствует повторное включение перенаправления, а также отсутствует проверка ошибок. Достаточно справедливо пропустить это в примере, ради удобства чтения, но, по крайней мере, объясните, чего не хватает.

2. Я только что включил вызов Wow64EnableWow64FsRedirection функции.

3. Спасибо. Мой совет заключался бы в использовании Win32Check() . Экономит много шаблонов. Кроме того, возможно, я параноик, но я бы прочитал результат FileExists в Boolean , а затем снова включил. И только потом реагировать на значение в этом Boolean .

Ответ №2:

У вас 32-разрядный процесс, запущенный в 64-разрядной системе. Ваш процесс выполняется внутри эмулятора WOW64 и зависит от средства перенаправления файловой системы. Это перенаправляет ссылки на 64-разрядную системную папку %windir% System32 в 32-разрядную системную папку %windir% SysWOW64.

Рекомендуемый способ получить доступ к 64-разрядной системной папке из 32-разрядного процесса, запущенного под эмулятором, — использовать псевдоним %windir%Sysnative:

32-разрядные приложения могут получить доступ к собственному системному каталогу, заменив %windir%Sysnative на %windir%System32. WOW64 распознает Sysnative как специальный псевдоним, используемый для указания того, что файловая система не должна перенаправлять доступ. Этот механизм является гибким и простым в использовании, следовательно, это рекомендуемый механизм для обхода перенаправления файловой системы. Обратите внимание, что 64-разрядные приложения не могут использовать псевдоним Sysnative, поскольку это виртуальный каталог, а не реальный.

Естественно, этот псевдоним существует только в 64-разрядных системах. Самый простой способ проверить это — проверить значение TOSVersion.Architecture .

Хотя можно отключить перенаправитель, делать это не рекомендуется. В документации говорится:

Приложения могут управлять средством перенаправления файловой системы WOW64, используя функции Wow64DisableWow64FsRedirection, Wow64EnableWow64FsRedirection и Wow64RevertWow64FsRedirection. Отключение перенаправления файловой системы влияет на все файловые операции, выполняемые вызывающим потоком, поэтому его следует отключать только при необходимости для одного вызова CreateFile и повторно включать сразу после возврата функции. Отключение перенаправления файловой системы на более длительные периоды может помешать 32-разрядным приложениям загружать системные библиотеки DLL, что приведет к сбою приложений.

Я бы настоятельно рекомендовал вам не отключать перенаправитель файловой системы.