diff --git a/Src/BUILDME.txt b/Src/BUILDME.txt
index c859d5413..95a6ad8ba 100644
--- a/Src/BUILDME.txt
+++ b/Src/BUILDME.txt
@@ -10,7 +10,7 @@ Visual Studio 2019 (Community Edition is enough)
   - Windows 10 SDK (10.0.19041.0) for Desktop C++
   - Visual C++ ATL support
 HTML Help Workshop
-WiX 3.14
+WiX 3.7 (3.14 for ARM64)
 7-Zip
 It is possible to convert the projects to newer versions of Visual Studio and newer SDKs.
 Newer versions of WiX will probably work fine.
diff --git a/Src/OpenShell.sln b/Src/OpenShell.sln
index f2932acf3..0b8f5275b 100644
--- a/Src/OpenShell.sln
+++ b/Src/OpenShell.sln
@@ -151,7 +151,7 @@ Global
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Release|Win32.Build.0 = Release|Win32
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Release|x64.ActiveCfg = Release|Win32
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Release|x64.Build.0 = Release|Win32
-		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Setup|ARM64.ActiveCfg = Release|Win32
+		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Setup|ARM64.ActiveCfg = Release|ARM64
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Setup|Win32.ActiveCfg = Release|Win32
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Setup|x64.ActiveCfg = Release|Win32
 		{EA65FDDD-CB77-417F-8BB4-2F3ECB5B3E75}.Debug|ARM64.ActiveCfg = Resource|Win32
diff --git a/Src/Setup/BuildArchives.bat b/Src/Setup/BuildArchives.bat
index eb5231a6d..8ea60554c 100644
--- a/Src/Setup/BuildArchives.bat
+++ b/Src/Setup/BuildArchives.bat
@@ -1,8 +1,11 @@
 REM ***** Collect PDBs
 
 echo -- Creating symbols package
-set CS_SYMBOLS_NAME=OpenShellPDB_%CS_VERSION_STR%.7z
+set CS_SYMBOLS_NAME=OpenShellPDB_%CS_VERSION_STR%
+if %ARCH%==ARM64 set CS_SYMBOLS_NAME=%CS_SYMBOLS_NAME%_ARM64
+set CS_SYMBOLS_NAME=%CS_SYMBOLS_NAME%.7z
 
