Jump to content
Sign in to follow this  

Specifying Program Files 32/64 bit location and when compiled for either.

Recommended Posts


I maintain a handful of scripts that must be maintained compatible for both 32 bit and 64 bit. I'm trying to prevent creating two separate versions by simply applying checks for @OSArch where necessary. I flip the #AutoIt3Wrapper_UseX64=n bool value whenever I need x64 bit compilation. My desire is to have no need to change any of the code even if I flip that bit and let the @OSArch checks do the work like so:

If Not StringCompare(@OSArch,"X86") Then
        If Not FileExists(@ProgramFilesDir & '\7-Zip\7z.exe') Then
            $bMissingDependency = True
    ElseIf Not StringCompare(@OSArch,"X64") Then
        If Not FileExists(StringLeft(@WindowsDir,3)&"Program Files" & '\7-Zip\7z.exe') Then
            $bMissingDependency = True
If $bMissingDependency Then
           MsgBox(0, "Required software missing", "The install process requires 7-Zip installed to proceed.  Must abort." & @CRLF _
                & "A browser will now open to the appropriate download location.  There are many versions, select the top one.  Please install and try again.", 30)....
;error handling for missing dependency and so forth.

The probem I've encountered is not trying to specify the x86 program files directory when the script is compiled for x64 bit. Thanks to this post for that appropriate solution to use EnvGet('ProgramFiles(x86)') in those cases : The problem I have is just the opposite. I'm unable to specify the x64 bit Program Files directory when the script is compilled for 32 bit without using some goofy workaround. I'm looking for a cleaner solution if anyone has any, but this is my sloppy workaround for now:

StringLeft(@WindowsDir,3)&"Program Files"

Also, I wasn't able to make use of this since it appeared to have no effect:

DllCall("kernel32.dll", "int", "Wow64DisableWow64FsRedirection", "int", 1)


Could someone be so kind to post a demonstration of how to appropriately use this redirect and point out any potential pitfalls if its used.

Share this post

Link to post
Share on other sites

This is how you use it.

Note: Only compile your script to 32 bit.

If @OSArch = "X64" Then
DllCall('kernel32.dll', 'int', 'Wow64EnableWow64FsRedirection', 'int', 0)
; do somthing here if os is 64 bit
DllCall('kernel32.dll', 'int', 'Wow64EnableWow64FsRedirection', 'int', 1)
; do somthing here if os is 32 bit
Edited by Aipion

Share this post

Link to post
Share on other sites

I think this should work.

; http://www.autoitscript.com/forum/topic/98712-winapiex-udf/

; Default - Get Directory for script architecture
; True - Get path for x64 OS (should return 32bit path on 32bit OS)
; False - Get Path for 32 bit
; on 2000, XP, server 2003 only the path for the script arch is returned.
Func _GetProgramfilesDir($x64=Default)
    ; ProgAndy
    If @OSBuild > 5000 Then ; Windows Longhorn and later
        If $x64 = Default Then
            Return _WinAPI_ShellGetKnownFolderPath($FOLDERID_ProgramFiles)
        ElseIf $x64 Then
            Return RegRead('HKLM64SOFTWAREMicrosoftWindowsCurrentVersion', 'ProgramFilesDir')
            Return _WinAPI_ShellGetKnownFolderPath($FOLDERID_ProgramFilesX86)
    Return SetExtended(1, @ProgramFilesDir)
Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post

Link to post
Share on other sites


I believe I have just found some shorter way.

The registry key "ProgramW6432Dir" in section


refers always to the 64-bit ProgramFilesDir regardless of 32-bit (#AutoIt3Wrapper_UseX64=N)

or 64-bit compilation (#AutoIt3Wrapper_UseX64=Y)

Below a short function to get the 64-bit ProgramFilesDir. It will return an empty string (and @error=1) when run on a 32-bit Operating System

Hope this can help


Func ProgramFilesDir64()

; Return ProgramFilesDir for 64-bit software on a 64-bit OS

; Return empty string and sets @error=1 if run on a 32-bit OS

If @OSArch="X86" Then SetError(1,0,"")

Return RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion", "ProgramW6432Dir")


Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this