From 47dccec915548abfcad4f2ea0017477132ba96fb Mon Sep 17 00:00:00 2001 From: Paresh More Date: Wed, 8 Jun 2016 12:29:21 +0100 Subject: [PATCH] Windows installer! --- .gitignore | 4 + Make.bat | 494 +++++++++++++++++++++++++++++++ pkg/win32/README.txt | 46 +++ pkg/win32/Resources/license.rtf | Bin 0 -> 1262 bytes pkg/win32/Resources/pgAdmin4.ico | Bin 0 -> 35147 bytes pkg/win32/installer.iss | 97 ++++++ pkg/win32/installer.iss.in | 97 ++++++ pkg/win32/replace.py | 36 +++ 8 files changed, 774 insertions(+) create mode 100644 Make.bat create mode 100644 pkg/win32/README.txt create mode 100644 pkg/win32/Resources/license.rtf create mode 100644 pkg/win32/Resources/pgAdmin4.ico create mode 100644 pkg/win32/installer.iss create mode 100644 pkg/win32/installer.iss.in create mode 100644 pkg/win32/replace.py diff --git a/.gitignore b/.gitignore index 0386e0300..843ae7b07 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,7 @@ pgadmin4.log /mac-build /src-build /dist +/win-build +runtime/Makefile.Debug +runtime/Makefile.Release +runtime/release/ diff --git a/Make.bat b/Make.bat new file mode 100644 index 000000000..34a50efb9 --- /dev/null +++ b/Make.bat @@ -0,0 +1,494 @@ +@ECHO off +SETLOCAL +REM +REM **************************************************************** +SET WD=%CD% +SET "PGBUILDPATH=%WD%\win-build" +SET CMDOPTION="" +IF "%1" == "clean" SET CMDOPTION="VALID" +IF "%1" == "x86" SET CMDOPTION="VALID" +IF "%1" == "amd64" SET CMDOPTION="VALID" + +IF NOT %CMDOPTION%=="VALID" ( GOTO USAGE ) +SET ARCHITECTURE=%1 + +IF "%ARCHITECTURE%"=="clean" ( + GOTO CLEAN_RELEASE + goto:exit +) + +REM Main Functions + +call :SET_PGADMIN4_ENVIRONMENT +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + +call :CLEAN_RELEASE + +call :CREATE_VIRTUAL_ENV +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + +call :CREATE_RUNTIME_ENV +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + +call :CREATE_PYTHON_ENV +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + +call :CLEANUP_ENV +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + +call :CREATE_INSTALLER +IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + +CD %WD% +goto:EXIT +REM Main function Ends + +:CLEAN_RELEASE + ECHO Calling clean target... + IF EXIST "%PGBUILDPATH%" rd "%PGBUILDPATH%" /S /Q + + FOR /R "%WD%" %%f in (*.pyc) do DEL /q "%%f" > nul + IF EXIST "%WD%\pkg\win32\Output" rd "%WD%\pkg\win32\Output" /S /Q + IF EXIST DEL /q "%WD%\pkg\win32\installer.iss" > nul + CD %WD% +GOTO:EOF + +:SET_PGADMIN4_ENVIRONMENT + REM Check os architecture x86 or amd64 + SET RegQry=HKLM\Hardware\Description\System\CentralProcessor\0 + REG.exe Query %RegQry% > checkOS.txt + Find /i "x86" < CheckOS.txt > StringCheck.txt + SET OSTYPE="" + IF %ERRORLEVEL% == 0 ( + SET OSTYPE=x86 + ) else ( + SET OSTYPE=amd64 + ) + DEL CheckOS.txt StringCheck.txt + SET OSVALUE="" + IF "%OSTYPE%"=="x86" ( + IF "%ARCHITECTURE%"=="amd64" ( + ECHO ARCHITECTURE - %ARCHITECTURE% cannot be run on 32 bit machine + goto:exit + ) + OSVALUE=%OSTYPE% + ) + + REM Check IF its is windows 32 bit machine and selected architecture is x86 + IF %OSVALUE%=="x86" ( + IF "%PYTHON_HOME%" == "" SET "PYTHON_HOME=C:\Python27123" + IF "%PYTHON_DLL%" == "" SET "PYTHON_DLL=C:\Windows\System32\python27.dll" + IF "%QTDIR%" == "" SET "QTDIR=C:\Qt\Qt5.5.1\5.5\msvc2013" + IF "%PGDIR%" == "" SET "PGDIR=C:\Program Files\PostgreSQL\9.5" + IF "%INNOTOOL%" == "" SET "INNOTOOL=C:\Program Files\Inno Setup 5" + IF "%VCDIR%" == "" SET "VCDIR=C:\Program Files\Microsoft Visual Studio 12.0\VC" + SET "VCREDISTNAME=vcredist_x86.exe" + goto SKIPARCVALIDATION + ) + + REM Check IF its is windows 64 bit machine and selected architecture is x86 or amd64 + IF "%ARCHITECTURE%"=="x86" ( + IF "%PYTHON_HOME%" == "" SET "PYTHON_HOME=C:\Python27" + IF "%PYTHON_DLL%" == "" SET "PYTHON_DLL=C:\Windows\SysWOW64\python27.dll" + IF "%QTDIR%" == "" SET "QTDIR=C:\Qt\Qt5.5.1\5.5\msvc2013" + IF "%PGDIR%" == "" SET "PGDIR=C:\Program Files (x86)\PostgreSQL\9.5" + IF "%INNOTOOL%" == "" SET "INNOTOOL=C:\Program Files (x86)\Inno Setup 5" + IF "%VCDIR%" == "" SET "VCDIR=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC" + IF "%VCREDIST%" == "" SET "VCREDIST=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\1033\vcredist_x86.exe" + SET "VCREDISTNAME=vcredist_x86.exe" + ) + + IF "%ARCHITECTURE%"=="amd64" ( + IF "%PYTHON_HOME%" == "" SET "PYTHON_HOME=C:\Python27-x64" + IF "%PYTHON_DLL%" == "" SET "PYTHON_DLL=C:\Windows\System32\python27.dll" + IF "%QTDIR%" == "" SET "QTDIR=C:\Qt\5.5\msvc2013" + IF "%PGDIR%" == "" SET "PGDIR=C:\Program Files\PostgreSQL\9.5" + IF "%INNOTOOL%" == "" SET "INNOTOOL=C:\Program Files\Inno Setup 5" + IF "%VCDIR%" == "" SET "VCDIR=C:\Program Files\Microsoft Visual Studio 12.0\VC" + IF "%VCREDIST%" == "" SET "VCREDIST=C:\Program Files\Microsoft Visual Studio 12.0\VC\redist\1033\vcredist_x64.exe" + SET "VCREDISTNAME=vcredist_x64.exe" + ) + +:SKIPARCVALIDATION + REM SET the variables IF not availalbe in windows enviroment + SET "VCVAR=%VCDIR%\vcvarsall.bat" + SET "VCNMAKE=%VCDIR%\bin\nmake.exe" + SET "QMAKE=%QTDIR%\bin\qmake.exe" + SET "VIRTUALENV=venv" + SET "TARGETINSTALLER=%WD%\dist" + SET "VCREDIST=%VCDIR%\redist\1033\%VCREDISTNAME%" + + FOR /F "tokens=3" %%a IN ('findstr /C:"APP_RELEASE =" %WD%\web\config.py') DO SET APP_RELEASE=%%a + FOR /F "tokens=3" %%a IN ('findstr /C:"APP_REVISION =" %WD%\web\config.py') DO SET APP_REVISION_VERSION=%%a + FOR /F "tokens=3" %%a IN ('findstr /C:"APP_SUFFIX =" %WD%\web\config.py') DO SET APP_SUFFIX_VERSION=%%a + REM remove single quote from the string + SET APP_SUFFIX_VERSION=%APP_SUFFIX_VERSION:'=% + SET APP_NAME="" + FOR /F "tokens=2* DELims='" %%a IN ('findstr /C:"APP_NAME =" web\config.py') DO SET APP_NAME=%%a + SET INSTALLERNAME=%APP_NAME%-v%APP_RELEASE%.%APP_REVISION_VERSION%-%APP_SUFFIX_VERSION%-%ARCHITECTURE%.exe + + SET PGADMIN4_VERSION=v%APP_RELEASE% + SET PGADMIN4_APP_VERSION=%APP_RELEASE%.%APP_REVISION_VERSION% + + ECHO **************************************************************** + ECHO S U M M A R Y + ECHO **************************************************************** + ECHO Target mode = %ARCHITECTURE% + ECHO INNOTOOL = %INNOTOOL% + ECHO VCDIR = %VCDIR% + ECHO VCDIST = %VCREDIST% + ECHO NMAKE = %VCNMAKE% + ECHO QTDIR = %QTDIR% + ECHO QMAKE = %QMAKE% + ECHO PYTHON_HOME = %PYTHON_HOME% + ECHO PYTHON_DLL = %PYTHON_DLL% + ECHO PGDIR = %PGDIR% + ECHO **************************************************************** + + REM Check IF path SET in enviroments really exist or not ? + IF NOT EXIST "%INNOTOOL%" GOTO err_handle_inno + IF NOT EXIST "%VCDIR%" GOTO err_handle_visualstudio + IF NOT EXIST "%VCREDIST%" GOTO err_handle_visualstudio_dist + IF NOT EXIST "%VCVAR%" GOTO err_handle_visualstudio + IF NOT EXIST "%VCNMAKE%" GOTO err_handle_visualstudio + IF NOT EXIST "%QTDIR%" GOTO err_handle_qt + IF NOT EXIST "%QMAKE%" GOTO err_handle_qt + IF NOT EXIST "%PYTHON_HOME%" GOTO err_handle_python + IF NOT EXIST "%PYTHON_DLL%" GOTO err_handle_python + IF NOT EXIST "%PGDIR%" GOTO err_handle_pg + + REM Check for QT and VC dependences + FOR /L %%G IN (15,1,19) DO "%VCDIR%\bin\cl.exe" /? 2>&1 | findstr /C:"Version %%G" > nul && SET MSVC_MAJOR_VERSION=%%G && GOTO QT_MSVC + + :QT_MSVC + IF %MSVC_MAJOR_VERSION%==19 SET QT_MSVC_PATH=msvc2015 + IF %MSVC_MAJOR_VERSION%==18 SET QT_MSVC_PATH=msvc2013 + IF %MSVC_MAJOR_VERSION%==17 SET QT_MSVC_PATH=msvc2012 + IF %MSVC_MAJOR_VERSION%==16 SET QT_MSVC_PATH=msvc2010 + IF %MSVC_MAJOR_VERSION%==15 SET QT_MSVC_PATH=msvc2008 + + REM on 64 bit machine if x86 is selected and QTDIR is set to 64 bit is should not allow + IF "%OSTYPE%"=="amd64" ( + IF "%ARCHITECTURE%"=="x86" ( + echo "%QTDIR%" | findstr /C:"_64" > nul && ( GOTO err_handle_qt_compactissue ) + ) + ) + + IF "%ARCHITECTURE%"=="amd64" ( + SET QT_MSVC_PATH=%QT_MSVC_PATH%_64 + ) + + IF NOT EXIST "%QTDIR%\..\%QT_MSVC_PATH%" GOTO err_handle_qt_mismatch + + REM get Python version ex. 2.7.1 will get as 27 + for /f "tokens=1 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "import sys; print sys.version.split(' ')[0]"') DO SET PYTHON_MAJOR=%%G + for /f "tokens=2 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "import sys; print sys.version.split(' ')[0]"') DO SET PYTHON_MINOR=%%G + SET "PYTHON_VERSION=%PYTHON_MAJOR%%PYTHON_MINOR%" + + IF NOT EXIST "%PYTHON_HOME%\Scripts\virtualenv.exe" GOTO err_handle_pythonvirtualenv + + SET REQUIRMENTTXT="" + IF "%PYTHON_MAJOR%"=="2" SET REQUIRMENTTXT=requirements_py2.txt + IF "%PYTHON_MAJOR%"=="3" SET REQUIRMENTTXT=requirements_py3.txt + IF %REQUIRMENTTXT% == "" GOTO err_handle_pythonversion + SET PATH=%PGDIR%;%PGDIR%\bin;%PATH% +goto:EXIT + + +:CREATE_VIRTUAL_ENV + ECHO Creating Virtual Enviroment... + IF NOT EXIST "%PGBUILDPATH%" MKDIR "%PGBUILDPATH%" + + CD "%PGBUILDPATH%" + "%PYTHON_HOME%\Scripts\virtualenv.exe" "%VIRTUALENV%" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + ECHO Activating Virtual Enviroment - %PGBUILDPATH%\%VIRTUALENV%\Scripts\activate... + CALL "%PGBUILDPATH%\%VIRTUALENV%\Scripts\activate" + SET PATH=%PGDIR%\bin;%PATH% + + ECHO Installing dependencies... + pip install -r "%WD%\%REQUIRMENTTXT%" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + pip install sphinx + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + ECHO Virtual Enviroment created successfully. + + ECHO Deactivating Virtual Enviroment - %PGBUILDPATH%\%VIRTUALENV%\Scripts\deactivate... + CALL "%PGBUILDPATH%\%VIRTUALENV%\Scripts\deactivate" + + CD %WD% +GOTO:EOF + +:CREATE_RUNTIME_ENV + ECHO Compiling source code... + MKDIR "%PGBUILDPATH%\runtime" > nul + + REM --- Processing WEB --- + CD "%WD%" + CD web + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + XCOPY /S /I /E /H /Y "%WD%\web" "%PGBUILDPATH%\web" > nul + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + REM Clean up .pyc, pgadmin4.db, config_local.py + ECHO Cleaning up unnecessary files... + for /R "%PGBUILDPATH%\web" %%f in (*.pyc) do DEL /q "%%f" + IF EXIST DEL /s "%PGBUILDPATH%\web\pgadmin4.db" > nul + IF EXIST DEL /s "%PGBUILDPATH%\web\config_local.py" > nul + + ECHO Creating config_local.py + ECHO SERVER_MODE = False > "%PGBUILDPATH%\web\config_local.py" + ECHO HELP_PATH = '../../../docs/en_US/html/' >> "%PGBUILDPATH%\web\config_local.py" + ECHO MINIFY_HTML = False >> "%PGBUILDPATH%\web\config_local.py" + + ECHO Building docs... + MKDIR "%PGBUILDPATH%\docs\en_US\html" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + "%PGBUILDPATH%\%VIRTUALENV%\Scripts\sphinx-build.exe" "%WD%\docs\en_US" "%PGBUILDPATH%\docs\en_US\html" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + ECHO Removing Sphinx + pip uninstall -y sphinx + + ECHO Assembling runtime environment... + CD "%WD%" + CD runtime + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + call "%VCVAR%" %ARCHITECTURE% + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + ECHO Calling - call "%VCVAR%" %ARCHITECTURE% + + call "%QMAKE%" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + call "%VCNMAKE%" clean + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + call "%VCNMAKE%" + IF ERRORLEVEL 1 GOTO ERR_HANDLER + REM Copy binary to Release Folder + copy "%WD%\runtime\release\pgAdmin4.exe" "%PGBUILDPATH%\runtime" + IF ERRORLEVEL 1 GOTO ERR_HANDLER + + REM Copy QTP dependences + copy "%QTDIR%\bin\icudt54.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\icuin54.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\icuuc54.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Core.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Sql.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Gui.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Qml.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5OpenGL.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Quick.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Sensors.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Widgets.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5WebKit.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Network.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Multimedia.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5WebChannel.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5Positioning.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5PrintSupport.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5WebKitWidgets.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%QTDIR%\bin\Qt5MultimediaWidgets.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + MKDIR "%PGBUILDPATH%\runtime\platforms" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + copy "%QTDIR%\plugins\platforms\qwindows.dll" "%PGBUILDPATH%\runtime\platforms" > nul + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + ECHO [Paths] > "%PGBUILDPATH%\runtime\qt.conf" + ECHO Plugins=plugins >> "%PGBUILDPATH%\runtime\qt.conf" + + copy "%PGDIR%\bin\libpq.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%PGDIR%\bin\ssleay32.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%PGDIR%\bin\libeay32.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%PGDIR%\bin\libintl-*.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%PGDIR%\bin\libiconv-*.dll" "%PGBUILDPATH%\runtime" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + MKDIR "%PGBUILDPATH%\installer" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + copy "%VCREDIST%" "%PGBUILDPATH%\installer" > nul + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + ECHO Runtime built successfully. + + CD %WD% +GOTO:EOF + +:CREATE_PYTHON_ENV + copy %PYTHON_DLL% "%PGBUILDPATH%\runtime" > nul + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + XCOPY /S /I /E /H /Y "%PYTHON_HOME%\DLLs" "%PGBUILDPATH%\%VIRTUALENV%\DLLs" > nul + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + XCOPY /S /I /E /H /Y "%PYTHON_HOME%\Lib" "%PGBUILDPATH%\%VIRTUALENV%\Lib" > nul + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + CD %WD% +GOTO:EOF + +:CREATE_INSTALLER + ECHO Preparing for creation of windows installer... + IF NOT EXIST "%TARGETINSTALLER%" MKDIR "%TARGETINSTALLER%" + + copy "%WD%\pkg\win32\Resources\pgAdmin4.ico" "%PGBUILDPATH%" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + REM search and replace string from config.py and copy to config_local.py + CD "%WD%" + CD pkg + CD win32 + + "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in" "-o" "%WD%\pkg\win32\installer.iss.in_stage1" "-s" MYAPP_NAME -r """%APP_NAME%""" + "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage1" "-o" "%WD%\pkg\win32\installer.iss.in_stage2" "-s" MYAPP_FULLVERSION -r """%PGADMIN4_APP_VERSION%""" + "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage2" "-o" "%WD%\pkg\win32\installer.iss.in_stage3" "-s" MYAPP_VERSION -r """%PGADMIN4_VERSION%""" + + set ARCMODE= + IF "%ARCHITECTURE%"=="amd64" ( + set ARCMODE="x64" + ) + "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage3" "-o" "%WD%\pkg\win32\installer.iss.in_stage4" "-s" MYAPP_ARCHITECTURESMODE -r """%ARCMODE%""" + "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage4" "-o" "%WD%\pkg\win32\installer.iss" "-s" MYAPP_VCDIST -r """%VCREDISTNAME%""" + + + DEL /s "%WD%\pkg\win32\installer.iss.in_stage*" > nul + ECHO Creating windows installer... using INNO tool + ECHO "%INNOTOOL%\ISCC.exe" /q "%WD%\pkg\win32\installer.iss" + CALL "%INNOTOOL%\ISCC.exe" /q "%WD%\pkg\win32\installer.iss" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + ECHO move "%WD%\pkg\win32\Output\Setup.exe" "%TARGETINSTALLER%\%INSTALLERNAME%" + MOVE "%WD%\pkg\win32\Output\Setup.exe" "%TARGETINSTALLER%\%INSTALLERNAME%" + IF %ERRORLEVEL% NEQ 0 EXIT /B %ERRORLEVEL% + + ECHO "Location - %TARGETINSTALLER%\%INSTALLERNAME%" + ECHO Installer generated successfully. + GOTO CLEAN_RELEASE + CD %WD% +GOTO:EOF + +:CLEANUP_ENV + ECHO Cleaning up private environment... + rd "%PGBUILDPATH%\%VIRTUALENV%\Include" /S /Q + rd "%PGBUILDPATH%\%VIRTUALENV%\Scripts" /S /Q + DEL /s "%PGBUILDPATH%\%VIRTUALENV%\pip-selfcheck.json" + + ECHO Cleaned up private environment successfully. + CD %WD% +GOTO:EOF + +:err_handle_inno + ECHO %INNOTOOL% does not exist + ECHO Please Install Innotool and SET INNOTOOL enviroment Variable. + ECHO SET "INNOTOOL=" + exit /B 1 +goto EXIT + +:err_handle_visualstudio + ECHO %VCDIR% does not exist, or + ECHO %VCVAR% does not exist, or + ECHO %VCNMAKE% does not exist. + ECHO Please Install Microsoft Visual studio and SET the VCDIR enviroment Variable. + ECHO SET "VCDIR%=" + ECHO SET "VCVAR%=" + ECHO SET "VCNMAKE%=" + exit /B 1 +goto EXIT + +:err_handle_visualstudio_dist + ECHO %VCREDIST% does not exist + ECHO Please Install Microsoft Visual studio and SET the VCDIST enviroment Variable. + ECHO SET "VCDIST%=" + exit /B 1 +goto EXIT + + +:err_handle_python + ECHO %PYTHON_HOME% does not exist, or + ECHO PYTHON_VERSION is not SET, or + ECHO %PYTHON_DLL% does not exist. + ECHO Please install Python and SET the PYTHON_HOME enviroment Variable. + ECHO SET "PYTHON_VERSION=" + ECHO SET "PYTHON_HOME=" + ECHO SET "PYTHON_DLL=" + exit /B 1 +goto EXIT + +:err_handle_qt + ECHO %QTDIR% does not exist. + ECHO Please Install QT SDK and SET the QTDIR enviroment variable. + ECHO SET "QTDIR=" + exit /B 1 +goto EXIT + +:err_handle_qt_mismatch + ECHO %QTDIR%\..\%QT_MSVC_PATH%" does not match with your current Visual Studio, version %QT_MSVC_PATH% + ECHO Your current QT installation willraise a linking error with an MSVC version mismatch. + ECHO Please use a valid QT installation with a folder %QT_MSVC_PATH%. You can use the Qt Maintenance + ECHO Tool to add or remove compiler kits. + exit /B 1 +goto EXIT + +:err_handle_qt_compactissue + ECHO %QTDIR%" does support the current architecture selected %ARCHITECTURE% + ECHO Please use a valid QT installation with a folder %QT_MSVC_PATH%. You can use the Qt Maintenance + ECHO Tool to add or remove compiler kits. + exit /B 1 +goto EXIT + +:err_handle_pg + ECHO %PGDIR% does not exist. + ECHO Please Install Postgres and SET enviroment Variable + ECHO SET "PGDIR=" + exit /B 1 +goto EXIT + +:err_handle_pythonversion + ECHO Python version supported Above 2.6, 2.xx and 3.xx only + exit /B 1 +goto EXIT + +:err_handle_pythonvirtualenv + ECHO Python virtualenv is missing @ location - %PYTHON_HOME%\Scripts\virtualenv.exe + exit /B 1 +goto EXIT + +:ERR_HANDLER + ECHO. + ECHO Aborting build! + CD %WD% + exit /B 1 +GOTO:EOF + +:USAGE + ECHO Invalid command line options.... + ECHO Usage: "Make.bat " + ECHO. + exit /B 1 +GOTO EXIT + +:EXIT + endlocal + exit /B 0 diff --git a/pkg/win32/README.txt b/pkg/win32/README.txt new file mode 100644 index 000000000..9a1004f2a --- /dev/null +++ b/pkg/win32/README.txt @@ -0,0 +1,46 @@ +Building pgAdmin windows installer on windows +================================= + +To generate a pgAdmin 4 installer for Windows bit, the following packages must be installed: + +1. Python installation + - Python 2.6 or above from https://www.python.org/ + +2. QT installation + - Qt 4.6 through 5.5 from http://www.qt.io/ + +3. PostgreSQL installation + - PostgreSQL 9.1 or above from http://www.postgresql.org/ + +4. Inno Setup Installer + - 5.0 and above from http://www.jrsoftware.org/isdl.php + +5. Microsoft visual studio (2008 and above) + +Building: Depending upon the archicture of the OS(x86|amd64) set then environment variables. + +1. Set the PYTHON environment variable to the Python root installation directory, e.g. for x86 + + SET "PYTHON_HOME=C:\Python27" + SET "PYTHON_DLL=C:\Windows\System32\python27.dll" + +2. Set the QTDIR environment variable to the QT root installation directory, e.g. for x86 + + SET "QTDIR=C:\Qt\Qt5.5.1\5.5\msvc2013" + +3. Set the PGDIR environment variable to the PostgreSQL installation directory, e.g. for x86 + + SET "PGDIR=C:\Program Files\PostgreSQL\9.5" + +4. Set the Inno Setup Installer environment variable to the Inno root installation directory, e.g. for x86 + + SET "INNOTOOL=C:\Program Files\Inno Setup 5" + +5. Set the Miscrosoft Visual studio environment variable to the Visual studio root installation directory, e.g. for x86 + + SET "VCDIR=C:\Program Files\Microsoft Visual Studio 12.0\VC" + +6. To build, go to pgAdmin4 source root directory and execute "Make.bat x86|amd64". Based on x86|amd64, this will + create the python virtual environment and install all the required python modules mentioned in the + requirements file using pip, build the runtime code and finally create the windows installer x86|amd64 in ./dist directory + diff --git a/pkg/win32/Resources/license.rtf b/pkg/win32/Resources/license.rtf new file mode 100644 index 0000000000000000000000000000000000000000..40555108fa0575040cd3d8bb06da301fea2dd2a6 GIT binary patch literal 1262 zcmaKq&2HN|5QV$WQw+N5E!;p>|IrmK(J=u@R7EO90BvZCve|2kDn-W#g1mc&a+0=- zb|aEQ&6zXb@V;@rn>VT-&Ggv}+j;yxZd%=SQPbO_+1SINdERvLn|}&FT{P=yN$hav z%y#GDRq`L8VhnF^nSYpp-0A1URNv~o9S*wpAhkL)>u5@UEcoL)l-eDz6JvYu7LKEy z!3MQwaImfEa8-Q^tr@*D>!a7;cV>jqcK)QCo-U0ap|zW1D5882>abf=>YjCuh9ZJ*chIdh&_-JMHxP4z^D9UbizCoV_)zZn3)Z_`$+!d#fj> zX9~UbW^?v4IYd;bsD|BCE@X6ezqcpTZ^54|Jl~I?hCwR_h*|CTLDJ~)^2|B_X9W}- z=rt`Qh!x2)kShx16-jfvO7SA&Wgc!NB{?i8WQ;5_3X%gUZlENUyn!XJAY~OzSLeQ@@2JjYAl9MYcroXZ}WyKX_Tu3M@zGM>Pq+%jOc`bo2 zCx5k|=PeT;_)>l&6-7HKU;?B(se@x8882p2Z@|uZf9-2U1olP?An7#|G<_;mav|7) zWel6d+M-TYkA{C^_)lUJge6N5?F}*#Nk&*MCU)q$A_(D+=4Y_LJ_{}pbj~DNksMz= z4u$1q#_;?rEm+EFm8?*OJh}`NkXu28n8re;5wWDsNCjnGVMp|G(t8Gnq_1&4DXeHk z>msEUAXkns3V4ZNn0N^bB3PIOs{gay01_V*Uu5iR8h{8d<*@?fgcXt&q)6xtVU{JY i@Ws?+N@RdQ3+yDJVR(4Lmy+|81$JSQ;!OPE;>AzwW`ocG literal 0 HcmV?d00001 diff --git a/pkg/win32/Resources/pgAdmin4.ico b/pkg/win32/Resources/pgAdmin4.ico new file mode 100644 index 0000000000000000000000000000000000000000..3fcebafdc9c16dedaf800066f84a3fb91a226ec1 GIT binary patch literal 35147 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 '{#MyAppFullVersion}' then + begin + MsgBox(ExpandConstant('{cm:NewerVersionExists}' + '(v' + Version + ') is already installed' ), mbInformation, MB_OK); + Result := False; + end + else + begin + Result := True; + end + end + else + begin + Result := True; + end +end; + +function InstallVC: Boolean; +begin + Result := True; +end; + +// End of program diff --git a/pkg/win32/installer.iss.in b/pkg/win32/installer.iss.in new file mode 100644 index 000000000..724294fa5 --- /dev/null +++ b/pkg/win32/installer.iss.in @@ -0,0 +1,97 @@ +#define MyAppName MYAPP_NAME +#define MyAppVersion MYAPP_VERSION +#define MyAppPublisher "The pgAdmin Development Team" +#define MyAppURL "www.pgadmin.org" +#define MyAppExeName "pgAdmin4.exe" +#define MyAppID "C14F64E7-DCB9-4DE1-8560-16F08FCFF64E" +#define MyAppFullVersion MYAPP_FULLVERSION +#define MyAppArchitecturesMode MYAPP_ARCHITECTURESMODE +#define MyAppVCDist MYAPP_VCDIST +[Setup] +AppId={#MyAppName}{#MyAppVersion} +AppName={#MyAppName} +AppVersion={#MyAppFullVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={pf}\{#MyAppName}\{#MyAppVersion} +DefaultGroupName={#MyAppName} +DisableWelcomePage=no +DisableProgramGroupPage=yes +LicenseFile=Resources\license.rtf +OutputBaseFilename=setup +SetupIconFile=Resources\pgAdmin4.ico +Compression=lzma +SolidCompression=yes +PrivilegesRequired=admin +ChangesEnvironment=yes +;UninstallFilesDir={app}\{#MyAppVersion} +ArchitecturesInstallIn64BitMode={#MyAppArchitecturesMode} + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Icons] +Name: {group}\{#MyAppName} {#MyAppVersion}; Filename: {app}\runtime\{#MyAppExeName}; IconFilename: {app}\pgAdmin4.ico; WorkingDir: {app}\runtime; + +[Files] +Source: "..\..\win-build\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; + +[Run] +Filename: "{app}\installer\{#MyAppVCDist}"; StatusMsg: "VC runtime redistributable package"; Parameters: "/passive /verysilent /norestart"; Check: InstallVC; +Filename: "{app}\runtime\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: runascurrentuser nowait postinstall skipifsilent + +[CustomMessages] +english.NewerVersionExists=A newer version of {#MyAppName} + +[Registry] +Root: HKLM; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; Flags: uninsdeletekeyifempty +Root: HKLM; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; Flags: uninsdeletekey +Root: HKLM; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; ValueType: string; ValueName: "InstallPath"; ValueData: "{app}" +Root: HKLM; Subkey: "Software\{#MyAppName}\{#MyAppVersion}"; ValueType: string; ValueName: "Version"; ValueData: "{#MyAppFullVersion}" + +[Code] +procedure CurStepChanged(CurStep: TSetupStep); +var + value : string; + begin + if CurStep = ssInstall then begin + value := ExpandConstant('{app}') + '\venv\Lib\site-packages' + ';' + + ExpandConstant('{app}') + '\venv\Lib' + ';' + + ExpandConstant('{app}') + '\venv\Lib\lib-tk' + ';' + + ExpandConstant('{app}') + '\venv\DLLs'; + RegWriteStringValue(HKEY_CURRENT_USER,'Software\pgAdmin Development Team\pgAdmin 4', 'PythonPath', value); + end; +end; + +// find current version before installation +function InitializeSetup: Boolean; +var + Version: String; +begin + if RegValueExists(HKEY_LOCAL_MACHINE,'Software\{#MyAppName}\{#MyAppVersion}', 'Version') then + begin + RegQueryStringValue(HKEY_LOCAL_MACHINE,'Software\{#MyAppName}\{#MyAppVersion}', 'Version', Version); + if Version > '{#MyAppFullVersion}' then + begin + MsgBox(ExpandConstant('{cm:NewerVersionExists}' + '(v' + Version + ') is already installed' ), mbInformation, MB_OK); + Result := False; + end + else + begin + Result := True; + end + end + else + begin + Result := True; + end +end; + +function InstallVC: Boolean; +begin + Result := True; +end; + +// End of program diff --git a/pkg/win32/replace.py b/pkg/win32/replace.py new file mode 100644 index 000000000..22eb443f5 --- /dev/null +++ b/pkg/win32/replace.py @@ -0,0 +1,36 @@ +import fileinput +import sys, getopt + +# Store input and output file names +infile='' +outfile='' +searchExp='' +replaceExp='' + +# Read command line args +myopts, args = getopt.getopt(sys.argv[1:],"i:o:s:r:") + +############################### +# o == option +# a == argument passed to the o +############################### +for o, a in myopts: + if o == '-i': + infile=a + elif o == '-o': + outfile=a + elif o == '-s': + searchExp=a + elif o == '-r': + replaceExp=a + else: + print("Usage: %s -i input -o output" % sys.argv[0]) + +# Display input and output file name passed as the args + +f1 = open(infile, 'r') +f2 = open(outfile, 'w') +for line in f1: + f2.write(line.replace(searchExp,replaceExp)) +f1.close() +f2.close()