+if exist Final\%CS_SYMBOLS_NAME% del Final\%CS_SYMBOLS_NAME% > nul
 7z a -mx9 .\Final\%CS_SYMBOLS_NAME% .\Output\symbols\* > nul
 
 if defined APPVEYOR (
diff --git a/Src/Setup/BuildBinaries.bat b/Src/Setup/BuildBinaries.bat
index ea05f84fa..75e37c283 100644
--- a/Src/Setup/BuildBinaries.bat
+++ b/Src/Setup/BuildBinaries.bat
@@ -7,15 +7,17 @@ echo -- Compiling
 
 for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do set MSBuildDir=%%i\MSBuild\Current\Bin\
 
-REM ********* Build ARM64 solution
-echo --- ARM64
-"%MSBuildDir%MSBuild.exe" ..\OpenShell.sln /m /t:Rebuild /p:Configuration="Setup" /p:Platform="ARM64" /verbosity:quiet /nologo
-@if ERRORLEVEL 1 exit /b 1
-
-REM ********* Build x64 solution
-echo --- x64
-"%MSBuildDir%MSBuild.exe" ..\OpenShell.sln /m /t:Rebuild /p:Configuration="Setup" /p:Platform="x64" /verbosity:quiet /nologo
-@if ERRORLEVEL 1 exit /b 1
+if %ARCH%==ARM64 (
+	REM ********* Build ARM64 solution
+	echo --- ARM64
+	"%MSBuildDir%MSBuild.exe" ..\OpenShell.sln /m /t:Rebuild /p:Configuration="Setup" /p:Platform="ARM64" /verbosity:quiet /nologo
+	if ERRORLEVEL 1 exit /b 1
+) else (
+	REM ********* Build x64 solution
+	echo --- x64
+	"%MSBuildDir%MSBuild.exe" ..\OpenShell.sln /m /t:Rebuild /p:Configuration="Setup" /p:Platform="x64" /verbosity:quiet /nologo
+	if ERRORLEVEL 1 exit /b 1
+)
 
 REM ********* Build 32-bit solution (must be after 64-bit)
 echo --- x86
@@ -48,19 +50,21 @@ copy /B ..\Update\DesktopToasts\Release\DesktopToasts.dll Output > nul
 copy /B ..\StartMenu\StartMenuHelper\Setup\StartMenuHelper32.dll Output > nul
 copy /B ..\Setup\SetupHelper\Release\SetupHelper.exe Output > nul
 
-copy /B ..\ClassicExplorer\Setup64\ClassicExplorer64.dll Output\x64 > nul
-copy /B ..\ClassicIE\Setup64\ClassicIEDLL_64.dll Output\x64 > nul
-copy /B ..\ClassicIE\Setup64\ClassicIE_64.exe Output\x64 > nul
-copy /B ..\StartMenu\Setup64\StartMenu.exe Output\x64 > nul
-copy /B ..\StartMenu\Setup64\StartMenuDLL.dll Output\x64 > nul
-copy /B ..\StartMenu\StartMenuHelper\Setup64\StartMenuHelper64.dll Output\x64 > nul
-
-copy /B ..\ClassicExplorer\SetupARM64\ClassicExplorerARM64.dll Output\ARM64 > nul
-copy /B ..\ClassicIE\SetupARM64\ClassicIEDLL_ARM64.dll Output\ARM64 > nul
-copy /B ..\ClassicIE\SetupARM64\ClassicIE_ARM64.exe Output\ARM64 > nul
-copy /B ..\StartMenu\SetupARM64\StartMenu.exe Output\ARM64 > nul
-copy /B ..\StartMenu\SetupARM64\StartMenuDLL.dll Output\ARM64 > nul
-copy /B ..\StartMenu\StartMenuHelper\SetupARM64\StartMenuHelperARM64.dll Output\ARM64 > nul
+if %ARCH%==ARM64 (
+	copy /B ..\ClassicExplorer\SetupARM64\ClassicExplorerARM64.dll Output\ARM64 > nul
+	copy /B ..\ClassicIE\SetupARM64\ClassicIEDLL_ARM64.dll Output\ARM64 > nul
+	copy /B ..\ClassicIE\SetupARM64\ClassicIE_ARM64.exe Output\ARM64 > nul
+	copy /B ..\StartMenu\SetupARM64\StartMenu.exe Output\ARM64 > nul
+	copy /B ..\StartMenu\SetupARM64\StartMenuDLL.dll Output\ARM64 > nul
+	copy /B ..\StartMenu\StartMenuHelper\SetupARM64\StartMenuHelperARM64.dll Output\ARM64 > nul
+) else (
+	copy /B ..\ClassicExplorer\Setup64\ClassicExplorer64.dll Output\x64 > nul
+	copy /B ..\ClassicIE\Setup64\ClassicIEDLL_64.dll Output\x64 > nul
+	copy /B ..\ClassicIE\Setup64\ClassicIE_64.exe Output\x64 > nul
+	copy /B ..\StartMenu\Setup64\StartMenu.exe Output\x64 > nul
+	copy /B ..\StartMenu\Setup64\StartMenuDLL.dll Output\x64 > nul
+	copy /B ..\StartMenu\StartMenuHelper\Setup64\StartMenuHelper64.dll Output\x64 > nul
+)
 
 copy /B "..\StartMenu\Skins\Classic Skin.skin" Output > nul
 copy /B "..\StartMenu\Skins\Full Glass.skin" Output > nul
@@ -89,13 +93,15 @@ copy /B Output\ClassicExplorer32.dll Output\PDB32 > nul
 copy /B ..\ClassicExplorer\Setup\ClassicExplorerSettings.pdb Output\PDB32 > nul
 copy /B Output\ClassicExplorerSettings.exe Output\PDB32 > nul
 
-REM Explorer x64
-copy /B ..\ClassicExplorer\Setup64\ClassicExplorer64.pdb Output\PDBx64 > nul
-copy /B Output\x64\ClassicExplorer64.dll Output\PDBx64 > nul
-
-REM Explorer ARM64
-copy /B ..\ClassicExplorer\SetupARM64\ClassicExplorerARM64.pdb Output\PDBARM64 > nul
-copy /B Output\ARM64\ClassicExplorerARM64.dll Output\PDBARM64 > nul
+if %ARCH%==ARM64 (
+	REM Explorer ARM64
+	copy /B ..\ClassicExplorer\SetupARM64\ClassicExplorerARM64.pdb Output\PDBARM64 > nul
+	copy /B Output\ARM64\ClassicExplorerARM64.dll Output\PDBARM64 > nul
+) else (
+	REM Explorer x64
+	copy /B ..\ClassicExplorer\Setup64\ClassicExplorer64.pdb Output\PDBx64 > nul
+	copy /B Output\x64\ClassicExplorer64.dll Output\PDBx64 > nul
+)
 
 REM IE 32
 copy /B ..\ClassicIE\Setup\ClassicIEDLL_32.pdb Output\PDB32 > nul
@@ -103,17 +109,19 @@ copy /B Output\ClassicIEDLL_32.dll Output\PDB32 > nul
 copy /B ..\ClassicIE\Setup\ClassicIE_32.pdb Output\PDB32 > nul
 copy /B Output\ClassicIE_32.exe Output\PDB32 > nul
 
-REM IE x64
-copy /B ..\ClassicIE\Setup64\ClassicIEDLL_64.pdb Output\PDBx64 > nul
-copy /B Output\x64\ClassicIEDLL_64.dll Output\PDBx64 > nul
-copy /B ..\ClassicIE\Setup64\ClassicIE_64.pdb Output\PDBx64 > nul
-copy /B Output\x64\ClassicIE_64.exe Output\PDBx64 > nul
-
-REM IE ARM64
-copy /B ..\ClassicIE\SetupARM64\ClassicIEDLL_ARM64.pdb Output\PDBARM64 > nul
-copy /B Output\ARM64\ClassicIEDLL_ARM64.dll Output\PDBARM64 > nul
-copy /B ..\ClassicIE\SetupARM64\ClassicIE_ARM64.pdb Output\PDBARM64 > nul
-copy /B Output\ARM64\ClassicIE_ARM64.exe Output\PDBARM64 > nul
+if %ARCH%==ARM64 (
+	REM IE ARM64
+	copy /B ..\ClassicIE\SetupARM64\ClassicIEDLL_ARM64.pdb Output\PDBARM64 > nul
+	copy /B Output\ARM64\ClassicIEDLL_ARM64.dll Output\PDBARM64 > nul
+	copy /B ..\ClassicIE\SetupARM64\ClassicIE_ARM64.pdb Output\PDBARM64 > nul
+	copy /B Output\ARM64\ClassicIE_ARM64.exe Output\PDBARM64 > nul
+) else (
+	REM IE x64
+	copy /B ..\ClassicIE\Setup64\ClassicIEDLL_64.pdb Output\PDBx64 > nul
+	copy /B Output\x64\ClassicIEDLL_64.dll Output\PDBx64 > nul
+	copy /B ..\ClassicIE\Setup64\ClassicIE_64.pdb Output\PDBx64 > nul
+	copy /B Output\x64\ClassicIE_64.exe Output\PDBx64 > nul
+)
 
 REM Menu 32
 copy /B ..\StartMenu\Setup\StartMenu.pdb Output\PDB32 > nul
@@ -127,21 +135,23 @@ copy /B Output\Update.exe Output\PDB32 > nul
 copy /B ..\Update\DesktopToasts\Release\DesktopToasts.pdb Output\PDB32 > nul
 copy /B Output\DesktopToasts.dll Output\PDB32 > nul
 
-REM Menu x64
-copy /B ..\StartMenu\Setup64\StartMenu.pdb Output\PDBx64 > nul
-copy /B Output\x64\StartMenu.exe Output\PDBx64 > nul
-copy /B ..\StartMenu\Setup64\StartMenuDLL.pdb Output\PDBx64 > nul
-copy /B Output\x64\StartMenuDLL.dll Output\PDBx64 > nul
-copy /B ..\StartMenu\StartMenuHelper\Setup64\StartMenuHelper64.pdb Output\PDBx64 > nul
-copy /B Output\x64\StartMenuHelper64.dll Output\PDBx64 > nul
-
-REM Menu ARM64
-copy /B ..\StartMenu\SetupARM64\StartMenu.pdb Output\PDBARM64 > nul
-copy /B Output\ARM64\StartMenu.exe Output\PDBARM64 > nul
-copy /B ..\StartMenu\SetupARM64\StartMenuDLL.pdb Output\PDBARM64 > nul
-copy /B Output\ARM64\StartMenuDLL.dll Output\PDBARM64 > nul
-copy /B ..\StartMenu\StartMenuHelper\SetupARM64\StartMenuHelperARM64.pdb Output\PDBARM64 > nul
-copy /B Output\ARM64\StartMenuHelperARM64.dll Output\PDBARM64 > nul
+if %ARCH%==ARM64 (
+	REM Menu ARM64
+	copy /B ..\StartMenu\SetupARM64\StartMenu.pdb Output\PDBARM64 > nul
+	copy /B Output\ARM64\StartMenu.exe Output\PDBARM64 > nul
+	copy /B ..\StartMenu\SetupARM64\StartMenuDLL.pdb Output\PDBARM64 > nul
+	copy /B Output\ARM64\StartMenuDLL.dll Output\PDBARM64 > nul
+	copy /B ..\StartMenu\StartMenuHelper\SetupARM64\StartMenuHelperARM64.pdb Output\PDBARM64 > nul
+	copy /B Output\ARM64\StartMenuHelperARM64.dll Output\PDBARM64 > nul
+) else (
+	REM Menu x64
+	copy /B ..\StartMenu\Setup64\StartMenu.pdb Output\PDBx64 > nul
+	copy /B Output\x64\StartMenu.exe Output\PDBx64 > nul
+	copy /B ..\StartMenu\Setup64\StartMenuDLL.pdb Output\PDBx64 > nul
+	copy /B Output\x64\StartMenuDLL.dll Output\PDBx64 > nul
+	copy /B ..\StartMenu\StartMenuHelper\Setup64\StartMenuHelper64.pdb Output\PDBx64 > nul
+	copy /B Output\x64\StartMenuHelper64.dll Output\PDBx64 > nul
+)
 
 REM ********* Source Index PDBs
 
diff --git a/Src/Setup/BuildInstaller.bat b/Src/Setup/BuildInstaller.bat
index a036dcd8a..64d8161ed 100644
--- a/Src/Setup/BuildInstaller.bat
+++ b/Src/Setup/BuildInstaller.bat
@@ -24,6 +24,13 @@ echo -- Building Installer (%CS_LANG_NAME_SHORT%)
 
 SET CS_INSTALLER_NAME=OpenShellSetup_%CS_VERSION_STR%-%CS_LANG_NAME_SHORT%
 if %CS_LANG_NAME_SHORT%==en SET CS_INSTALLER_NAME=OpenShellSetup_%CS_VERSION_STR%
+if %ARCH%==ARM64 SET CS_INSTALLER_NAME=%CS_INSTALLER_NAME%_ARM64
+
+SET CS_SETUP_ARCH=Win32
+if %ARCH%==ARM64 SET CS_SETUP_ARCH=ARM64
+
+SET CS_SETUP_DIR=Release
+if %ARCH%==ARM64 SET CS_SETUP_DIR=%CS_SETUP_DIR%ARM64
 
 if exist Temp rd /Q /S Temp
 md Temp
@@ -36,58 +43,61 @@ md Temp
 	@set /a "CS_VERSION_NUM=%%A<<24|%%B<<16|%%C"
 )
 
