Jump to content

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
        EndIf
    ElseIf Not StringCompare(@OSArch,"X64") Then
        If Not FileExists(StringLeft(@WindowsDir,3)&"Program Files" & '\7-Zip\7z.exe') Then
            $bMissingDependency = True
        EndIf
    EndIf
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)

http://www.autoitscript.com/autoit3/docs/intro/64-bit_support.htm

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.

Link to comment
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)
Else
; do somthing here if os is 32 bit
EndIf
Edited by Guest
Link to comment
Share on other sites

I think this should work.

#include<WinAPIEx.au3>
#include<APIConstants.au3>
; 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')
        Else
            Return _WinAPI_ShellGetKnownFolderPath($FOLDERID_ProgramFilesX86)
        EndIf
    EndIf
    Return SetExtended(1, @ProgramFilesDir)
EndFunc
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

Link to comment
Share on other sites

  • 5 months later...

Hello

I believe I have just found some shorter way.

The registry key "ProgramW6432Dir" in section

"HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion"

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")

EndFunc

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...