diff --git a/.gitignore b/.gitignore index 1b84bcee17..77c9c744e2 100644 --- a/.gitignore +++ b/.gitignore @@ -16,8 +16,7 @@ ui_*.h moc_predefs.h src/res/qrc_resources.cpp windows/ASIOSDK2 -windows/VC_redist.x64.exe -windows/vc_redist.x86.exe +windows/NSIS debug/ release/ build/ diff --git a/.travis.yml b/.travis.yml index b403dd389c..d60f7c082e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,37 +44,25 @@ matrix: # on: # repo: corrados/jamulus # tags: true - # - os: windows - # before_install: - # - dir C:/Program\ Files\ \(x86\)/Windows\ Kits/10/bin/10.0.17134.0/x64 - # - cmd.exe /C 'cd && "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" - # x86 && cd && cd "C:/Users/travis/build/corrados/jamulus/windows" && dir' - # - curl -vLO http://download.qt.io/official_releases/online_installers/qt-unified-windows-x86-online.exe - # - curl -vLO http://www.steinberg.net/sdk_downloads/ASIOSDK2.3.2.zip - # - unzip ASIOSDK2.3.2.zip - # - mkdir ASIOSDK2 - # - cp -rvu ASIOSDK2.3.2/* ASIOSDK2 - # - pwd - # - mv qt-unified-windows-x86-online.exe windows - # - mv ASIOSDK2 windows - # - cd windows - # - "./qt-unified-windows-x86-online.exe --verbose --script qt-installer-windows.qs" - # - ls -la C:/Qt/5.12.3/msvc2017/bin/qtenv2.bat - # script: - # - cmd.exe /C 'cd && "C:\Qt\5.12.3\msvc2017\bin\qtenv2.bat" && cd && "C:\Program - # Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" - # x86 && cd "C:\Users\travis\build\corrados\jamulus" && cd && qmake Jamulus.pro - # && nmake' - # #deploy function is only available in travis-ci.com (not free) but not in travis-ci.org (free) - # #deploy: - # # provider: releases - # # api_key: - # # secure: aQ93/8XU3HEGTif0/rSiF+gcm4uRhyWFdr3Va50BprwQOrZkNg8zIMwIKKODwjLDqxaH4msgNYutcr/VLdLjo4YP43It0UIfv3LGa2VFAkFhuQurMXZlVyx8RhIGLjIaWVWN1GCbNdAQwWNNo2mAkEdRaBrj/26geZotGcYZiztGwTAdy0t/vyYjO1sLZdBKcf7dJ06Pm2ktZO/rDyE4UtCTQiRfqLCKsQ/SILbewOMG/auaSUdU0utsbvXxr+dCzqBPwdSSptWqhIORXORL5oPn6242URzIJkmw5XPwhSabhdbzUjCIN9E24z1vp+cffAohuGXyXXZy9/bGeKa0mXfAaXV+TnJkpMd+i3fN5dY+vhFrlLOpRojRK6NqvaMID6tcNNtZMmFSgaZGyCUJQn4/0X+LdPwvK3/dXY+qElJW62QiJmQAt9OBGcq8EFqQDmEtRivRlbpbERsd/IJoOxP7nI2T00g04uV543ZmhU4fmGw6MVPAlIGRsBECjB0AMTp+3xW3OaUp7jy3WZpZXRrXNI41nZogrxhevPME1BRNk3V+MWQo8R3C+bIaCa5Um/3DZxnMxZgXjI9yzzR7Z8f4RWaQCKjXx41/pk7jxm1TcEyBfRVsb313l/fRLg+fjCmaEnnxu43333XGIv4eIyAGDR8ydF2VpmyP2ejzh8I= - # # file: - # # - Jamulus.exe - # # skip_cleanup: true - # # on: - # # repo: corrados/jamulus - # # tags: true - + - os: windows + env: + # QT_ACCOUNT_USERNAME and QT_ACCOUNT_PASSWORD variables for Qt registration at install time + - secure: WlWyUMU53vGPwZ340bZZy3PVJJfuFZ8gegyLHGYXo1Hp++BCtHJ5FH2kVYxW0pUNqKobkrlGdNMLrhfDD5qATj6TqbRTQr/XKqK5Qhe8sf7Ag/Z+AUjguED7QL0th2Ll6eBlSc9ayrQfvCjvzmyFXGB85iXvuJlbqUCya6xRyiflq37KimLGjxFOhUkCGsIgraUxUxGm/dLj07x2gH1XeozzSOhX/4uDwlP+y642zWyWf/pOrUTSuid97TJseD9tAmLqFpVo43BqDuCe1/7OmBnZkJQb4obU43KeRAHLUCSnbI+kVVNfW8j0/1ynObngIZoC+KQnvc+4NTU13yRez8HoFcEXa9l9oTRBu+nFu+TM+c8+EBNKDZxrdF2NYLRuNdYIzVqZsbSIT+8aoAwMS+bO9AgW2KCelz7zCSoPRokfM2vH7JPEq7Ofib8neK4MEzAKYL1K0/vDlZktsxX8xIhrzgJQCF8IloMLPR3sKIOckYjBzsQG9Q6QJqC6BKJJSpeN6I6LF6cksSMcUalhsqgCghrLFHalJj0mhkSQGTvXtDr3OOfPSicj1fC3efqjiZ9uT6b5yR2gC9e4NaC0qLcqLuHJL10CUjn2eizKBqr0Onu/ybkkClfBUFzu3uOf8YMq3I1hp4xzkfEPAb1A2Iem6rYA9ndyGUnXrYNoLRs= + - secure: ldDKzVJFDbA1+tJg4jicBTUAzm83mjybEY2hvPxMofE2gBNwAFRj2+XJD5H1tQ/BBE3LADOVRiwiCxZZLSotIChmmrtQJ68tshYTwcpjf+VQ3m59NsHl0xbjP3/B9DYu1zBOhUc43gGsDnRulvzDi8HwbxrM4ACNCepy+zq+a8M7BytddrhZSgIT0rsTBU0t/StH7B/Pu6E6KByelgdmbnZbuAqaT2HMi+IiGrAJiw70Hmq4BgegsEv4kLyNLe2ofZsdvmFw20Gumfg9B4PFM2S0QESj2pPwFgz+uYUgS/0ncpGdFTshnDKPFj7ePgrHT8eM9bMC8BM8RedpoR0vSUyioCxx0YJzSsw8JE8DEe3qNt3HmhPcH678wrYxs3cXLoTC8kBGDPD6drzqBIvILVfPJcaXRJlD7I+GOIkXFojLrxDZRy9I73KbWHGRONLguGBVyqJxGVrPH6hjEAxhgLLMUAnoh61wPFtvnayT+SbWl2NbAewnsjfCNnLgBZOxdmlKMjC5yUH3wnnyBn5jEAHcjrtbSfQ+lD+ZlYmeuimgsvjomHOHKw3N2+tfKW9lAH45ShiiMIMOk9HP9zKnDnyG6hI0q9wPFxWrkc3RZpRmQO1S9QjB2gD3cWiVMNTBYI+XNOqZEUicTc4XwOByf8bm5SyH4H1+8o1RytgbEZY= + before_install: + - curl -vL -o "${TEMP}/qt-installer.exe" http://download.qt.io/official_releases/online_installers/qt-unified-windows-x86-online.exe + - "${TEMP}/qt-installer.exe --verbose --script ./windows/qt-installer-windows.qs" + script: + - powershell -ExecutionPolicy ByPass -Command "./windows/deploy_windows.ps1" + #deploy function is only available in travis-ci.com (not free) but not in travis-ci.org (free) + #deploy: + # provider: releases + # api_key: + # secure: aQ93/8XU3HEGTif0/rSiF+gcm4uRhyWFdr3Va50BprwQOrZkNg8zIMwIKKODwjLDqxaH4msgNYutcr/VLdLjo4YP43It0UIfv3LGa2VFAkFhuQurMXZlVyx8RhIGLjIaWVWN1GCbNdAQwWNNo2mAkEdRaBrj/26geZotGcYZiztGwTAdy0t/vyYjO1sLZdBKcf7dJ06Pm2ktZO/rDyE4UtCTQiRfqLCKsQ/SILbewOMG/auaSUdU0utsbvXxr+dCzqBPwdSSptWqhIORXORL5oPn6242URzIJkmw5XPwhSabhdbzUjCIN9E24z1vp+cffAohuGXyXXZy9/bGeKa0mXfAaXV+TnJkpMd+i3fN5dY+vhFrlLOpRojRK6NqvaMID6tcNNtZMmFSgaZGyCUJQn4/0X+LdPwvK3/dXY+qElJW62QiJmQAt9OBGcq8EFqQDmEtRivRlbpbERsd/IJoOxP7nI2T00g04uV543ZmhU4fmGw6MVPAlIGRsBECjB0AMTp+3xW3OaUp7jy3WZpZXRrXNI41nZogrxhevPME1BRNk3V+MWQo8R3C+bIaCa5Um/3DZxnMxZgXjI9yzzR7Z8f4RWaQCKjXx41/pk7jxm1TcEyBfRVsb313l/fRLg+fjCmaEnnxu43333XGIv4eIyAGDR8ydF2VpmyP2ejzh8I= + # file: + # - Jamulus.exe + # skip_cleanup: true + # on: + # repo: corrados/jamulus + # tags: true diff --git a/windows/FindProcDLL.dll b/windows/FindProcDLL.dll deleted file mode 100644 index 790c227969..0000000000 Binary files a/windows/FindProcDLL.dll and /dev/null differ diff --git a/windows/deploy_windows.bat b/windows/deploy_windows.bat deleted file mode 100755 index 16c315622f..0000000000 --- a/windows/deploy_windows.bat +++ /dev/null @@ -1,72 +0,0 @@ -@echo off - -rem To set up a new Qt and Visual Studio version -rem - set environment path variable to the correct Qt bin directories: -rem - QTDIR32: points to the Qt 32 bit binaries, e.g., C:\Qt\5.10.1\msvc2015 -rem - QTDIR64: points to the Qt 64 bin binaries, e.g., C:\Qt\5.10.1\msvc2015_64 -rem - if using Visual Studio Express version, download the redistributable (it is not automatically there) -rem - change the Qt distribute dll names in the installer.nsi file (some contain version numbers) - -rem settings and check --------------------------------------------------------- -set NSIS_PATH=%PROGRAMFILES(x86)%\NSIS -set VS_REDIST32_EXE=vc_redist.x86.exe -set VS_REDIST64_EXE=VC_redist.x64.exe - -if "%VSINSTALLDIR%" == "" goto vsenvproblem -if "%QTDIR32%" == "" goto qtdirproblem -if "%QTDIR64%" == "" goto qtdirproblem -cd .. - - -rem ########################## 32 bit build #################################### -set QTDIR=%QTDIR32% -set Path=%QTDIR32%\bin;%Path% -rem create visual studio project file ------------------------------------------ -qmake -tp vc -spec win32-msvc - -rem TODO qmake seems to use the incorrect VS version to create the project file. -rem As a quick hack I simply replace the toolset version which seems to work. -powershell -Command "(gc jamulus.vcxproj) -replace 'v141', 'v140' | Out-File -encoding ASCII jamulus.vcxproj" -powershell -Command "(gc jamulus.vcxproj) -replace 'x64', 'Win32' | Out-File -encoding ASCII jamulus.vcxproj" -powershell -Command "(gc jamulus.vcxproj) -replace ';WIN64', '' | Out-File -encoding ASCII jamulus.vcxproj" -powershell -Command "(gc jamulus.vcxproj) -replace '-DWIN64 ', '' | Out-File -encoding ASCII jamulus.vcxproj" - -rem clean and compile solution ------------------------------------------------- -devenv Jamulus.vcxproj /Clean "Release|x86" -devenv Jamulus.vcxproj /Build "Release|x86" -mkdir release\x86 -copy release\Jamulus.exe release\x86\ - - -rem ########################## 64 bit build #################################### -set QTDIR=%QTDIR64% -set Path=%QTDIR64%\bin;%Path% - -rem create visual studio project file ------------------------------------------ -qmake -tp vc - -rem TODO qmake seems to use the incorrect VS version to create the project file. -rem As a quick hack I simply replace the toolset version which seems to work. -powershell -Command "(gc jamulus.vcxproj) -replace 'v141', 'v140' | Out-File -encoding ASCII jamulus.vcxproj" - -rem clean and compile solution ------------------------------------------------- -devenv Jamulus.vcxproj /Clean "Release|x64" -devenv Jamulus.vcxproj /Build "Release|x64" - - -rem ########################## create installer ################################ -cd windows -"%NSIS_PATH%\makensis.exe" installer.nsi -move Jamulusinstaller.exe ../deploy/Jamulus-version-installer.exe -goto endofskript - - -:vsenvproblem -echo Use the Visual Studio x86 x64 Cross Tools Command Prompt to call this skript -goto endofskript - -:qtdirproblem -echo The QTDIR32 and QTDIR64 is not set, please set these environment variables correclty before calling this script -goto endofskript - -:endofskript diff --git a/windows/deploy_windows.ps1 b/windows/deploy_windows.ps1 new file mode 100644 index 0000000000..7b7bbdefa7 --- /dev/null +++ b/windows/deploy_windows.ps1 @@ -0,0 +1,209 @@ +param( + # Replace default path with system Qt installation folder if necessary + [string] $QtInstallPath = "C:\Qt\5.12.3" +) + +# Global constants +$RootPath = "$PWD" +$BuildPath = "$RootPath\build" +$DeployPath = "$RootPath\deploy" +$WindowsPath ="$RootPath\windows" +$AppName = "Jamulus" + +# Stop at all errors +$ErrorActionPreference = "Stop" + +# Execute native command with errorlevel handling +Function Execute-Native-Command { + Param( + [string] $Command, + [string[]] $Arguments + ) + + & "$Command" @Arguments + + if ($LastExitCode -Ne 0) + { + Throw "Native command $Command returned with exit code $LastExitCode" + } +} + +# Cleanup existing build folders +Function Clean-Build-Environment +{ + if (Test-Path -Path $BuildPath) { Remove-Item -Path $BuildPath -Recurse -Force } + if (Test-Path -Path $DeployPath) { Remove-Item -Path $DeployPath -Recurse -Force } + + New-Item -Path $BuildPath -ItemType Directory + New-Item -Path $DeployPath -ItemType Directory +} + +# Download and uncompress dependency in ZIP format +Function Install-Dependency +{ + param( + [Parameter(Mandatory=$true)] + [string] $Uri, + [Parameter(Mandatory=$true)] + [string] $Name, + [Parameter(Mandatory=$true)] + [string] $Destination + ) + + if (Test-Path -Path "$WindowsPath\$Destination") { return } + + $TempFileName = [System.IO.Path]::GetTempFileName() + ".zip" + Invoke-WebRequest -Uri $Uri -OutFile $TempFileName + Expand-Archive -Path $TempFileName -DestinationPath $Env:TEMP -Force + Move-Item -Path "$Env:TEMP\$Name" -Destination "$WindowsPath\$Destination" -Force + Remove-Item -Path $TempFileName -Force +} + +# Install VSSetup (Visual Studio detection), ASIO SDK and NSIS Installer +Function Install-Dependencies +{ + Install-PackageProvider -Name "Nuget" -Scope CurrentUser -Force + Install-Module -Name "VSSetup" -Scope CurrentUser -Force + Install-Dependency -Uri "http://www.steinberg.net/sdk_downloads/ASIOSDK2.3.2.zip" ` + -Name "ASIOSDK2.3.2" -Destination "ASIOSDK2" + Install-Dependency -Uri "https://netix.dl.sourceforge.net/project/nsis/NSIS%203/3.05/nsis-3.05.zip" ` + -Name "nsis-3.05" -Destination "NSIS" +} + +# Setup environment variables and build tool paths +Function Setup-Build-Environment +{ + param( + [Parameter(Mandatory=$true)] + [string] $QtInstallPath, + [Parameter(Mandatory=$true)] + [string] $BuildArch + ) + + # Look for Visual Studio/Build Tools 2017 or later (version 15.0 or above) + $VsInstallPath = Get-VSSetupInstance | ` + Select-VSSetupInstance -Product "*" -Version "15.0" -Latest | ` + Select-Object -ExpandProperty "InstallationPath" + + if ($VsInstallPath -Eq "") { $VsInstallPath = "" } + + if ($BuildArch -Eq "x86_64") + { + $VcVarsBin = "$VsInstallPath\VC\Auxiliary\build\vcvars64.bat" + $QtMsvcSpecPath = "$QtInstallPath\msvc2017_64\bin" + } + else + { + $VcVarsBin = "$VsInstallPath\VC\Auxiliary\build\vcvars32.bat" + $QtMsvcSpecPath = "$QtInstallPath\msvc2017\bin" + } + + # Setup Qt executables paths for later calls + Set-Item Env:QtQmakePath "$QtMsvcSpecPath\qmake.exe" + Set-Item Env:QtWinDeployPath "$QtMsvcSpecPath\windeployqt.exe" + + "" + "**********************************************************************" + "Using Visual Studio/Build Tools environment settings located at" + $VcVarsBin + "**********************************************************************" + "" + "**********************************************************************" + "Using Qt binaries for Visual C++ located at" + $QtMsvcSpecPath + "**********************************************************************" + "" + + if (-Not (Test-Path -Path $VcVarsBin)) + { + Throw "Microsoft Visual Studio ($BuildArch variant) is not installed. " + ` + "Please install Visual Studio 2017 or above it before running this script." + } + + if (-Not (Test-Path -Path $Env:QtQmakePath)) + { + Throw "The Qt binaries for Microsoft Visual C++ 2017 (msvc2017) could not be located. " + ` + "Please install Qt with support for MSVC 2017 before running this script," + ` + "then call this script with the Qt install location, for example C:\Qt\5.12.3" + } + + # Import environment variables set by vcvarsXX.bat into current scope + $EnvDump = [System.IO.Path]::GetTempFileName() + Execute-Native-Command -Command "cmd" ` + -Arguments ("/c", "`"$VcVarsBin`" && set > `"$EnvDump`"") + + foreach ($_ in Get-Content -Path $EnvDump) + { + if ($_ -Match "^([^=]+)=(.*)$") + { + Set-Item "Env:$($Matches[1])" $Matches[2] + } + } + + Remove-Item -Path $EnvDump -Force +} + +# Build Jamulus x86_64 and x86 +Function Build-App +{ + param( + [Parameter(Mandatory=$true)] + [string] $BuildConfig, + [Parameter(Mandatory=$true)] + [string] $BuildArch + ) + + Execute-Native-Command -Command "$Env:QtQmakePath" ` + -Arguments ("$RootPath\$AppName.pro", "CONFIG+=$BuildConfig $BuildArch", ` + "-o", "$BuildPath\Makefile") + + Set-Location -Path $BuildPath + Execute-Native-Command -Command "nmake" -Arguments ("$BuildConfig") + Execute-Native-Command -Command "$Env:QtWinDeployPath" ` + -Arguments ("--$BuildConfig", "--compiler-runtime", "--dir=$DeployPath\$BuildArch", + "$BuildPath\$BuildConfig\$AppName.exe") + + Move-Item -Path "$BuildPath\$BuildConfig\$AppName.exe" -Destination "$DeployPath\$BuildArch" -Force + Execute-Native-Command -Command "nmake" -Arguments ("clean") + Set-Location -Path $RootPath +} + +# Build and deploy Jamulus 64bit and 32bit variants +function Build-App-Variants +{ + param( + [Parameter(Mandatory=$true)] + [string] $QtInstallPath + ) + + foreach ($_ in ("x86_64", "x86")) + { + $OriginalEnv = Get-ChildItem Env: + Setup-Build-Environment -QtInstallPath $QtInstallPath -BuildArch $_ + Build-App -BuildConfig "release" -BuildArch $_ + $OriginalEnv | % { Set-Item "Env:$($_.Name)" $_.Value } + } +} + +# Build Windows installer +Function Build-Installer +{ + foreach ($_ in Get-Content -Path "$RootPath\$AppName.pro") + { + if ($_ -Match "^VERSION *= *(.*)$") + { + $AppVersion = $Matches[1] + break + } + } + + Execute-Native-Command -Command "$WindowsPath\NSIS\makensis" ` + -Arguments ("/v4", "/DAPP_NAME=$AppName", "/DAPP_VERSION=$AppVersion", ` + "/DROOT_PATH=$RootPath", "/DWINDOWS_PATH=$WindowsPath", "/DDEPLOY_PATH=$DeployPath", ` + "$WindowsPath\installer.nsi") +} + +Clean-Build-Environment +Install-Dependencies +Build-App-Variants -QtInstallPath $QtInstallPath +Build-Installer diff --git a/windows/installer-banner.bmp b/windows/installer-banner.bmp new file mode 100644 index 0000000000..3c3fc8f523 Binary files /dev/null and b/windows/installer-banner.bmp differ diff --git a/windows/installer-banner.xcf b/windows/installer-banner.xcf new file mode 100644 index 0000000000..9964e17d30 Binary files /dev/null and b/windows/installer-banner.xcf differ diff --git a/windows/installer-welcome.bmp b/windows/installer-welcome.bmp new file mode 100644 index 0000000000..53024738c0 Binary files /dev/null and b/windows/installer-welcome.bmp differ diff --git a/windows/installer.nsi b/windows/installer.nsi index 8f04714eea..06cfec108b 100755 --- a/windows/installer.nsi +++ b/windows/installer.nsi @@ -1,146 +1,290 @@ -; Jamulus NSIS installer script -!include LogicLib.nsh -!include x64.nsh +; Jamulus NSIS Installer with Modern User Interface -!define APP_NAME "Jamulus" -!define APP_EXE "Jamulus.exe" -!define AUTORUN_NAME "Jamulus server" -!define UNINSTALL_EXE "Uninstall.exe" -!define INSTALLER_NAME "Jamulusinstaller.exe" -!define BINARY_PATH "..\release\" -!define VS_REDIST_EXE "vc_redist.x86.exe" -!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" +; Includes +!include "x64.nsh" ; 64bit architecture support +!include "MUI2.nsh" ; Modern UI +!include "LogicLib.nsh" ; Logical operators +!include "Sections.nsh" ; Support for section selection + +; Compile-time definitions +!define VC_REDIST32_EXE "vc_redist.x86.exe" +!define VC_REDIST64_EXE "vc_redist.x64.exe" +!define APP_INSTALL_KEY "Software\${APP_NAME}" +!define APP_INSTALL_VALUE "InstallFolder" +!define AUTORUN_NAME "${APP_NAME} Server" !define AUTORUN_KEY "Software\Microsoft\Windows\CurrentVersion\Run" +!define APP_EXE "${APP_NAME}.exe" +!define UNINSTALL_EXE "Uninstall.exe" +!define APP_UNINSTALL_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" +; General +SetCompressor bzip2 ; Compression mode +Unicode true ; Support all languages via Unicode +RequestExecutionLevel admin ; Administrator privileges are required for installation -SetCompressor lzma -Name "${APP_NAME}" -Caption "${APP_NAME}" -OutFile "${INSTALLER_NAME}" -InstallDir "$PROGRAMFILES\${APP_NAME}" - -LicenseText "License" -LicenseData "..\COPYING" - -Page license -Page directory -Page instfiles - - -Section - - ; check if software is currently running - !addplugindir ..\windows - FindProcDLL::FindProc "${APP_EXE}" - IntCmp $R0 1 0 notRunning - MessageBox MB_OK|MB_ICONEXCLAMATION "${APP_NAME} is running. Please close it and run the setup again." /SD IDOK - Abort - notRunning: - - ; add reg keys so that software appears in Windows "Add/Remove Software" - WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${APP_NAME} (remove only)" - WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" '"$INSTDIR\${UNINSTALL_EXE}"' - - SetOutPath $INSTDIR - - ; main application - ${If} ${RunningX64} - File "${BINARY_PATH}${APP_EXE}" - ${Else} - File "${BINARY_PATH}x86\${APP_EXE}" - ${EndIf} - - ; QT dlls - ${If} ${RunningX64} - File "$%QTDIR64%\bin\Qt5Core.dll" - File "$%QTDIR64%\bin\Qt5Gui.dll" - File "$%QTDIR64%\bin\Qt5Widgets.dll" - File "$%QTDIR64%\bin\Qt5Network.dll" - File "$%QTDIR64%\bin\Qt5Xml.dll" - File "$%QTDIR64%\bin\D3DCompiler_47.dll" - File "$%QTDIR64%\bin\libEGL.dll" - File "$%QTDIR64%\bin\libGLESv2.dll" - ${Else} - File "$%QTDIR32%\bin\Qt5Core.dll" - File "$%QTDIR32%\bin\Qt5Gui.dll" - File "$%QTDIR32%\bin\Qt5Widgets.dll" - File "$%QTDIR32%\bin\Qt5Network.dll" - File "$%QTDIR32%\bin\Qt5Xml.dll" - File "$%QTDIR32%\bin\D3DCompiler_47.dll" - File "$%QTDIR32%\bin\libEGL.dll" - File "$%QTDIR32%\bin\libGLESv2.dll" - ${EndIf} - - ; other files - File "..\COPYING" - - ; temporarily create Microsoft Visual Studio redistributable - ${If} ${RunningX64} - File "$%VS_REDIST64_EXE%" - ExecWait '"$INSTDIR\$%VS_REDIST64_EXE%" /q /norestart' - ${Else} - File "$%VS_REDIST32_EXE%" - ExecWait '"$INSTDIR\$%VS_REDIST32_EXE%" /q /norestart' - ${EndIf} - - ; uninstaller - WriteUninstaller $INSTDIR\${UNINSTALL_EXE} - - ; shortcuts - CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$OUTDIR\${APP_EXE}" - - CreateDirectory "$SMPROGRAMS\${APP_NAME}" - CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\${APP_EXE}" - CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME} Server.lnk" "$INSTDIR\${APP_EXE}" "-s" - CreateShortCut "$SMPROGRAMS\${APP_NAME}\${UNINSTALL_EXE}.lnk" "$INSTDIR\${UNINSTALL_EXE}" - - ; cleanup: remove temporary Microsoft Visual Studio redistributable executable - ${If} ${RunningX64} - Delete $INSTDIR\$%VS_REDIST64_EXE% - ${Else} - Delete $INSTDIR\$%VS_REDIST32_EXE% - ${EndIf} - - ; additional platform dlls - SetOutPath $INSTDIR\platforms - ${If} ${RunningX64} - File "$%QTDIR64%\plugins\platforms\qwindows.dll" - File "$%QTDIR64%\plugins\platforms\qminimal.dll" - ${Else} - File "$%QTDIR32%\plugins\platforms\qwindows.dll" - File "$%QTDIR32%\plugins\platforms\qminimal.dll" - ${EndIf} +; Installer name and file +Name "${APP_NAME}" +OutFile "${DEPLOY_PATH}\${APP_NAME}-${APP_VERSION}-installer-win.exe" +Caption "${APP_NAME} ${APP_VERSION} Installer" +BrandingText "${APP_NAME} powers your online jam session" -SectionEnd + ; Additional plugin location (for nsProcess) +!addplugindir "${WINDOWS_PATH}" + +; Installer graphical element configuration +!define MUI_ICON "${WINDOWS_PATH}\mainicon.ico" +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_BITMAP "${WINDOWS_PATH}\installer-banner.bmp" +!define MUI_WELCOMEFINISHPAGE_BITMAP "${WINDOWS_PATH}\installer-welcome.bmp" +!define MUI_UNWELCOMEFINISHPAGE_BITMAP "${WINDOWS_PATH}\uninstaller-welcome.bmp" + +; Store the installer language - must be placed before the installer page configuration +!define MUI_LANGDLL_REGISTRY_ROOT HKLM +!define MUI_LANGDLL_REGISTRY_KEY "${APP_INSTALL_KEY}" +!define MUI_LANGDLL_REGISTRY_VALUENAME "InstallLanguage" + +; Installer page configuration +!define MUI_PAGE_CUSTOMFUNCTION_PRE AbortOnRunningApp +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "${ROOT_PATH}\COPYING" +!define MUI_PAGE_CUSTOMFUNCTION_LEAVE ValidateDestinationFolder +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!define MUI_FINISHPAGE_RUN "$INSTDIR\${APP_EXE}" +!insertmacro MUI_PAGE_FINISH + +; Uninstaller page configuration +!define MUI_PAGE_CUSTOMFUNCTION_PRE un.AbortOnRunningApp +!insertmacro MUI_UNPAGE_WELCOME +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES +!insertmacro MUI_UNPAGE_FINISH + +; Supported languages configuration - languages other than English are disabled for now +; Additional languages can be added below, see https://nsis.sourceforge.io/Examples/Modern%20UI/MultiLanguage.nsi +!insertmacro MUI_LANGUAGE "English" ; The first language is the default +; !insertmacro MUI_LANGUAGE "Italian" + +LangString INVALID_FOLDER_MSG ${LANG_ENGLISH} \ + "The destination folder already exists. Please enter a new destination folder." +; LangString INVALID_FOLDER_MSG ${LANG_ITALIAN} \ +; "La cartella di destinazione esiste già. Selezionare una nuova cartella di destinazione." + +LangString RUNNING_APP_MSG ${LANG_ENGLISH} \ + "${APP_NAME} is running. Please close it and run the setup again." +; LangString RUNNING_APP_MSG ${LANG_ITALIAN} \ +; "${APP_NAME} è in esecuzione. Chiudere l'applicazione prima di eseguire l'installazione." + +; Abort the installer/uninstaller if Jamulus is running +!macro _AbortOnRunningApp + + nsProcess::_FindProcess "${APP_EXE}" + Pop $R0 + + ${If} $R0 = 0 + MessageBox MB_OK|MB_ICONEXCLAMATION "$(RUNNING_APP_MSG)" /sd IDOK + Quit + ${EndIf} + +!macroend + + +; Installer +!macro InstallApplication buildArch + + !define prefix "${DEPLOY_PATH}\${buildArch}" + !tempfile files + + ; Find target folders + !system 'cmd.exe /v /c "for /f "usebackq" %d in (`dir /b /s /ad "${prefix}"`) do \ + @(set "_d=%d" && echo CreateDirectory "$INSTDIR\!_d:${prefix}\=!" >> "${files}")"' + + ; Find target files + !system 'cmd.exe /v /c "for /r "${prefix}" %f in (*.*) do \ + @(set "_f=%f" && echo File "/oname=$INSTDIR\!_f:${prefix}\=!" "!_f!" >> "${files}")"' + + ; Install folders and files + CreateDirectory "$INSTDIR" + !include "${files}" + + ; Add the redistribution license + File "/oname=$INSTDIR\COPYING" "${ROOT_PATH}\COPYING" + + ; Cleanup + !delfile "${files}" + !undef files + !undef prefix + +!macroend + +!macro SetupShortcuts + + ; Add the registry key to store the installation folder + WriteRegStr HKLM "${APP_INSTALL_KEY}" "${APP_INSTALL_VALUE}" "$INSTDIR" + + ; Add the registry keys so that software appears in Windows "Add/Remove Software" + WriteRegStr HKLM "${APP_UNINSTALL_KEY}" "DisplayName" "${APP_NAME}" + WriteRegStr HKLM "${APP_UNINSTALL_KEY}" "DisplayIcon" "$INSTDIR\${APP_EXE},0" + WriteRegStr HKLM "${APP_UNINSTALL_KEY}" "UninstallString" '"$INSTDIR\${UNINSTALL_EXE}"' + + ; Add the uninstaller + WriteUninstaller "$INSTDIR\${UNINSTALL_EXE}" + + ; Add the Start Menu and desktop shortcuts + CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$OUTDIR\${APP_EXE}" + CreateDirectory "$SMPROGRAMS\${APP_NAME}" + CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\${APP_EXE}" + CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME} Server.lnk" "$INSTDIR\${APP_EXE}" "-s" + CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME} Uninstall.lnk" "$INSTDIR\${UNINSTALL_EXE}" + +!macroend + +SectionGroup "InstallGroup" + + Section "Install" Install_x86_64 + + ; Install the main application + !insertmacro InstallApplication x86_64 + !insertmacro SetupShortcuts + + ; Install Microsoft Visual Studio redistributables and remove the installer afterwards + ExecWait "$\"$INSTDIR\${VC_REDIST64_EXE}$\" /q /norestart" + Delete "$INSTDIR\${VC_REDIST64_EXE}" + SectionEnd -Section "Uninstall" + Section "Install" Install_x86 -DeleteRegKey HKLM "${UNINST_KEY}" + ; Install the main application + !insertmacro InstallApplication x86 + !insertmacro SetupShortcuts -; the software may have written an auto run entry in the registry, remove it -DeleteRegValue HKCU "${AUTORUN_KEY}" "${AUTORUN_NAME}" + ; Install Microsoft Visual Studio redistributables and remove the installer afterwards + ExecWait "$\"$INSTDIR\${VC_REDIST32_EXE}$\" /q /norestart" + Delete "$INSTDIR\${VC_REDIST32_EXE}" -Delete "$DESKTOP\${APP_NAME}.lnk" -Delete "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" -Delete "$SMPROGRAMS\${APP_NAME}\${APP_NAME} server.lnk" -Delete "$SMPROGRAMS\${APP_NAME}\${UNINSTALL_EXE}.lnk" -RMDIR "$SMPROGRAMS\${APP_NAME}" + SectionEnd -Delete $INSTDIR\${UNINSTALL_EXE} -Delete $INSTDIR\${APP_EXE} -Delete $INSTDIR\Qt5Core.dll -Delete $INSTDIR\Qt5Gui.dll -Delete $INSTDIR\Qt5Widgets.dll -Delete $INSTDIR\Qt5Network.dll -Delete $INSTDIR\Qt5Xml.dll -Delete $INSTDIR\D3DCompiler_47.dll -Delete $INSTDIR\libEGL.dll -Delete $INSTDIR\libGLESv2.dll -Delete $INSTDIR\COPYING -Delete $INSTDIR\platforms\qwindows.dll -Delete $INSTDIR\platforms\qminimal.dll -RMDir $INSTDIR\platforms -RMDir $INSTDIR +SectionGroupEnd + +Function .onInit + + ; Set up registry access, installation folder and installer section for current architecture + ${If} ${RunningX64} + SetRegView 64 + SectionSetFlags ${Install_x86_64} ${SF_SELECTED} + SectionSetFlags ${Install_x86} ${SECTION_OFF} + + ; Set default installation folder, retrieve from registry if available + ReadRegStr $INSTDIR HKLM "${APP_INSTALL_KEY}" "${APP_INSTALL_VALUE}" + IfErrors 0 +2 + StrCpy $INSTDIR "$PROGRAMFILES64\${APP_NAME}" + + ${Else} + SetRegView 32 + SectionSetFlags ${Install_x86} ${SF_SELECTED} + SectionSetFlags ${Install_x86_64} ${SECTION_OFF} + + ; Set default installation folder, retrieve from registry if available + ReadRegStr $INSTDIR HKLM "${APP_INSTALL_KEY}" "${APP_INSTALL_VALUE}" + IfErrors 0 +2 + StrCpy $INSTDIR "$PROGRAMFILES32\${APP_NAME}" + + ${EndIf} + + ; Install for all users + SetShellVarContext all + + ; Select installer language + !insertmacro MUI_LANGDLL_DISPLAY + +FunctionEnd + +; Ensure Jamulus is installed into a new folder only, unless Jamulus is already installed there +Function ValidateDestinationFolder + + ${If} ${FileExists} "$INSTDIR\*" + ${AndIfNot} ${FileExists} "$INSTDIR\${APP_EXE}" + StrCpy $INSTDIR "$INSTDIR\${APP_NAME}" + MessageBox MB_OK|MB_ICONEXCLAMATION "$(INVALID_FOLDER_MSG)" /sd IDOK + Abort + ${endIf} + +FunctionEnd + +Function AbortOnRunningApp + !insertmacro _AbortOnRunningApp +FunctionEnd + + +; Uninstaller +!macro un.InstallFiles buildArch + + !define prefix "${DEPLOY_PATH}\${buildArch}" + !tempfile files + + ; Find target files + !system 'cmd.exe /v /c "for /r "${prefix}" %f in (*.*) do \ + @(set "_f=%f" && echo Delete "$INSTDIR\!_f:${prefix}\=!" >> "${files}")"' + + ; Find target folders in reverse order to ensure they can be deleted when empty + !system 'cmd.exe /v /c "for /f "usebackq" %d in \ + (`dir /b /s /ad "${prefix}" ^| C:\Windows\System32\sort.exe /r`) do \ + @(set "_d=%d" && echo RMDir "$INSTDIR\!_d:${prefix}\=!" >> "${files}")"' + + ; Remove files and folders + !include "${files}" + + Delete "$INSTDIR\COPYING" + Delete "$INSTDIR\${UNINSTALL_EXE}" + RMDir "$INSTDIR" + + ; Cleanup + !delfile "${files}" + !undef files + !undef prefix + +!macroend + +Section "un.Install" + + ; Delete the main application + ${If} ${RunningX64} + !insertmacro un.InstallFiles x86_64 + ${Else} + !insertmacro un.InstallFiles x86 + ${EndIf} + + ; Remove the Start Menu and desktop shortcuts + Delete "$DESKTOP\${APP_NAME}.lnk" + RMDir /r "$SMPROGRAMS\${APP_NAME}" + + ; There may be an auto run entry in the registry for the server, remove it + DeleteRegValue HKCU "${AUTORUN_KEY}" "${AUTORUN_NAME}" + + ; Remove the remaining registry keys + DeleteRegKey HKLM "${APP_UNINSTALL_KEY}" + DeleteRegKey HKLM "${APP_INSTALL_KEY}" SectionEnd + +Function un.onInit + + ; Set up registry access for current architecture + ${If} ${RunningX64} + SetRegView 64 + ${Else} + SetRegView 32 + ${EndIf} + + ; Uninstall for all users + SetShellVarContext all + + ; Retrieve installer language + !insertmacro MUI_UNGETLANGUAGE + +FunctionEnd + +Function un.AbortOnRunningApp + !insertmacro _AbortOnRunningApp +FunctionEnd diff --git a/windows/nsProcess.dll b/windows/nsProcess.dll new file mode 100644 index 0000000000..2478624ee0 Binary files /dev/null and b/windows/nsProcess.dll differ diff --git a/windows/qt-installer-windows.qs b/windows/qt-installer-windows.qs index 8164790b74..6f5ffdfdee 100644 --- a/windows/qt-installer-windows.qs +++ b/windows/qt-installer-windows.qs @@ -1,92 +1,126 @@ /* * Qt Installer script for a non-interactive installation of Qt5 on Windows. - * Installs the 64-bit package if environment variable PLATFORM="x64". + * + * Run with: + * qt-unified-windows-x86-online.exe --verbose --script qt-installer-windows.qs + * + * globals QInstaller, QMessageBox, buttons, gui, installer, console */ -// jshint strict:false -/* globals QInstaller, QMessageBox, buttons, gui, installer, console */ - -// Run with: -// .\qt-unified-windows-x86-3.0.4-online.exe --verbose --script tools\qt-installer-windows.qs - -// Look for Name elements in -// https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5123/Updates.xml -// Unfortunately it is not possible to disable deps like qt.tools.qtcreator -var INSTALL_COMPONENTS = [ - installer.environmentVariable("PLATFORM") == "x64" ? - "qt.qt5.5123.win64_msvc2017_64" : - "qt.qt5.5123.win32_msvc2017", -]; - function Controller() { - // Continue on installing to an existing (possibly empty) directory. + installer.setMessageBoxAutomaticAnswer("installationError", QMessageBox.Retry); + installer.setMessageBoxAutomaticAnswer("installationErrorWithRetry", QMessageBox.Retry); + installer.setMessageBoxAutomaticAnswer("DownloadError", QMessageBox.Retry); + installer.setMessageBoxAutomaticAnswer("archiveDownloadError", QMessageBox.Retry); + + // Continue on installation to an existing (possibly empty) directory. installer.setMessageBoxAutomaticAnswer("OverwriteTargetDirectory", QMessageBox.Yes); - // Continue at "SHOW FINISHED PAGE" + + // Continue at the end of the installation installer.installationFinished.connect(function() { - console.log("installationFinished"); + console.log("Step: InstallationFinished"); gui.clickButton(buttons.NextButton); }); } -Controller.prototype.WelcomePageCallback = function() { + +Controller.prototype.WelcomePageCallback = function() +{ console.log("Step: " + gui.currentPageWidget()); // At least for 3.0.4 immediately clicking Next fails, so wait a bit. // https://github.com/benlau/qtci/commit/85cb986b66af4807a928c70e13d82d00dc26ebf0 gui.clickButton(buttons.NextButton, 1000); }; -Controller.prototype.CredentialsPageCallback = function() { +Controller.prototype.CredentialsPageCallback = function() +{ console.log("Step: " + gui.currentPageWidget()); + + var page = gui.pageWidgetByObjectName("CredentialsPage"); + var username = installer.environmentVariable("QT_ACCOUNT_USERNAME"); + var password = installer.environmentVariable("QT_ACCOUNT_PASSWORD"); + page.loginWidget.EmailLineEdit.setText(username); + page.loginWidget.PasswordLineEdit.setText(password); + gui.clickButton(buttons.NextButton); }; -Controller.prototype.IntroductionPageCallback = function() { +Controller.prototype.IntroductionPageCallback = function() +{ console.log("Step: " + gui.currentPageWidget()); gui.clickButton(buttons.NextButton); }; -Controller.prototype.TargetDirectoryPageCallback = function() { +Controller.prototype.ObligationsPageCallback = function() +{ + console.log("Step: " + gui.currentPageWidget()); + + var page = gui.pageWidgetByObjectName("ObligationsPage"); + page.obligationsAgreement.setChecked(true); + page.completeChanged(); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.DynamicTelemetryPluginFormCallback = function() +{ + console.log("Step: " + gui.currentPageWidget()); + + var page = gui.pageWidgetByObjectName("DynamicTelemetryPluginForm"); + page.statisticGroupBox.disableStatisticRadioButton.setChecked(true); + gui.clickButton(buttons.NextButton); +} + +Controller.prototype.TargetDirectoryPageCallback = function() +{ console.log("Step: " + gui.currentPageWidget()); - // Keep default at "C:\Qt". - //gui.currentPageWidget().TargetDirectoryLineEdit.setText("E:\\Qt"); gui.clickButton(buttons.NextButton); }; Controller.prototype.ComponentSelectionPageCallback = function() { console.log("Step: " + gui.currentPageWidget()); - var page = gui.currentPageWidget(); - page.deselectAll(); - for (var i = 0; i < INSTALL_COMPONENTS.length; i++) { - page.selectComponent(INSTALL_COMPONENTS[i]); - } + + var selection = gui.pageWidgetByObjectName("ComponentSelectionPage"); + gui.findChild(selection, "Latest releases").checked = false; + gui.findChild(selection, "LTS").checked = true; + gui.findChild(selection, "FetchCategoryButton").click(); + + // Look for Name elements in + // https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5123/Updates.xml + var widget = gui.currentPageWidget(); + widget.deselectAll(); + widget.selectComponent("qt.qt5.5123.win32_msvc2017"); + widget.selectComponent("qt.qt5.5123.win64_msvc2017_64"); + gui.clickButton(buttons.NextButton); -}; +} -Controller.prototype.LicenseAgreementPageCallback = function() { +Controller.prototype.LicenseAgreementPageCallback = function() +{ console.log("Step: " + gui.currentPageWidget()); + gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true); gui.clickButton(buttons.NextButton); }; -Controller.prototype.StartMenuDirectoryPageCallback = function() { +Controller.prototype.StartMenuDirectoryPageCallback = function() +{ console.log("Step: " + gui.currentPageWidget()); gui.clickButton(buttons.NextButton); }; -Controller.prototype.ReadyForInstallationPageCallback = function() { +Controller.prototype.ReadyForInstallationPageCallback = function() +{ console.log("Step: " + gui.currentPageWidget()); gui.clickButton(buttons.NextButton); }; -Controller.prototype.FinishedPageCallback = function() { +Controller.prototype.FinishedPageCallback = function() +{ console.log("Step: " + gui.currentPageWidget()); - // TODO somehow the installer crashes after this step. - // https://stackoverflow.com/questions/25105269/silent-install-qt-run-installer-on-ubuntu-server + var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm; if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) { checkBoxForm.launchQtCreatorCheckBox.checked = false; } gui.clickButton(buttons.FinishButton); }; - -// vim: set ft=javascript: diff --git a/windows/uninstaller-welcome.bmp b/windows/uninstaller-welcome.bmp new file mode 100644 index 0000000000..b9732de2fe Binary files /dev/null and b/windows/uninstaller-welcome.bmp differ