-REM ********* Build x86 MSI
-echo --- x86 MSI
-candle Setup.wxs -nologo -out Temp\Setup32.wixobj -ext WixUIExtension -ext WixUtilExtension -dx64=0 -dARM64=0 -dCS_LANG_FOLDER=%CS_LANG_FOLDER% -dCS_LANG_NAME=%CS_LANG_NAME%
-@if ERRORLEVEL 1 exit /b 1
-
-@REM We need to suppress ICE38 and ICE43 because they apply only to per-user installation. We only support per-machine installs
-@REM We need to suppress ICE09 because the helper DLLs need to go into the system directory (for safety reasons)
-light Temp\Setup32.wixobj -nologo -out Temp\Setup32.msi -ext WixUIExtension -ext WixUtilExtension -loc ..\Localization\%CS_LANG_FOLDER%\OpenShellText-%CS_LANG_NAME%.wxl -loc ..\Localization\%CS_LANG_FOLDER%\WixUI_%CS_LANG_NAME%.wxl -sice:ICE38 -sice:ICE43 -sice:ICE09
-@if ERRORLEVEL 1 exit /b 1
-
-
-REM ********* Build x64 MSI
-echo --- x64 MSI
-candle Setup.wxs -nologo -out Temp\Setup64.wixobj -ext WixUIExtension -ext WixUtilExtension -dx64=1 -dARM64=0 -dCS_LANG_FOLDER=%CS_LANG_FOLDER% -dCS_LANG_NAME=%CS_LANG_NAME%
-@if ERRORLEVEL 1 exit /b 1
-
-@REM We need to suppress ICE38 and ICE43 because they apply only to per-user installation. We only support per-machine installs
-@REM We need to suppress ICE09 because the helper DLLs need to go into the system directory (for safety reasons)
-light Temp\Setup64.wixobj -nologo -out Temp\Setup64.msi -ext WixUIExtension -ext WixUtilExtension -loc ..\Localization\%CS_LANG_FOLDER%\OpenShellText-%CS_LANG_NAME%.wxl -loc ..\Localization\%CS_LANG_FOLDER%\WixUI_%CS_LANG_NAME%.wxl -sice:ICE38 -sice:ICE43 -sice:ICE09
-@if ERRORLEVEL 1 exit /b 1
-
-
-REM ********* Build ARM64 MSI
-echo --- ARM64 MSI
-candle Setup.wxs -nologo -out Temp\SetupARM64.wixobj -ext WixUIExtension -ext WixUtilExtension -dx64=0 -dARM64=1 -dCS_LANG_FOLDER=%CS_LANG_FOLDER% -dCS_LANG_NAME=%CS_LANG_NAME%
-@if ERRORLEVEL 1 exit /b 1
-
-@REM We need to suppress ICE38 and ICE43 because they apply only to per-user installation. We only support per-machine installs
-@REM We need to suppress ICE09 because the helper DLLs need to go into the system directory (for safety reasons)
-light Temp\SetupARM64.wixobj -nologo -out Temp\SetupARM64.msi -ext WixUIExtension -ext WixUtilExtension -loc ..\Localization\%CS_LANG_FOLDER%\OpenShellText-%CS_LANG_NAME%.wxl -loc ..\Localization\%CS_LANG_FOLDER%\WixUI_%CS_LANG_NAME%.wxl -sice:ICE38 -sice:ICE43 -sice:ICE09
-@if ERRORLEVEL 1 exit /b 1
-
+if %ARCH%==ARM64 (
+	REM ********* Build ARM64 MSI
+	echo --- ARM64 MSI
+	candle Setup.wxs -nologo -out Temp\SetupARM64.wixobj -ext WixUIExtension -ext WixUtilExtension -dx64=0 -dARM64=1 -dCS_LANG_FOLDER=%CS_LANG_FOLDER% -dCS_LANG_NAME=%CS_LANG_NAME%
+	if ERRORLEVEL 1 exit /b 1
+
+	REM We need to suppress ICE38 and ICE43 because they apply only to per-user installation. We only support per-machine installs
+	REM We need to suppress ICE09 because the helper DLLs need to go into the system directory (for safety reasons)
+	light Temp\SetupARM64.wixobj -nologo -out Temp\SetupARM64.msi -ext WixUIExtension -ext WixUtilExtension -loc ..\Localization\%CS_LANG_FOLDER%\OpenShellText-%CS_LANG_NAME%.wxl -loc ..\Localization\%CS_LANG_FOLDER%\WixUI_%CS_LANG_NAME%.wxl -sice:ICE38 -sice:ICE43 -sice:ICE09
+	if ERRORLEVEL 1 exit /b 1
+) else (
+	REM ********* Build x86 MSI
+	echo --- x86 MSI
+	candle Setup.wxs -nologo -out Temp\Setup32.wixobj -ext WixUIExtension -ext WixUtilExtension -dx64=0 -dARM64=0 -dCS_LANG_FOLDER=%CS_LANG_FOLDER% -dCS_LANG_NAME=%CS_LANG_NAME%
+	if ERRORLEVEL 1 exit /b 1
+
+	REM We need to suppress ICE38 and ICE43 because they apply only to per-user installation. We only support per-machine installs
+	REM We need to suppress ICE09 because the helper DLLs need to go into the system directory (for safety reasons)
+	light Temp\Setup32.wixobj -nologo -out Temp\Setup32.msi -ext WixUIExtension -ext WixUtilExtension -loc ..\Localization\%CS_LANG_FOLDER%\OpenShellText-%CS_LANG_NAME%.wxl -loc ..\Localization\%CS_LANG_FOLDER%\WixUI_%CS_LANG_NAME%.wxl -sice:ICE38 -sice:ICE43 -sice:ICE09
+	if ERRORLEVEL 1 exit /b 1
+
+	REM ********* Build x64 MSI
+	echo --- x64 MSI
+	candle Setup.wxs -nologo -out Temp\Setup64.wixobj -ext WixUIExtension -ext WixUtilExtension -dx64=1 -dARM64=0 -dCS_LANG_FOLDER=%CS_LANG_FOLDER% -dCS_LANG_NAME=%CS_LANG_NAME%
+	if ERRORLEVEL 1 exit /b 1
+
+	REM We need to suppress ICE38 and ICE43 because they apply only to per-user installation. We only support per-machine installs
+	REM We need to suppress ICE09 because the helper DLLs need to go into the system directory (for safety reasons)
+	light Temp\Setup64.wixobj -nologo -out Temp\Setup64.msi -ext WixUIExtension -ext WixUtilExtension -loc ..\Localization\%CS_LANG_FOLDER%\OpenShellText-%CS_LANG_NAME%.wxl -loc ..\Localization\%CS_LANG_FOLDER%\WixUI_%CS_LANG_NAME%.wxl -sice:ICE38 -sice:ICE43 -sice:ICE09
+	if ERRORLEVEL 1 exit /b 1
+)
 
 REM ********* Build MSI Checksums
 echo --- MSI Checksums
