Search code examples
inno-setupemulationarm64windows-11

Can Inno Setup detect Windows11 on ARM64 hardware which can emulate x64?


Windows 11 supports emulating x64 hardware whilst actually running on an ARM64 platform. An example of this would be running Windows inside a virtual machine on a Mac.

Previously my Inno installer was just using the following to ensure that the PC was capable of running our software:

ArchitecturesAllowed=x64

However on an ARM-based system like the example given this causes the setup to terminate because it (rightly) sees arm64 as the architecture.

I can't just add arm64 to that line because that won't distinguish between older ARM-based systems which have no x64 emulation capability and those that do.

Hopefully, in the Inno Setup Google Group this topic was discussed as follows:

Jordan Russell Oct 4, 2021, 5:45:40 PM

...

If they were to switch to "ArchitecturesInstall64BitMode=x64 arm64", then you should get the x64 files. Unfortunately, however, the x64 files would also be installed on older ARM64 builds that don't support x64 emulation, resulting in a non-functioning app.

...

I do still plan, though, to add official support for detecting x64 emulation in the near future. A new architecture identifier "x64compatible" will match both x64 Windows and ARM64 Windows with x64 emulation support, and an IsX64Compatible function will also be added. To encourage adoption of "x64compatible" so that more x64 apps can be installed on ARM64, the existing "x64" will be deprecated and renamed to "x64strict", and later on the compiler will print a warning when "x64" is used.

However the relevant Inno documentation sections don't seem to have any mention of this. (https://jrsoftware.org/ishelp/index.php?topic=setup_architecturesallowed, https://jrsoftware.org/ishelp/index.php?topic=isxfunc_isarm64)

Is there any built-in way to do it?

If not I may have to try some direct system calls such as those mentioned in How to detect if Windows supports running x64 processes?.


Solution

  • This answer applies to versions of Inno Setup before 6.3.0.

    As the question you have linked shows, you can call GetMachineTypeAttributes WinAPI function on Windows 11 to determine x64 support. On older versions of Windows, use ProcessorArchitecture Inno Setup support function

    Something like this should do (but I do not have ARM64 machine to test this on).

    [Code]
    
    const
      IMAGE_FILE_MACHINE_AMD64 = $8664;
    
    function GetMachineTypeAttributes(
        Machine: Word; var MachineTypeAttributes: Integer): HRESULT;
      external '[email protected] stdcall delayload';
    
    <event('InitializeSetup')>
    function InitializeSetupCheckArchitecture(): Boolean;
    var
      MachineTypeAttributes: Integer;
      Arch: TSetupProcessorArchitecture;
    begin
      if IsWindows11OrNewer then
      begin
        OleCheck(
          GetMachineTypeAttributes(IMAGE_FILE_MACHINE_AMD64, MachineTypeAttributes));
        if MachineTypeAttributes <> 0 then
        begin
          Log('Windows 11 or newer, with x64 support');
          Result := True;
        end
          else
        begin
          Log('Windows 11 or newer, without x64 support');
          Result := False;
        end;
      end
        else
      begin
        Arch := ProcessorArchitecture;
        if Arch = paX64 then
        begin
          Log('Windows 10 or older, on x64 architecture');
          Result := True;
        end
          else
        begin
          Log('Windows 10 or older, not on x64 architecture');
          Result := False;
        end;
      end;
    
      if not Result then
      begin
        MsgBox('This product can be installed on system with x64 support only.',
          mbError, MB_OK);
      end;
    end;
    

    The code completely replaces the ArchitecturesAllowed directive (it assumes it is not set, though setting it to x64 arm64 should do no harm).

    The IsWindows11OrNewer comes from Determine Windows version in Inno Setup.