实际存在时找不到系统文件 - “c:\ windows \ system32 \ alg.exe”。
我最近从Win 7 x86转移到x64,当我在x86上时,我对此没有任何问题,尝试过Delphi 7& XE2。
我正在使用的代码:
if FileExists('c:\windows\system32\alg.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;
答案 0 :(得分:15)
这是因为WOW64 file system redirection
,如果您的32位应用程序想要访问本机system32目录,则必须使用Wow64DisableWow64FsRedirection
函数或Sysnative
别名。
试试这个样本
{$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:\windows\system32\alg.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,导致 应用程序失败。
32位应用程序可以访问本机系统目录 将%windir%\ Sysnative替换为%windir%\ System32。 WOW64 将Sysnative识别为用于指示该文件的特殊别名 系统不应重定向访问。这种机制很灵活 因此,它是推荐的绕过文件的机制 系统重定向。请注意,64位应用程序无法使用 Sysnative别名,因为它是一个虚拟目录而不是真正的目录。
{$APPTYPE CONSOLE}
{$R *.res}
uses
SysUtils,
Windows;
begin
try
if FileExists('c:\windows\SysNative\alg.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 :(得分:12)
您在64位系统上运行32位进程。您的进程在WOW64模拟器中运行,并受File System Redirector的约束。这会将对64位系统文件夹%windir%\ System32的引用重定向到32位系统文件夹%windir%\ SysWOW64。
在模拟器下运行的32位进程中,建议访问64位系统文件夹的方法是使用%windir%\ Sysnative别名:
32位应用程序可以通过将%windir%\ Sysnative替换为%windir%\ System32来访问本机系统目录。 WOW64将Sysnative识别为一个特殊别名,用于指示文件系统不应重定向访问。此机制灵活且易于使用,因此,它是推荐的绕过文件系统重定向的机制。请注意,64位应用程序不能使用Sysnative别名,因为它是虚拟目录而不是真实目录。
当然,这个别名仅存在于64位系统上。检查它的最简单方法是测试TOSVersion.Architecture
的值。
虽然可以禁用重定向器,但建议不要这样做。文档说:
应用程序可以使用Wow64DisableWow64FsRedirection,Wow64EnableWow64FsRedirection和Wow64RevertWow64FsRedirection函数控制WOW64文件系统重定向器。禁用文件系统重定向会影响调用线程执行的所有文件操作,因此只有在单个CreateFile调用需要时才应禁用它,并在函数返回后立即重新启用它。禁用较长时间的文件系统重定向可能会阻止32位应用程序加载系统DLL,从而导致应用程序失败。
我强烈建议您不要禁用文件系统重定向器。