-Utility\Release\Utility.exe crcmsi Temp
+if %ARCH%==ARM64 (
+	Utility\Release\Utility.exe crcarm64msi Temp
+) else (
+	Utility\Release\Utility.exe crcmsi Temp
+)
 @if ERRORLEVEL 1 exit /b 1
 
 REM ********* Build bootstrapper
 echo --- Bootstrapper
 for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -requires Microsoft.Component.MSBuild -property installationPath`) do set MSBuildDir=%%i\MSBuild\Current\Bin\
 
-"%MSBuildDir%MSBuild.exe" Setup.sln /m /t:Rebuild /p:Configuration="Release" /p:Platform="Win32" /verbosity:quiet /nologo
+"%MSBuildDir%MSBuild.exe" Setup.sln /m /t:Rebuild /p:Configuration="Release" /p:Platform="%CS_SETUP_ARCH%" /verbosity:quiet /nologo
 @if ERRORLEVEL 1 exit /b 1
 
-if exist Final rd /Q /S Final
-md Final
+if exist Final\%CS_INSTALLER_NAME%.exe del Final\%CS_INSTALLER_NAME%.exe > nul
+md Final 1> nul 2>&1
 
-copy /B Release\Setup.exe Final\%CS_INSTALLER_NAME%.exe > nul
+copy /B %CS_SETUP_DIR%\Setup.exe Final\%CS_INSTALLER_NAME%.exe > nul
 
 if defined APPVEYOR (
-	appveyor PushArtifact Release\Setup.exe -FileName %CS_INSTALLER_NAME%.exe
+	appveyor PushArtifact %CS_SETUP_DIR%\Setup.exe -FileName %CS_INSTALLER_NAME%.exe
 )
 
 SET CS_LANG_FOLDER=
diff --git a/Src/Setup/Setup.cpp b/Src/Setup/Setup.cpp
index 412916f28..baa167702 100644
--- a/Src/Setup/Setup.cpp
+++ b/Src/Setup/Setup.cpp
@@ -12,7 +12,7 @@
 #include "StringUtils.h"
 #include "FNVHash.h"
 
-// Setup.exe is a bootstrap application that contains installers for x86, x64 and ARM64.
+// Setup.exe is a bootstrap application that contains installers for x86 and x64 or ARM64.
 // It unpacks the right installer into the temp directory and executes it.
 
 typedef BOOL (WINAPI *FIsWow64Process)( HANDLE hProcess, PBOOL Wow64Process );
@@ -81,13 +81,13 @@ static int ExtractMsi( HINSTANCE hInstance, const wchar_t *msiName, ExtractType
 		}
 		return ERR_HASH_NOTFOUND;
 	}
-	unsigned int hash0=((unsigned int*)pRes)[extractType==ARM64?2:extractType==x64?1:0];
+	unsigned int hash0=((unsigned int*)pRes)[extractType==x64?1:0];
 	const Chunk *pChunks=NULL;
 	int chunkCount=0;
 	if (extractType==x64)
 	{
-		chunkCount=((unsigned int*)pRes)[3];
-		pChunks=(Chunk*)((unsigned int*)pRes+4);
+		chunkCount=((unsigned int*)pRes)[2];
+		pChunks=(Chunk*)((unsigned int*)pRes+3);
 	}
 
 	// extract the installer
@@ -98,7 +98,7 @@ static int ExtractMsi( HINSTANCE hInstance, const wchar_t *msiName, ExtractType
 		HGLOBAL hRes=LoadResource(hInstance,hResInfo);
 		pRes32=(unsigned char*)LockResource(hRes);
 	}
-	if (!pRes32)
+	if (!pRes32 && extractType!=ARM64)
 	{
 		if (!bQuiet)
 		{
@@ -340,9 +340,10 @@ int APIENTRY wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCm
 
 	// Use IsWow64Process2 if it's available (Windows 10 1511+), otherwise fall back to IsWow64Process
 	FIsWow64Process2 isWow64Process2=(FIsWow64Process2)GetProcAddress(hKernel32,"IsWow64Process2");
+	USHORT processMachine = 0;
 	if (isWow64Process2)
 	{
-		USHORT processMachine = 0, nativeMachine = 0;
+		USHORT nativeMachine = 0;
 		isWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine);
 		extractType=nativeMachine==IMAGE_FILE_MACHINE_AMD64?x64:nativeMachine==IMAGE_FILE_MACHINE_ARM64?ARM64:x86;
 	}
@@ -373,7 +374,7 @@ int APIENTRY wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCm
 
 	// On ARM64 we must launch msiexec.exe from system32 and not syswow64 as would otherwise happen
 	PVOID wow64FsRedirVal=NULL;
-	if (extractType == ARM64)
+	if (extractType == ARM64 && processMachine != IMAGE_FILE_MACHINE_ARM64)
 		Wow64DisableWow64FsRedirection(&wow64FsRedirVal);
 
 	// start the installer
@@ -381,7 +382,7 @@ int APIENTRY wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCm
 	PROCESS_INFORMATION processInfo;
 	memset(&processInfo,0,sizeof(processInfo));
 	BOOL ret=CreateProcess(NULL,cmdLine,NULL,NULL,TRUE,0,NULL,NULL,&startupInfo,&processInfo);
-	if (extractType == ARM64)
+	if (extractType == ARM64 && processMachine != IMAGE_FILE_MACHINE_ARM64)
 		Wow64RevertWow64FsRedirection(wow64FsRedirVal);
 	if (!ret)
 	{
diff --git a/Src/Setup/Setup.rc b/Src/Setup/Setup.rc
index 339a63efc..99e7e8da7 100644
--- a/Src/Setup/Setup.rc
+++ b/Src/Setup/Setup.rc
@@ -100,9 +100,12 @@ END
 // MSI_FILE
 //
 
+#if defined(_M_AMD64) || defined(_M_IX86)
 IDR_MSI_FILE32          MSI_FILE                "Temp\\Setup32.msi_"
 IDR_MSI_FILE64          MSI_FILE                "Temp\\Setup64.msi_"
+#elif defined(_M_ARM64)
 IDR_MSI_FILEARM64       MSI_FILE                "Temp\\SetupARM64.msi_"
+#endif
 IDR_MSI_CHECKSUM        MSI_FILE                "msichecksum.bin"
 
 
diff --git a/Src/Setup/Setup.sln b/Src/Setup/Setup.sln
index e805f6e7d..c25994faa 100644
--- a/Src/Setup/Setup.sln
+++ b/Src/Setup/Setup.sln
@@ -1,7 +1,7 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27130.2010
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31005.135
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Setup", "Setup.vcxproj", "{A4A4D3B1-24E7-401E-A37C-72141D7603DC}"
 EndProject
@@ -9,22 +9,32 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Lib", "..\Lib\Lib.vcxproj",
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM64 = Debug|ARM64
 		Debug|Win32 = Debug|Win32
 		Debug|x64 = Debug|x64
+		Release|ARM64 = Release|ARM64
 		Release|Win32 = Release|Win32
 		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Debug|ARM64.ActiveCfg = Debug|ARM64
+		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Debug|ARM64.Build.0 = Debug|ARM64
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Debug|Win32.ActiveCfg = Debug|Win32
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Debug|Win32.Build.0 = Debug|Win32
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Debug|x64.ActiveCfg = Debug|Win32
+		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Release|ARM64.ActiveCfg = Release|ARM64
+		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Release|ARM64.Build.0 = Release|ARM64
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Release|Win32.ActiveCfg = Release|Win32
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Release|Win32.Build.0 = Release|Win32
 		{A4A4D3B1-24E7-401E-A37C-72141D7603DC}.Release|x64.ActiveCfg = Release|Win32
+		{D42FE717-485B-492D-884A-1999F6D51154}.Debug|ARM64.ActiveCfg = Debug|ARM64
+		{D42FE717-485B-492D-884A-1999F6D51154}.Debug|ARM64.Build.0 = Debug|ARM64
 		{D42FE717-485B-492D-884A-1999F6D51154}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D42FE717-485B-492D-884A-1999F6D51154}.Debug|Win32.Build.0 = Debug|Win32
 		{D42FE717-485B-492D-884A-1999F6D51154}.Debug|x64.ActiveCfg = Debug|x64
 		{D42FE717-485B-492D-884A-1999F6D51154}.Debug|x64.Build.0 = Debug|x64
+		{D42FE717-485B-492D-884A-1999F6D51154}.Release|ARM64.ActiveCfg = Release|ARM64
+		{D42FE717-485B-492D-884A-1999F6D51154}.Release|ARM64.Build.0 = Release|ARM64
 		{D42FE717-485B-492D-884A-1999F6D51154}.Release|Win32.ActiveCfg = Release|Win32
 		{D42FE717-485B-492D-884A-1999F6D51154}.Release|Win32.Build.0 = Release|Win32
 		{D42FE717-485B-492D-884A-1999F6D51154}.Release|x64.ActiveCfg = Release|x64
diff --git a/Src/Setup/Setup.vcxproj b/Src/Setup/Setup.vcxproj
index cc39c92e8..f04530b66 100644
--- a/Src/Setup/Setup.vcxproj
+++ b/Src/Setup/Setup.vcxproj
@@ -1,10 +1,18 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|ARM64">
+      <Configuration>Debug</Configuration>
+      <Platform>ARM64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Debug|Win32">
       <Configuration>Debug</Configuration>
       <Platform>Win32</Platform>
     </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|ARM64">
+      <Configuration>Release</Configuration>
+      <Platform>ARM64</Platform>
+    </ProjectConfiguration>
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
@@ -23,11 +31,22 @@
     <CharacterSet>Unicode</CharacterSet>
     <WholeProgramOptimization>true</WholeProgramOptimization>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
     <ConfigurationType>Application</ConfigurationType>
     <PlatformToolset>v142</PlatformToolset>
     <CharacterSet>Unicode</CharacterSet>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v142</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
   </ImportGroup>
@@ -35,21 +54,39 @@
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="..\Version.props" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\Version.props" />
+  </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
     <Import Project="..\Version.props" />
   </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="..\Version.props" />
+  </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <OutDir>$(Configuration)\</OutDir>
     <IntDir>$(Configuration)\</IntDir>
     <LinkIncremental>true</LinkIncremental>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(Configuration)ARM64\</OutDir>
+    <IntDir>$(Configuration)ARM64\</IntDir>
+  </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <OutDir>$(Configuration)\</OutDir>
     <IntDir>$(Configuration)\</IntDir>
     <LinkIncremental>false</LinkIncremental>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(Configuration)ARM64\</OutDir>
+    <IntDir>$(Configuration)ARM64\</IntDir>
+  </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
       <Optimization>Disabled</Optimization>
@@ -65,7 +102,30 @@
       <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <ResourceCompile>
-      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_M_IX86=1;_X86_=1;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>comctl32.lib;Psapi.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <ConformanceMode>true</ConformanceMode>
+      <LanguageStandard>stdcpp17</LanguageStandard>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_M_ARM64=1;_ARM64_=1;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
     <Link>
       <AdditionalDependencies>comctl32.lib;Psapi.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -88,7 +148,32 @@
       <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <ResourceCompile>
-      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>_M_IX86=1;_X86_=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>comctl32.lib;Psapi.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <AdditionalIncludeDirectories>..\Lib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <MultiProcessorCompilation>true</MultiProcessorCompilation>
+      <ConformanceMode>true</ConformanceMode>
+      <LanguageStandard>stdcpp17</LanguageStandard>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_M_ARM64=1;_ARM64_=1;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
     </ResourceCompile>
     <Link>
       <AdditionalDependencies>comctl32.lib;Psapi.lib;version.lib;%(AdditionalDependencies)</AdditionalDependencies>
@@ -122,9 +207,18 @@
     <None Include="BuildInstaller.bat" />
     <None Include="Setup.wxs" />
     <None Include="msichecksum.bin" />
-    <None Include="Temp\Setup32.msi_" />
-    <None Include="Temp\Setup64.msi_" />
-    <None Include="Temp\SetupARM64.msi_" />
+    <None Include="Temp\Setup32.msi_">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
+    </None>
+    <None Include="Temp\Setup64.msi_">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
+    </None>
+    <None Include="Temp\SetupARM64.msi_">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </None>
     <None Include="__MakeFinal.bat" />
   </ItemGroup>
   <ItemGroup>
diff --git a/Src/Setup/Utility/Utility.cpp b/Src/Setup/Utility/Utility.cpp
index 0d2cd60a6..07e438cac 100644
--- a/Src/Setup/Utility/Utility.cpp
+++ b/Src/Setup/Utility/Utility.cpp
@@ -79,7 +79,7 @@ struct Chunk
 	int start1, start2, len;
 };
 
-int CalcMsiChecksum( wchar_t *const *params, int count )
+int CalcMsiChecksum( wchar_t *const *params, int count, bool bArm64 )
 {
 	if (count<2) return 2;
 
@@ -87,8 +87,11 @@ int CalcMsiChecksum( wchar_t *const *params, int count )
 
 	// load files
 	wchar_t path1[_MAX_PATH];
-	std::vector<unsigned char> buf1, buf2, buf3;
-	Sprintf(path1,_countof(path1),L"%s\\Setup32.msi",params[1]);
+	std::vector<unsigned char> buf1, buf2;
+	if (!bArm64)
+		Sprintf(path1,_countof(path1),L"%s\\Setup32.msi",params[1]);
+	else
+		Sprintf(path1,_countof(path1),L"%s\\SetupARM64.msi",params[1]);
 	LoadFile(path1,buf1);
 	if (buf1.empty())
 	{
@@ -96,66 +99,61 @@ int CalcMsiChecksum( wchar_t *const *params, int count )
 		return 1;
 	}
 	wchar_t path2[_MAX_PATH];
-	Sprintf(path2,_countof(path2),L"%s\\Setup64.msi",params[1]);
-	LoadFile(path2,buf2);
-	if (buf2.empty())
-	{
-		Printf("Failed to open file %s\n",path2);
-		return 1;
-	}
-	wchar_t path3[_MAX_PATH];
-	Sprintf(path3,_countof(path3),L"%s\\SetupARM64.msi",params[1]);
-	LoadFile(path3,buf3);
-	if (buf3.empty())
+	if (!bArm64)
 	{
-		Printf("Failed to open file %s\n",path2);
-		return 1;
+		Sprintf(path2,_countof(path2),L"%s\\Setup64.msi",params[1]);
+		LoadFile(path2,buf2);
+		if (buf2.empty())
+		{
+			Printf("Failed to open file %s\n",path2);
+			return 1;
+		}
 	}
 
 	int len1=(int)buf1.size();
 	int len2=(int)buf2.size();
-	int len3=(int)buf3.size();
 
 	for (std::vector<unsigned char>::iterator it=buf1.begin();it!=buf1.end();++it)
 		*it^=0xFF;
 	for (std::vector<unsigned char>::iterator it=buf2.begin();it!=buf2.end();++it)
 		*it^=0xFF;
-	for (std::vector<unsigned char>::iterator it=buf3.begin();it!=buf3.end();++it)
-		*it^=0xFF;
 
-	// detect common blocks (assuming at least 256K in size and in the same order in both files)
-	const int BLOCK_SIZE=256*1024;
+	// detect x86/x64 common blocks (assuming at least 256K in size and in the same order in both files)
 	std::vector<Chunk> chunks;
-	int start2=0;
-	for (int i=0;i<len1-BLOCK_SIZE;i+=BLOCK_SIZE)
+	if (!bArm64)
 	{
-		for (int j=start2;j<len2-BLOCK_SIZE;j++)
+		const int BLOCK_SIZE=256*1024;	
+		int start2=0;
+		for (int i=0;i<len1-BLOCK_SIZE;i+=BLOCK_SIZE)
 		{
-			if (memcmp(&buf1[i],&buf2[j],BLOCK_SIZE)==0)
+			for (int j=start2;j<len2-BLOCK_SIZE;j++)
 			{
-				Chunk chunk;
-				chunk.start1=i;
-				chunk.start2=j;
-				chunk.len=BLOCK_SIZE;
-				while (chunk.start1>0 && chunk.start2>0 && buf1[chunk.start1-1]==buf2[chunk.start2-1])
-				{
-					chunk.start1--;
-					chunk.start2--;
-					chunk.len++;
-				}
-				while (chunk.start1+chunk.len<len1 && chunk.start2+chunk.len<len2 && buf1[chunk.start1+chunk.len]==buf2[chunk.start2+chunk.len])
+				if (memcmp(&buf1[i],&buf2[j],BLOCK_SIZE)==0)
 				{
-					chunk.len++;
+					Chunk chunk;
+					chunk.start1=i;
+					chunk.start2=j;
+					chunk.len=BLOCK_SIZE;
+					while (chunk.start1>0 && chunk.start2>0 && buf1[chunk.start1-1]==buf2[chunk.start2-1])
+					{
+						chunk.start1--;
+						chunk.start2--;
+						chunk.len++;
+					}
+					while (chunk.start1+chunk.len<len1 && chunk.start2+chunk.len<len2 && buf1[chunk.start1+chunk.len]==buf2[chunk.start2+chunk.len])
+					{
+						chunk.len++;
+					}
+					chunks.push_back(chunk);
+					i=chunk.start1+chunk.len-1;
+					start2=chunk.start2+chunk.len;
+					break;
 				}
-				chunks.push_back(chunk);
-				i=chunk.start1+chunk.len-1;
-				start2=chunk.start2+chunk.len;
-				break;
 			}
 		}
 	}
 
-	// save modified 32-bit MSI
+	// save modified x86 or ARM64 MSI
 	{
 		Strcat(path1,_countof(path1),L"_");
 		FILE *f=NULL;
@@ -169,6 +167,7 @@ int CalcMsiChecksum( wchar_t *const *params, int count )
 	}
 
 	// save modified 64-bit MSI
+	if (!bArm64)
 	{
 		Strcat(path2,_countof(path2),L"_");
 		FILE *f=NULL;
@@ -189,23 +188,9 @@ int CalcMsiChecksum( wchar_t *const *params, int count )
 		fclose(f);
 	}
 
-	// save ARM64 MSI
-	{
-		Strcat(path3,_countof(path3),L"_");
-		FILE *f=NULL;
-		if (_wfopen_s(&f,path3,L"wb") || !f)
-		{
-			Printf("Failed to write %s\n",path3);
-			return 1;
-		}
-		fwrite(&buf3[0],1,len3,f);
-		fclose(f);
-	}
-
-	unsigned int fnvs[3];
+	unsigned int fnvs[2];
 	fnvs[0]=CalcFNVHash(&buf1[0],len1,FNV_HASH0);
-	fnvs[1]=CalcFNVHash(&buf2[0],len2,FNV_HASH0);
-	fnvs[2]=CalcFNVHash(&buf3[0],len3,FNV_HASH0);
+	fnvs[1]=bArm64?0:CalcFNVHash(&buf2[0],len2,FNV_HASH0);
 
 	// save fnvs and chunks
 	{
@@ -1117,7 +1102,8 @@ static HRESULT CALLBACK TaskDialogCallback( HWND hwnd, UINT uNotification, WPARA
 // Open-Shell utility - multiple utilities for building and maintaining Open-Shell
 // Usage:
 //   no parameters - saves a troubleshooting log
-//   crcmsi <msi path> // creates a file with checksum of all three msi files
+//   crcmsi <msi path> // creates a file with checksum of the x86 and x64 msi files
+//   crcarm64msi <msi path> // creates a file with checksum of the ARM64 msi file
 //   makeEN <explorer dll> <start menu dll> <ie dll> <update exe> // extracts the localization resources and creates a sample en-US.DLL
 //   extract <dll> <csv> // extracts the string table, the dialog text, and the L10N text from a DLL and stores it in a CSV
 //   extract en-us.dll <dll> <csv> // extracts the string table, the dialog text, and the L10N text from two DLL and stores it in a CSV
@@ -1183,7 +1169,12 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpstrC
 #ifndef _WIN64
 	if (_wcsicmp(params[0],L"crcmsi")==0)
 	{
-		return CalcMsiChecksum(params,count);
+		return CalcMsiChecksum(params,count,false);
+	}
+
+	if (_wcsicmp(params[0],L"crcarm64msi")==0)
+	{
+		return CalcMsiChecksum(params,count,true);
 	}
 
 	if (_wcsicmp(params[0],L"makeEN")==0)
diff --git a/Src/Setup/__MakeFinal.bat b/Src/Setup/__MakeFinal.bat
index d1b1ebbf3..62078f85a 100644
--- a/Src/Setup/__MakeFinal.bat
+++ b/Src/Setup/__MakeFinal.bat
@@ -1,5 +1,12 @@
 @echo off
-set PATH=C:\Program Files\7-Zip\;C:\Program Files (x86)\HTML Help Workshop;C:\Program Files (x86)\WiX Toolset v3.14\bin\;%PATH%
+
+rem Default to x86/x64 unless we are building for ARM64
+set ARCH=%1
+if "%ARCH%"=="" set ARCH=x86_x64
+
+rem WiX toolset 3.14 is required for ARM64
+set PATH=C:\Program Files\7-Zip;C:\Program Files (x86)\HTML Help Workshop;C:\Program Files (x86)\WiX Toolset v3.7\bin;%PATH%
+if %ARCH%==ARM64 set PATH=C:\Program Files (x86)\WiX Toolset v3.14\bin;%PATH%
 
 cd %~dp0
 
diff --git a/Src/Setup/__MakeFinalARM64.bat b/Src/Setup/__MakeFinalARM64.bat
new file mode 100644
index 000000000..e2bd17c3f
--- /dev/null
+++ b/Src/Setup/__MakeFinalARM64.bat
@@ -0,0 +1,7 @@
+@echo off
+cd %~dp0
+
+call __MakeFinal.bat ARM64
+if ERRORLEVEL 1 exit /b 1
+
+exit /b 0
diff --git a/Src/Setup/__MakeFinalAllLanguages.bat b/Src/Setup/__MakeFinalAllLanguages.bat
index ad73e7a04..213e751bd 100644
--- a/Src/Setup/__MakeFinalAllLanguages.bat
+++ b/Src/Setup/__MakeFinalAllLanguages.bat
@@ -1,7 +1,13 @@
 @echo off
 rem This file is to create all the files required for a new release to publish
 
-set PATH=C:\Program Files\7-Zip\;C:\Program Files (x86)\HTML Help Workshop;C:\Program Files (x86)\WiX Toolset v3.11\bin\;%PATH%
+rem Default to x86/x64 unless we are building for ARM64
+set ARCH=%1
+if "%ARCH%"=="" set ARCH=x86_x64
+
+rem WiX toolset 3.14 is required for ARM64
+set PATH=C:\Program Files\7-Zip;C:\Program Files (x86)\HTML Help Workshop;C:\Program Files (x86)\WiX Toolset v3.11\bin;%PATH%
+if %ARCH%==ARM64 set PATH=C:\Program Files (x86)\WiX Toolset v3.14\bin;%PATH%
 
 cd %~dp0
 
diff --git a/Src/Setup/__MakeFinalAllLanguagesARM64.bat b/Src/Setup/__MakeFinalAllLanguagesARM64.bat
new file mode 100644
index 000000000..472c4c778
--- /dev/null
+++ b/Src/Setup/__MakeFinalAllLanguagesARM64.bat
@@ -0,0 +1,7 @@
+@echo off
+cd %~dp0
+
+call __MakeFinalAllLanguages.bat ARM64
+if ERRORLEVEL 1 exit /b 1
+
+exit /b 0