3

a file is located in C:\program files (x86)\my app\myexe.exe

  1. FileExists('C:\program files (x86)\my app\myexe.exe') returns true;

  2. FileExists('C:\program files\my app\myexe.exe') returns false; in both cases, if I use Wow64DisableWow64FsRedirection or not.

Why ? Thanks

user382591
  • 1,320
  • 5
  • 19
  • 39

1 Answers1

8

File system redirection is only there for the %windir%\system32 directory. The description of the File System Redirector seems to make this obvious.

Note the comment in the page

Applications should use the SHGetSpecialFolderPath function to determine the %ProgramFiles% directory name.

Edit Turns out that the FOLDERID_ProgramFilesx64 does not work on 32bit applications running on 64bit windows. In this case, you can use the environment variable %ProgramW6432% instead. Note that this variable is only available on Windows 7 and later for 32bit applications.

The following delphi snippet allows accessing the variable:

function GetEnvironmentString(aString : string) : string;
var
  dest : string;
  retSize : integer;
begin
  SetLength(dest, MAX_PATH);
  retSize := ExpandEnvironmentStrings(pchar(aString), pchar(dest), MAX_PATH);
  if retSize > 0 then
      SetLength(dest, retSize - 1);
  result := dest;
end;

Called as:

GetEnvironmentString('%ProgramW6432%');

IF you're on a 64bit version of windows, then a 32bit application cannot use FOLDERID_ProgramFilesX64 to explicitly get the 64bit location of Program Files, but can use the environment variable expansion instead. On a 32bit version of windows, this location is invalid, and will not get you a value. You need to check the bitness of the system before attempting to access this variable.

You can use the function IsWow64Process to determine this. The following snippet should allow you to check this:

function IsWow64: Boolean;
type
  TIsWow64Process = function(Handle: Windows.THandle; var Res: Windows.BOOL): Windows.BOOL; stdcall;
var
  IsWow64Result: Windows.BOOL;
  IsWow64Process: TIsWow64Process;
begin
  // Try to load required function from kernel32
  IsWow64Process := Windows.GetProcAddress(Windows.GetModuleHandle('kernel32.dll'), 'IsWow64Process');
  if Assigned(IsWow64Process) then
  begin
    // Function is implemented: call it
    if not IsWow64Process(Windows.GetCurrentProcess, IsWow64Result) then
      raise SysUtils.Exception.Create('IsWow64: bad process handle');
    // Return result of function
    Result := IsWow64Result;
  end
  else
    // Function not implemented: can't be running on Wow64
    Result := False;
end;

In summary: FOLDERID_ProgramFiles gives you the 32/64 bit variant when accessed from a 32/64 bit program, FOLDERID_ProgramFilesX64 gives you the 64bit version explicitly on a 64-bit application, and FOLDERID_ProgramFilesX86 gives you the 32bit variant explicitly. You can use the environment variable expansion to get the 64bit value on a 32bit application

Anya Shenanigans
  • 91,618
  • 3
  • 107
  • 122
  • No other path concerned then ? – user382591 Jul 19 '12 at 07:39
  • As stated in the page, In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64. Access to %windir%\lastgood\system32 is redirected to %windir%\lastgood\SysWOW64. Access to %windir%\regedit.exe is redirected to %windir%\SysWOW64\regedit.exe. There are some explicit excpetions, and they are called out on the page as well. – Anya Shenanigans Jul 19 '12 at 07:50
  • As showed here : http://stackoverflow.com/questions/11426708/accessing-icons-in-a-64bit-exe-with-a-32bit-program it seems that a 32bit app will resolve shortcuts that contain %Programfiles% to the x86 directory... – Lars Bargmann Jul 19 '12 at 14:33
  • Caused by explorer being a 32bit application. The document at http://msdn.microsoft.com/en-us/library/windows/hardware/gg463051.aspx contains a lot of useful hints and details in relation to appropriate variable use – Anya Shenanigans Jul 19 '12 at 15:26
  • 1
    `FOLDERID_ProgramFilesX64` **is not** available to 32-bit apps running under WOW64. This is [documented by MSDN](http://download.microsoft.com/download/A/F/7/AF7777E5-7DCD-4800-8A0A-B18336565F5B/wow64_bestprac.docx): "Some variables work only if the process is 64-bit. For example, FOLDERID_ProgramFilesX64 does not work for 32-bit callers". However, a 32-bit process can use the `%ProgramW6432%` environment variable instead, at least on Windows 7 and later. – Remy Lebeau Jul 20 '12 at 02:31
  • self contradictory document - the table in the document implies it will work, while a sample program shows that it doesn't – Anya Shenanigans Jul 20 '12 at 04:52