Removed junk updater, switched to NSIS.
This commit is contained in:
parent
959f4e04af
commit
89193d06cb
14 changed files with 336 additions and 714 deletions
113
CMakeLists.txt
113
CMakeLists.txt
|
@ -69,14 +69,6 @@
|
||||||
# Setup basic variables.
|
# Setup basic variables.
|
||||||
project(rssguard)
|
project(rssguard)
|
||||||
|
|
||||||
if(WIN32 OR OS2)
|
|
||||||
# Setup "rssguard_updater" project.
|
|
||||||
project(rssguard_updater)
|
|
||||||
|
|
||||||
set(UPDATER_SUBFOLDER "updater")
|
|
||||||
set(UPDATER_EXE_NAME "rssguard_updater")
|
|
||||||
endif(WIN32 OR OS2)
|
|
||||||
|
|
||||||
set(APP_NAME "RSS Guard")
|
set(APP_NAME "RSS Guard")
|
||||||
set(APP_LOW_NAME "rssguard")
|
set(APP_LOW_NAME "rssguard")
|
||||||
set(APP_VERSION "2.0.0.0")
|
set(APP_VERSION "2.0.0.0")
|
||||||
|
@ -98,6 +90,10 @@ option(USE_QT_5 "Use Qt 5 for building" OFF)
|
||||||
option(ENABLE_OS2_RC "Compile application icon on OS/2" OFF)
|
option(ENABLE_OS2_RC "Compile application icon on OS/2" OFF)
|
||||||
option(BUNDLE_ICON_THEMES "Equip installation with custom icon themes" ON)
|
option(BUNDLE_ICON_THEMES "Equip installation with custom icon themes" ON)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
option(USE_NSIS "Use NSIS generator to produce installer" OFF)
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
# Set appropriate CMake policies.
|
# Set appropriate CMake policies.
|
||||||
if(POLICY CMP0012)
|
if(POLICY CMP0012)
|
||||||
cmake_policy(SET CMP0012 NEW)
|
cmake_policy(SET CMP0012 NEW)
|
||||||
|
@ -118,6 +114,11 @@ message(STATUS "[${APP_LOW_NAME}] ==== Options summary ====")
|
||||||
message(STATUS "[${APP_LOW_NAME}] Use Qt 5 for building -> ${USE_QT_5}")
|
message(STATUS "[${APP_LOW_NAME}] Use Qt 5 for building -> ${USE_QT_5}")
|
||||||
message(STATUS "[${APP_LOW_NAME}] Equip installation with custom icon themes -> ${BUNDLE_ICON_THEMES}")
|
message(STATUS "[${APP_LOW_NAME}] Equip installation with custom icon themes -> ${BUNDLE_ICON_THEMES}")
|
||||||
message(STATUS "[${APP_LOW_NAME}] Compile application icon on OS/2 -> ${ENABLE_OS2_RC}")
|
message(STATUS "[${APP_LOW_NAME}] Compile application icon on OS/2 -> ${ENABLE_OS2_RC}")
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
message(STATUS "[${APP_LOW_NAME}] Use NSIS generator to produce installer -> ${USE_NSIS}")
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
message(STATUS "[${APP_LOW_NAME}] ==== Options summary ====")
|
message(STATUS "[${APP_LOW_NAME}] ==== Options summary ====")
|
||||||
message(STATUS "")
|
message(STATUS "")
|
||||||
|
|
||||||
|
@ -126,6 +127,9 @@ message(STATUS "[${APP_LOW_NAME}] Compilation process begins right now.")
|
||||||
|
|
||||||
# Setup misc options.
|
# Setup misc options.
|
||||||
set(CMAKE_COLOR_MAKEFILE ON)
|
set(CMAKE_COLOR_MAKEFILE ON)
|
||||||
|
set(CMAKE_MODULE_PATH
|
||||||
|
${PROJECT_SOURCE_DIR}/resources/nsis
|
||||||
|
${CMAKE_MODULE_PATH})
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
# Eliminate a warning when building in Windows that relates
|
# Eliminate a warning when building in Windows that relates
|
||||||
|
@ -538,29 +542,6 @@ if(WIN32)
|
||||||
)
|
)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
# Setup source & header files for "rssguard_updater".
|
|
||||||
if(WIN32 OR OS2)
|
|
||||||
set(UPDATER_SOURCES
|
|
||||||
# QTSINGLEAPPLICATION sources.
|
|
||||||
src/qtsingleapplication/qtlocalpeer.cpp
|
|
||||||
src/qtsingleapplication/qtsingleapplication.cpp
|
|
||||||
|
|
||||||
# MAIN sources.
|
|
||||||
src/miscellaneous/iofactory.cpp
|
|
||||||
src/updater/formupdater.cpp
|
|
||||||
src/updater/main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set(UPDATER_HEADERS
|
|
||||||
# QTSINGLEAPPLICATION headers.
|
|
||||||
src/qtsingleapplication/qtlocalpeer.h
|
|
||||||
src/qtsingleapplication/qtsingleapplication.h
|
|
||||||
|
|
||||||
# MAIN headers.
|
|
||||||
src/updater/formupdater.h
|
|
||||||
)
|
|
||||||
endif(WIN32 OR OS2)
|
|
||||||
|
|
||||||
# Add custom icon on Mac OS X.
|
# Add custom icon on Mac OS X.
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
SET (APP_SOURCES ${APP_SOURCES} resources/macosx/rssguard.icns)
|
SET (APP_SOURCES ${APP_SOURCES} resources/macosx/rssguard.icns)
|
||||||
|
@ -596,45 +577,9 @@ include_directories (
|
||||||
${CMAKE_SOURCE_DIR}/src/gui
|
${CMAKE_SOURCE_DIR}/src/gui
|
||||||
${CMAKE_SOURCE_DIR}/src/network-web
|
${CMAKE_SOURCE_DIR}/src/network-web
|
||||||
${CMAKE_SOURCE_DIR}/src/dynamic-shortcuts
|
${CMAKE_SOURCE_DIR}/src/dynamic-shortcuts
|
||||||
${CMAKE_SOURCE_DIR}/src/updater
|
|
||||||
${CMAKE_BINARY_DIR}/src
|
${CMAKE_BINARY_DIR}/src
|
||||||
)
|
)
|
||||||
|
|
||||||
# Compile "rssguard_updater" utility on supported platforms.
|
|
||||||
if(WIN32 OR OS2)
|
|
||||||
message(STATUS "[${APP_LOW_NAME}] RSS Guard updater will be compiled.")
|
|
||||||
|
|
||||||
if(${USE_QT_5})
|
|
||||||
add_executable(${UPDATER_EXE_NAME} WIN32
|
|
||||||
${UPDATER_SOURCES}
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
target_link_libraries(${UPDATER_EXE_NAME} Qt5::WinMain)
|
|
||||||
endif(WIN32)
|
|
||||||
|
|
||||||
# Use modules from Qt.
|
|
||||||
qt5_use_modules(rssguard_updater
|
|
||||||
Core
|
|
||||||
Widgets
|
|
||||||
Network
|
|
||||||
)
|
|
||||||
else(${USE_QT_5})
|
|
||||||
add_executable(${UPDATER_EXE_NAME} WIN32
|
|
||||||
${UPDATER_SOURCES}
|
|
||||||
${UPDATER_MOC}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Link modules from Qt.
|
|
||||||
target_link_libraries(${UPDATER_EXE_NAME}
|
|
||||||
${QT_QTCORE_LIBRARY}
|
|
||||||
${QT_QTGUI_LIBRARY}
|
|
||||||
${QT_QTNETWORK_LIBRARY}
|
|
||||||
${QT_QTMAIN_LIBRARY}
|
|
||||||
)
|
|
||||||
endif(${USE_QT_5})
|
|
||||||
endif(WIN32 OR OS2)
|
|
||||||
|
|
||||||
# Compile "rssguard"
|
# Compile "rssguard"
|
||||||
if(${USE_QT_5})
|
if(${USE_QT_5})
|
||||||
add_executable(${EXE_NAME} WIN32 MACOSX_BUNDLE
|
add_executable(${EXE_NAME} WIN32 MACOSX_BUNDLE
|
||||||
|
@ -689,13 +634,7 @@ if(WIN32 OR OS2)
|
||||||
RUNTIME DESTINATION ./${UPDATER_SUBFOLDER})
|
RUNTIME DESTINATION ./${UPDATER_SUBFOLDER})
|
||||||
|
|
||||||
# Copy DLLs and other binary files for main installation and updater.
|
# Copy DLLs and other binary files for main installation and updater.
|
||||||
if(WIN32)
|
if(WIN32 AND NOT ${USE_QT_5})
|
||||||
# Copy "7za" utility on Windows, OS/2 uses built-in "7za".
|
|
||||||
install(FILES resources/binaries/windows/7za/7za.exe
|
|
||||||
resources/binaries/windows/7za/7za_license.txt
|
|
||||||
DESTINATION ./${UPDATER_SUBFOLDER})
|
|
||||||
|
|
||||||
if(NOT ${USE_QT_5})
|
|
||||||
install(FILES ${APP_DLLS_QT4_MSVC2010}
|
install(FILES ${APP_DLLS_QT4_MSVC2010}
|
||||||
DESTINATION ./)
|
DESTINATION ./)
|
||||||
install(FILES ${APP_DLLS_QT4_MSVC2010_IMAGEFORMATS}
|
install(FILES ${APP_DLLS_QT4_MSVC2010_IMAGEFORMATS}
|
||||||
|
@ -705,8 +644,7 @@ if(WIN32 OR OS2)
|
||||||
|
|
||||||
install(FILES ${APP_DLLS_QT4_MSVC2010}
|
install(FILES ${APP_DLLS_QT4_MSVC2010}
|
||||||
DESTINATION ./${UPDATER_SUBFOLDER})
|
DESTINATION ./${UPDATER_SUBFOLDER})
|
||||||
endif(NOT ${USE_QT_5})
|
endif(WIN32 AND NOT ${USE_QT_5})
|
||||||
endif(WIN32)
|
|
||||||
|
|
||||||
if(BUNDLE_ICON_THEMES)
|
if(BUNDLE_ICON_THEMES)
|
||||||
install(DIRECTORY resources/graphics/icons/mini-kfaenza
|
install(DIRECTORY resources/graphics/icons/mini-kfaenza
|
||||||
|
@ -802,17 +740,40 @@ elseif(UNIX)
|
||||||
endif(WIN32 OR OS2)
|
endif(WIN32 OR OS2)
|
||||||
|
|
||||||
# Custom target for packaging.
|
# Custom target for packaging.
|
||||||
|
if(WIN32)
|
||||||
|
if(USE_NSIS)
|
||||||
|
set(CPACK_GENERATOR "NSIS")
|
||||||
|
else(USE_NSIS)
|
||||||
set(CPACK_GENERATOR "ZIP")
|
set(CPACK_GENERATOR "ZIP")
|
||||||
|
endif(USE_NSIS)
|
||||||
|
else(WIN32)
|
||||||
|
set(CPACK_GENERATOR "ZIP")
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
set(CPACK_PACKAGE_NAME ${APP_LOW_NAME})
|
set(CPACK_PACKAGE_NAME ${APP_LOW_NAME})
|
||||||
set(CPACK_PACKAGE_VERSION ${APP_VERSION})
|
set(CPACK_PACKAGE_VERSION ${APP_VERSION})
|
||||||
|
set(CPACK_PACKAGE_VERSION_PATCH "0")
|
||||||
|
set(CPACK_PACKAGE_VENDOR ${APP_AUTHOR})
|
||||||
|
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY ${APP_NAME})
|
||||||
set(CPACK_IGNORE_FILES "/resources/aur/;\\\\.psd$;/resources/deployment;/CVS/;/\\\\.svn/;/\\\\.git/;\\\\.swp$;/CMakeLists.txt.user;\\\\.#;/#;\\\\.tar.gz$;/CMakeFiles/;CMakeCache.txt;\\\\.qm$;/build/;\\\\.diff$;.DS_Store'")
|
set(CPACK_IGNORE_FILES "/resources/aur/;\\\\.psd$;/resources/deployment;/CVS/;/\\\\.svn/;/\\\\.git/;\\\\.swp$;/CMakeLists.txt.user;\\\\.#;/#;\\\\.tar.gz$;/CMakeFiles/;CMakeCache.txt;\\\\.qm$;/build/;\\\\.diff$;.DS_Store'")
|
||||||
set(CPACK_SOURCE_GENERATOR "TGZ")
|
set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||||
set(CPACK_SOURCE_IGNORE_FILES ${CPACK_IGNORE_FILES})
|
set(CPACK_SOURCE_IGNORE_FILES ${CPACK_IGNORE_FILES})
|
||||||
|
|
||||||
|
set(CPACK_NSIS_INSTALLED_ICON_NAME "${APP_LOW_NAME}.ico")
|
||||||
|
set(CPACK_NSIS_HELP_LINK ${APP_URL})
|
||||||
|
set(CPACK_NSIS_URL_INFO_ABOUT ${APP_URL})
|
||||||
|
set(CPACK_NSIS_CONTACT ${APP_EMAIL})
|
||||||
|
|
||||||
# Load packaging facilities.
|
# Load packaging facilities.
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|
||||||
|
# Configure file with custom definitions for NSIS.
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/resources/nsis/NSIS.definitions.nsh.in
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/resources/nsis/NSIS.definitions.nsh
|
||||||
|
)
|
||||||
|
|
||||||
# make dist implementation.
|
# make dist implementation.
|
||||||
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
|
add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -1,29 +0,0 @@
|
||||||
7-Zip Command line version
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
License for use and distribution
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
7-Zip Copyright (C) 1999-2010 Igor Pavlov.
|
|
||||||
|
|
||||||
7za.exe is distributed under the GNU LGPL license
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
You can use 7-Zip on any computer, including a computer in a commercial
|
|
||||||
organization. You don't need to register or pay for 7-Zip.
|
|
||||||
|
|
||||||
|
|
||||||
GNU LGPL information
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Lesser General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2.1 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Lesser General Public License for more details.
|
|
||||||
|
|
||||||
You can receive a copy of the GNU Lesser General Public License from
|
|
||||||
http://www.gnu.org/
|
|
0
resources/nsis/NSIS.InstallOptions.ini.in
Executable file
0
resources/nsis/NSIS.InstallOptions.ini.in
Executable file
27
resources/nsis/NSIS.definitions.nsh.in
Executable file
27
resources/nsis/NSIS.definitions.nsh.in
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
; This file is part of RSS Guard.
|
||||||
|
;
|
||||||
|
; Copyright (C) 2011-2014 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
|
;
|
||||||
|
; RSS Guard is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
; (at your option) any later version.
|
||||||
|
;
|
||||||
|
; RSS Guard is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with RSS Guard. If not, see <http:;www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
!define VERSION "@APP_VERSION@"
|
||||||
|
!define APP_VERSION "@APP_VERSION@"
|
||||||
|
!define APP_NAME "@APP_NAME@"
|
||||||
|
!define EXE_NAME "@EXE_NAME@"
|
||||||
|
!define README_FILE "README"
|
||||||
|
!define LICENSE_FILE "@PROJECT_SOURCE_DIR@\resources\text\COPYING_GNU_GPL"
|
||||||
|
!define MUI_ICON "@PROJECT_SOURCE_DIR@\resources\graphics\@APP_LOW_NAME@.ico"
|
||||||
|
!define MUI_UNICON "@PROJECT_SOURCE_DIR@\resources\graphics\@APP_LOW_NAME@.ico"
|
||||||
|
!define PATCH "0"
|
246
resources/nsis/NSIS.template.in
Executable file
246
resources/nsis/NSIS.template.in
Executable file
|
@ -0,0 +1,246 @@
|
||||||
|
; This file is part of RSS Guard.
|
||||||
|
;
|
||||||
|
; Copyright (C) 2011-2014 by Martin Rotter <rotter.martinos@gmail.com>
|
||||||
|
;
|
||||||
|
; RSS Guard is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
; (at your option) any later version.
|
||||||
|
;
|
||||||
|
; RSS Guard is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with RSS Guard. If not, see <http:;www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; Do necessary inclusions.
|
||||||
|
!include ..\..\..\resources\nsis\NSIS.definitions.nsh
|
||||||
|
!include MUI2.nsh
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; Basic values definitions.
|
||||||
|
!define INST_DIR "@CPACK_TEMPORARY_DIRECTORY@"
|
||||||
|
|
||||||
|
; Name and file.
|
||||||
|
Name "${APP_NAME}"
|
||||||
|
OutFile "@CPACK_TOPLEVEL_DIRECTORY@/@CPACK_OUTPUT_FILE_NAME@"
|
||||||
|
|
||||||
|
; Set custom branding text.
|
||||||
|
BrandingText "${APP_NAME}"
|
||||||
|
|
||||||
|
; Set compression.
|
||||||
|
SetCompressor /SOLID /FINAL lzma
|
||||||
|
|
||||||
|
; Default installation folder.
|
||||||
|
InstallDir "@CPACK_NSIS_INSTALL_ROOT@\${APP_NAME}"
|
||||||
|
InstallDirRegKey HKCU "Software\${APP_NAME}" "Install Directory"
|
||||||
|
|
||||||
|
; Require administrator access.
|
||||||
|
RequestExecutionLevel admin
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; Interface Settings
|
||||||
|
|
||||||
|
; Show "are you sure" dialog when cancelling installation.
|
||||||
|
!define MUI_ABORTWARNING
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; Pages
|
||||||
|
|
||||||
|
; Pages for installator.
|
||||||
|
!insertmacro MUI_PAGE_WELCOME
|
||||||
|
!insertmacro MUI_PAGE_LICENSE "${LICENSE_FILE}"
|
||||||
|
!insertmacro MUI_PAGE_DIRECTORY
|
||||||
|
!insertmacro MUI_PAGE_COMPONENTS
|
||||||
|
|
||||||
|
; Start menu folder page configuration.
|
||||||
|
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
|
||||||
|
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\${APP_NAME}"
|
||||||
|
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
|
||||||
|
|
||||||
|
!insertmacro MUI_PAGE_INSTFILES
|
||||||
|
|
||||||
|
; Offer user to launch the application right when it is installed.
|
||||||
|
!define MUI_FINISHPAGE_RUN "$INSTDIR\${EXE_NAME}"
|
||||||
|
|
||||||
|
!insertmacro MUI_PAGE_FINISH
|
||||||
|
|
||||||
|
; Pages for uninstallator.
|
||||||
|
!insertmacro MUI_UNPAGE_CONFIRM
|
||||||
|
!insertmacro MUI_UNPAGE_INSTFILES
|
||||||
|
!insertmacro MUI_UNPAGE_FINISH
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; Languages.
|
||||||
|
|
||||||
|
!insertmacro MUI_LANGUAGE "English"
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; Helper macros.
|
||||||
|
|
||||||
|
!macro ExecWaitJob _exec
|
||||||
|
StrCpy $9 0
|
||||||
|
System::Call 'kernel32::CreateIoCompletionPort(i -1,i0,i0,i0)i.r1'
|
||||||
|
${IfThen} $1 != 0 ${|} IntOp $9 $9 + 1 ${|}
|
||||||
|
System::Call 'kernel32::CreateJobObject(i0,i0)i.r2'
|
||||||
|
${IfThen} $2 != 0 ${|} IntOp $9 $9 + 1 ${|}
|
||||||
|
System::Call '*(i 0,i $1)i.r0'
|
||||||
|
System::Call 'kernel32::SetInformationJobObject(i $2,i 7,i $0,i 8)i.r3'
|
||||||
|
${IfThen} $3 != 0 ${|} IntOp $9 $9 + 1 ${|}
|
||||||
|
System::Free $0
|
||||||
|
System::Call '*(i,i,i,i)i.r0'
|
||||||
|
System::Alloc 72
|
||||||
|
pop $4
|
||||||
|
System::Call "*$4(i 72)"
|
||||||
|
System::Call 'kernel32::CreateProcess(i0,t ${_exec},i0,i0,i0,i 0x01000004,i0,i0,i $4,i $0)i.r3'
|
||||||
|
${IfThen} $3 != 0 ${|} IntOp $9 $9 + 1 ${|}
|
||||||
|
System::Free $4
|
||||||
|
System::Call "*$0(i.r3,i.r4,i,i)"
|
||||||
|
System::Free $0
|
||||||
|
System::Call 'kernel32::AssignProcessToJobObject(i $2,i $3)i.r0'
|
||||||
|
${IfThen} $0 != 0 ${|} IntOp $9 $9 + 1 ${|}
|
||||||
|
System::Call 'kernel32::ResumeThread(i $4)i.r0'
|
||||||
|
${IfThen} $0 != -1 ${|} IntOp $9 $9 + 1 ${|}
|
||||||
|
System::Call 'kernel32::CloseHandle(i $3)'
|
||||||
|
System::Call 'kernel32::CloseHandle(i $4)'
|
||||||
|
!define __ExecWaitJob__ ExecWaitJob${__LINE__}
|
||||||
|
${__ExecWaitJob__}ioportwait:
|
||||||
|
System::Call 'kernel32::GetQueuedCompletionStatus(i $1,*i.r3,*i,*i.r4,i -1)i.r0'
|
||||||
|
${IfThen} $0 = 0 ${|} StrCpy $9 0 ${|}
|
||||||
|
${IfThen} $3 != 4 ${|} goto ${__ExecWaitJob__}ioportwait ${|}
|
||||||
|
System::Call 'kernel32::CloseHandle(i $2)'
|
||||||
|
System::Call 'kernel32::CloseHandle(i $1)'
|
||||||
|
!undef __ExecWaitJob__
|
||||||
|
${IfThen} $9 < 6 ${|} MessageBox mb_iconstop `ExecWaitJob "${_exec}" failed!` ${|}
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
; If you are using solid compression, files that are required before
|
||||||
|
; the actual installation should be stored first in the data block,
|
||||||
|
; because this will make your installer start faster.
|
||||||
|
!insertmacro MUI_RESERVEFILE_LANGDLL
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; Sections.
|
||||||
|
|
||||||
|
; Installer sections.
|
||||||
|
Section "!Core" Core
|
||||||
|
ReadRegStr $R0 SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "UninstallString"
|
||||||
|
IfFileExists $R0 +1 NotInstalled
|
||||||
|
MessageBox MB_OK|MB_ICONEXCLAMATION "${APP_NAME} is already installed. $\n$\nClick 'OK' to uninstall it then continue with current installation." IDOK Uninstall
|
||||||
|
|
||||||
|
Uninstall:
|
||||||
|
!insertmacro ExecWaitJob '"$R0 /S"'
|
||||||
|
|
||||||
|
NotInstalled:
|
||||||
|
SetOutPath "$INSTDIR"
|
||||||
|
|
||||||
|
; Install core application files.
|
||||||
|
@CPACK_NSIS_FULL_INSTALL@
|
||||||
|
|
||||||
|
; Store installation folder.
|
||||||
|
WriteRegStr HKCU "Software\${APP_NAME}" "Install Directory" $INSTDIR
|
||||||
|
|
||||||
|
; Create uninstaller.
|
||||||
|
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||||
|
|
||||||
|
; Create entry in Windows "Add/Remove programs" panel.
|
||||||
|
Push "DisplayName"
|
||||||
|
Push "${APP_NAME}"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
Push "DisplayVersion"
|
||||||
|
Push "${APP_VERSION}"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
Push "Publisher"
|
||||||
|
Push "@CPACK_PACKAGE_VENDOR@"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
Push "UninstallString"
|
||||||
|
Push "$INSTDIR\Uninstall.exe"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
Push "NoRepair"
|
||||||
|
Push "1"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
Push "NoModify"
|
||||||
|
Push "1"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
Push "DisplayIcon"
|
||||||
|
Push "$INSTDIR\@CPACK_NSIS_INSTALLED_ICON_NAME@"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
Push "HelpLink"
|
||||||
|
Push "@CPACK_NSIS_HELP_LINK@"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
Push "URLInfoAbout"
|
||||||
|
Push "@CPACK_NSIS_URL_INFO_ABOUT@"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
Push "Contact"
|
||||||
|
Push "@CPACK_NSIS_CONTACT@"
|
||||||
|
Call ConditionalAddToRegisty
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
Section "Desktop Icon" DesktopIcon
|
||||||
|
CreateShortCut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${EXE_NAME}"
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
Section "Start Menu Shortcuts" StartMenuShortcuts
|
||||||
|
CreateDirectory "$SMPROGRAMS\${APP_NAME}"
|
||||||
|
CreateShortCut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\${EXE_NAME}"
|
||||||
|
CreateShortCut "$SMPROGRAMS\${APP_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
LangString DESC_Core ${LANG_ENGLISH} "Core installation files for ${APP_NAME}."
|
||||||
|
LangString DESC_DesktopIcon ${LANG_ENGLISH} "Desktop icon for ${APP_NAME}."
|
||||||
|
LangString DESC_QuickLaunchIcon ${LANG_ENGLISH} "Quick launch icon for ${APP_NAME}."
|
||||||
|
LangString DESC_StartMenuShortcuts ${LANG_ENGLISH} "Start Menu Shortcuts for ${APP_NAME}."
|
||||||
|
|
||||||
|
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||||
|
!insertmacro MUI_DESCRIPTION_TEXT ${Core} $(DESC_Core)
|
||||||
|
!insertmacro MUI_DESCRIPTION_TEXT ${DesktopIcon} $(DESC_DesktopIcon)
|
||||||
|
!insertmacro MUI_DESCRIPTION_TEXT ${QuickLaunchIcon} $(DESC_QuickLaunchIcon)
|
||||||
|
!insertmacro MUI_DESCRIPTION_TEXT ${StartMenuShortcuts} $(DESC_StartMenuShortcuts)
|
||||||
|
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||||
|
|
||||||
|
; Uninstaller section.
|
||||||
|
Section "Uninstall"
|
||||||
|
; Remove core application files & directories.
|
||||||
|
@CPACK_NSIS_DELETE_FILES@
|
||||||
|
@CPACK_NSIS_DELETE_DIRECTORIES@
|
||||||
|
|
||||||
|
; Remove uninstaller.
|
||||||
|
Delete "$INSTDIR\Uninstall.exe"
|
||||||
|
|
||||||
|
; Remove entry from Windows "Add/Remove programs" panel.
|
||||||
|
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
|
||||||
|
|
||||||
|
; Remove rest of installed files.
|
||||||
|
; Custom files are left intact.
|
||||||
|
RMDir "$INSTDIR"
|
||||||
|
|
||||||
|
Delete "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk"
|
||||||
|
Delete "$SMPROGRAMS\${APP_NAME}\Uninstall.lnk"
|
||||||
|
RMDir "$SMPROGRAMS\${APP_NAME}"
|
||||||
|
|
||||||
|
Delete "$DESKTOP\${APP_NAME}.lnk"
|
||||||
|
|
||||||
|
DeleteRegKey /ifempty HKCU "Software\${APP_NAME}"
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
;--------------------------------
|
||||||
|
; Custom functions.
|
||||||
|
|
||||||
|
; Executed when installer starts.
|
||||||
|
Function .onInit
|
||||||
|
IntOp $0 ${SF_SELECTED} | ${SF_RO}
|
||||||
|
SectionSetFlags ${Core} $0
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
; Conditional saving to registry.
|
||||||
|
Function ConditionalAddToRegisty
|
||||||
|
Pop $0
|
||||||
|
Pop $1
|
||||||
|
StrCmp "$0" "" ConditionalAddToRegisty_EmptyString
|
||||||
|
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "$1" "$0"
|
||||||
|
ConditionalAddToRegisty_EmptyString:
|
||||||
|
FunctionEnd
|
|
@ -8,7 +8,7 @@ Fixed:
|
||||||
|
|
||||||
Added:
|
Added:
|
||||||
<ul>
|
<ul>
|
||||||
<li></li>
|
<li>Added NSIS-based "portable" installer for Windows and restructured update process.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
Changed:
|
Changed:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="1.9.9.9" type="feature">
|
<release version="1.9.9.9" type="feature">
|
||||||
<url platform="x86" os="Windows">https://bitbucket.org/skunkos/rssguard/downloads/rssguard-1.9.9.9-win32.7z</url>
|
<url platform="x86" os="Windows">https://bitbucket.org/skunkos/rssguard/downloads/rssguard-2.0.0.0-win32-test.exe</url>
|
||||||
<url platform="x86" os="OS2">https://bitbucket.org/skunkos/rssguard/downloads/rssguard-1.9.9.9-os2.7z</url>
|
<url platform="x86" os="OS2">https://bitbucket.org/skunkos/rssguard/downloads/rssguard-1.9.9.9-os2.7z</url>
|
||||||
<changes>
|
<changes>
|
||||||
<![CDATA[<body>
|
<![CDATA[<body>
|
||||||
|
|
|
@ -35,10 +35,6 @@
|
||||||
#define APP_VERSION "@APP_VERSION@"
|
#define APP_VERSION "@APP_VERSION@"
|
||||||
#define APP_USERAGENT QString("@APP_NAME@/@APP_VERSION@ (@APP_URL@) on @CMAKE_SYSTEM@")
|
#define APP_USERAGENT QString("@APP_NAME@/@APP_VERSION@ (@APP_URL@) on @CMAKE_SYSTEM@")
|
||||||
|
|
||||||
#define APP_UPDATER_SUBFOLDER "updater"
|
|
||||||
#define APP_UPDATER_EXECUTABLE "rssguard_updater.exe"
|
|
||||||
#define APP_7ZA_EXECUTABLE "7za.exe"
|
|
||||||
|
|
||||||
#define RELEASES_LIST "https://bitbucket.org/skunkos/rssguard/raw/master/resources/text/UPDATES?at=master"
|
#define RELEASES_LIST "https://bitbucket.org/skunkos/rssguard/raw/master/resources/text/UPDATES?at=master"
|
||||||
#define DEFAULT_LOCALE "en_GB"
|
#define DEFAULT_LOCALE "en_GB"
|
||||||
#define DEFAULT_FEED_ENCODING "UTF-8"
|
#define DEFAULT_FEED_ENCODING "UTF-8"
|
||||||
|
|
|
@ -148,7 +148,7 @@ void FormUpdate::saveUpdateFile(const QByteArray &file_contents) {
|
||||||
|
|
||||||
qDebug("Update file contents was successfuly saved.");
|
qDebug("Update file contents was successfuly saved.");
|
||||||
|
|
||||||
m_updateFilePath = output_file.fileName();
|
m_updateFilePath = QDir::toNativeSeparators(output_file.fileName());
|
||||||
m_readyToInstall = true;
|
m_readyToInstall = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -199,47 +199,17 @@ void FormUpdate::startUpdate() {
|
||||||
// via self-update feature.
|
// via self-update feature.
|
||||||
close();
|
close();
|
||||||
|
|
||||||
// Now we need to copy updater to temporary path and launch it
|
qDebug("Preparing to launch external installer '%s'.", qPrintable(m_updateFilePath));
|
||||||
// with correct arguments from there.
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
QString temp_directory = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
|
||||||
#else
|
|
||||||
QString temp_directory = QDesktopServices::storageLocation(QDesktopServices::TempLocation);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QString source_updater_directory = QDir::toNativeSeparators(qApp->applicationDirPath() + QDir::separator() +
|
if (!QProcess::startDetached(m_updateFilePath)) {
|
||||||
APP_UPDATER_SUBFOLDER);
|
|
||||||
QString target_updater_directory = QDir::toNativeSeparators(temp_directory + QDir::separator() +
|
|
||||||
APP_UPDATER_SUBFOLDER);
|
|
||||||
|
|
||||||
if (QDir(temp_directory).exists(APP_UPDATER_SUBFOLDER)) {
|
|
||||||
IOFactory::removeDirectory(target_updater_directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
IOFactory::copyDirectory(source_updater_directory, target_updater_directory);
|
|
||||||
|
|
||||||
qDebug("Preparing to launch external updater '%s'.",
|
|
||||||
qPrintable(target_updater_directory + QDir::separator() + APP_UPDATER_EXECUTABLE));
|
|
||||||
|
|
||||||
if (!QProcess::startDetached(target_updater_directory + QDir::separator() + APP_UPDATER_EXECUTABLE,
|
|
||||||
QStringList() <<
|
|
||||||
APP_VERSION <<
|
|
||||||
m_updateInfo.m_availableVersion <<
|
|
||||||
QDir::toNativeSeparators(qApp->applicationFilePath()) <<
|
|
||||||
QDir::toNativeSeparators(m_updateFilePath))) {
|
|
||||||
qDebug("External updater was not launched due to error.");
|
qDebug("External updater was not launched due to error.");
|
||||||
|
|
||||||
if (SystemTrayIcon::isSystemTrayActivated()) {
|
qApp->showGuiMessage(tr("Cannot update application"),
|
||||||
qApp->trayIcon()->showMessage(tr("Cannot update application"),
|
|
||||||
tr("Cannot launch external updater. Update application manually."),
|
tr("Cannot launch external updater. Update application manually."),
|
||||||
QSystemTrayIcon::Warning);
|
QSystemTrayIcon::Warning, this);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
MessageBox::show(this,
|
qApp->quit();
|
||||||
QMessageBox::Warning,
|
|
||||||
tr("Cannot update application"),
|
|
||||||
tr("Cannot launch external updater. Update application manually."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (update_for_this_system && isSelfUpdateSupported()) {
|
else if (update_for_this_system && isSelfUpdateSupported()) {
|
||||||
|
@ -264,19 +234,10 @@ void FormUpdate::startUpdate() {
|
||||||
} else {
|
} else {
|
||||||
// Self-update and package are not available.
|
// Self-update and package are not available.
|
||||||
if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) {
|
if (!WebFactory::instance()->openUrlInExternalBrowser(url_file)) {
|
||||||
if (SystemTrayIcon::isSystemTrayActivated()) {
|
qApp->showGuiMessage(tr("Cannot update application"),
|
||||||
qApp->trayIcon()->showMessage(tr("Cannot update application"),
|
|
||||||
tr("Cannot navigate to installation file. Check new installation downloads "
|
tr("Cannot navigate to installation file. Check new installation downloads "
|
||||||
"manually on project website."),
|
"manually on project website."),
|
||||||
QSystemTrayIcon::Warning);
|
QSystemTrayIcon::Warning, this);
|
||||||
}
|
|
||||||
else {
|
|
||||||
MessageBox::show(this,
|
|
||||||
QMessageBox::Warning,
|
|
||||||
tr("Cannot update application"),
|
|
||||||
tr("Cannot navigate to installation file. Check new installation downloads "
|
|
||||||
"manually on project website."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@ void Downloader::downloadFile(const QString &url, int timeout, bool protected_co
|
||||||
request.setOriginatingObject(&originatingObject);
|
request.setOriginatingObject(&originatingObject);
|
||||||
|
|
||||||
// Set url for this request and fire it up.
|
// Set url for this request and fire it up.
|
||||||
|
m_timer->setInterval(timeout);
|
||||||
|
|
||||||
request.setUrl(url);
|
request.setUrl(url);
|
||||||
runGetRequest(request);
|
runGetRequest(request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,382 +0,0 @@
|
||||||
// This file is part of RSS Guard.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2011-2014 by Martin Rotter <rotter.martinos@gmail.com>
|
|
||||||
//
|
|
||||||
// RSS Guard is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// RSS Guard is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "updater/formupdater.h"
|
|
||||||
|
|
||||||
#include "definitions/definitions.h"
|
|
||||||
#include "miscellaneous/iofactory.h"
|
|
||||||
#include "qtsingleapplication/qtsingleapplication.h"
|
|
||||||
|
|
||||||
#include <QDesktopWidget>
|
|
||||||
#include <QIcon>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QTextEdit>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QProcessEnvironment>
|
|
||||||
#include <QScrollBar>
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
|
|
||||||
FormUpdater *FormUpdater::s_instance;
|
|
||||||
|
|
||||||
FormUpdater::FormUpdater(QWidget *parent)
|
|
||||||
: QMainWindow(parent, Qt::Dialog | Qt::WindowStaysOnTopHint),
|
|
||||||
m_state(NoState),
|
|
||||||
m_txtOutput(new QTextEdit(this)),
|
|
||||||
m_parsedArguments(QHash<QString, QString>()) {
|
|
||||||
|
|
||||||
// Initialize singleton.
|
|
||||||
s_instance = this;
|
|
||||||
|
|
||||||
m_txtOutput->setAutoFormatting(QTextEdit::AutoNone);
|
|
||||||
m_txtOutput->setAcceptRichText(true);
|
|
||||||
m_txtOutput->setFontPointSize(10.0);
|
|
||||||
m_txtOutput->setReadOnly(true);
|
|
||||||
m_txtOutput->setFocusPolicy(Qt::StrongFocus);
|
|
||||||
m_txtOutput->setContextMenuPolicy(Qt::DefaultContextMenu);
|
|
||||||
m_txtOutput->setTextInteractionFlags(Qt::TextSelectableByMouse |
|
|
||||||
Qt::TextSelectableByKeyboard |
|
|
||||||
Qt::LinksAccessibleByKeyboard |
|
|
||||||
Qt::LinksAccessibleByMouse);
|
|
||||||
|
|
||||||
setCentralWidget(m_txtOutput);
|
|
||||||
setWindowTitle("RSS Guard updater");
|
|
||||||
setWindowIcon(QIcon(APP_ICON_PATH));
|
|
||||||
moveToCenterAndResize();
|
|
||||||
|
|
||||||
connect(this, SIGNAL(debugMessageProduced(QtMsgType,QString)),
|
|
||||||
this, SLOT(consumeDebugMessage(QtMsgType,QString)));
|
|
||||||
}
|
|
||||||
|
|
||||||
FormUpdater::~FormUpdater() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::startUpgrade() {
|
|
||||||
qDebug("Started...");
|
|
||||||
|
|
||||||
printHeading("Welcome to RSS Guard updater");
|
|
||||||
printText("Analyzing updater arguments.");
|
|
||||||
|
|
||||||
if (QtSingleApplication::arguments().size() != 5) {
|
|
||||||
printText("Insufficient arguments passed. Update process cannot proceed.");
|
|
||||||
printText("\nPress any key to exit updater...");
|
|
||||||
|
|
||||||
m_state = ExitError;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process arguments.
|
|
||||||
saveArguments();
|
|
||||||
printArguments();
|
|
||||||
|
|
||||||
if (!printUpdateInformation() || !doPreparationCleanup() || !doExtractionAndCopying()) {
|
|
||||||
printText("\nPress any key to exit updater...");
|
|
||||||
|
|
||||||
m_state = ExitError;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
doFinalCleanup();
|
|
||||||
executeMainApplication();
|
|
||||||
|
|
||||||
printText("\nPress any key to exit updater...");
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::saveArguments() {
|
|
||||||
// Obtain parameters.
|
|
||||||
QStringList arguments = QtSingleApplication::arguments();
|
|
||||||
|
|
||||||
m_parsedArguments["updater_path"] = QDir::toNativeSeparators(qApp->applicationFilePath());
|
|
||||||
m_parsedArguments["current_version"] = arguments.at(1);
|
|
||||||
m_parsedArguments["next_version"] = arguments.at(2);
|
|
||||||
m_parsedArguments["rssguard_executable_path"] = QDir::toNativeSeparators(arguments.at(3));
|
|
||||||
m_parsedArguments["rssguard_path"] = QDir::toNativeSeparators(QFileInfo(m_parsedArguments["rssguard_executable_path"]).absolutePath());
|
|
||||||
m_parsedArguments["update_file_path"] = QDir::toNativeSeparators(arguments.at(4));
|
|
||||||
m_parsedArguments["temp_path"] = QDir::toNativeSeparators(QFileInfo(m_parsedArguments["update_file_path"]).absolutePath());
|
|
||||||
m_parsedArguments["output_temp_path"] = m_parsedArguments["temp_path"] + QDir::separator() + APP_LOW_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::executeMainApplication() {
|
|
||||||
printText("\nApplication was upgraded without serious errors.");
|
|
||||||
|
|
||||||
if (!QProcess::startDetached(m_parsedArguments["rssguard_executable_path"])) {
|
|
||||||
printText("RSS Guard was not started successfully. Start it manually.");
|
|
||||||
m_state = ExitError;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_state = ExitNormal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::triggerDebugMessageConsumption(QtMsgType type, const QString &message) {
|
|
||||||
emit debugMessageProduced(type, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::consumeDebugMessage(QtMsgType type, const QString &message) {
|
|
||||||
switch (type) {
|
|
||||||
case QtDebugMsg:
|
|
||||||
printText(message);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QtWarningMsg:
|
|
||||||
printText(QString("WARNING: %1").arg(message));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QtCriticalMsg:
|
|
||||||
printText(QString("CRITICAL: %1").arg(message));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case QtFatalMsg:
|
|
||||||
printText(QString("FATAL: %1").arg(message));
|
|
||||||
qApp->exit(EXIT_FAILURE);
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
void FormUpdater::debugHandler(QtMsgType type,
|
|
||||||
const QMessageLogContext &placement,
|
|
||||||
const QString &message) {
|
|
||||||
#ifndef QT_NO_DEBUG_OUTPUT
|
|
||||||
Q_UNUSED(placement)
|
|
||||||
|
|
||||||
s_instance->triggerDebugMessageConsumption(type, message);
|
|
||||||
#else
|
|
||||||
Q_UNUSED(type)
|
|
||||||
Q_UNUSED(placement)
|
|
||||||
Q_UNUSED(message)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void FormUpdater::debugHandler(QtMsgType type, const char *message) {
|
|
||||||
#ifndef QT_NO_DEBUG_OUTPUT
|
|
||||||
s_instance->triggerDebugMessageConsumption(type, QString(message));
|
|
||||||
#else
|
|
||||||
Q_UNUSED(type)
|
|
||||||
Q_UNUSED(message)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void FormUpdater::printArguments() {
|
|
||||||
printNewline();
|
|
||||||
printHeading("Arguments");
|
|
||||||
|
|
||||||
printText(QString("Updater executable file:\n -> %1").arg(m_parsedArguments["updater_path"]));
|
|
||||||
printText(QString("Application executable file:\n -> %1").arg(m_parsedArguments["rssguard_executable_path"]));
|
|
||||||
printText(QString("Temp folder:\n -> %1").arg(m_parsedArguments["temp_path"]));
|
|
||||||
printText(QString("Application temp folder:\n -> %1").arg(m_parsedArguments["output_temp_path"]));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FormUpdater::printUpdateInformation() {
|
|
||||||
qApp->processEvents();
|
|
||||||
|
|
||||||
bool update_file_exists = QFile::exists(m_parsedArguments["update_file_path"]);
|
|
||||||
|
|
||||||
printNewline();
|
|
||||||
printHeading("Update information");
|
|
||||||
|
|
||||||
printText(QString("Version change:\n -> %1 --> %2").arg(m_parsedArguments["current_version"], m_parsedArguments["next_version"]));
|
|
||||||
printText(QString("Update file:\n -> %1").arg(m_parsedArguments["update_file_path"]));
|
|
||||||
printText(QString("Update file exists:\n -> %1").arg(update_file_exists ? "yes" : "no"));
|
|
||||||
printText(QString("Update file size:\n -> %1 bytes").arg(QFileInfo(m_parsedArguments["update_file_path"]).size()));
|
|
||||||
|
|
||||||
if (!update_file_exists) {
|
|
||||||
printText("\nUpdate file does not exist or is corrupted.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return update_file_exists;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FormUpdater::doPreparationCleanup() {
|
|
||||||
qApp->processEvents();
|
|
||||||
|
|
||||||
printNewline();
|
|
||||||
printHeading("Initial cleanup");
|
|
||||||
|
|
||||||
// Check if main RSS Guard instance is running.
|
|
||||||
for (int i = 1; i <= 4; i++) {
|
|
||||||
qApp->processEvents();
|
|
||||||
|
|
||||||
if (i == 4) {
|
|
||||||
printText("Updater made 3 attempts to exit RSS Guard and it failed. Update cannot continue.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printText(QString("Check for running instances of RSS Guard, attempt %1.").arg(i));
|
|
||||||
|
|
||||||
if (static_cast<QtSingleApplication*>(QCoreApplication::instance())->sendMessage(APP_QUIT_INSTANCE)) {
|
|
||||||
printText("The main application is running. Quitting it.");
|
|
||||||
printText("Waiting for 6000 ms for main application to finish.");
|
|
||||||
|
|
||||||
QEventLoop blocker(this);
|
|
||||||
QTimer::singleShot(6000, &blocker, SLOT(quit()));
|
|
||||||
blocker.exec();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printText("The main application is not running.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove old folders.
|
|
||||||
if (QDir(m_parsedArguments["output_temp_path"]).exists()) {
|
|
||||||
if (!IOFactory::removeDirectory(m_parsedArguments["output_temp_path"])) {
|
|
||||||
printText("Cleanup of old temporary files failed.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printText("Cleanup of old temporary files is done.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IOFactory::removeDirectory(m_parsedArguments["rssguard_path"],
|
|
||||||
QStringList(),
|
|
||||||
// Keep the folder with settings.
|
|
||||||
QStringList() << "data")) {
|
|
||||||
printText("Full cleanup of actual RSS Guard installation failed.");
|
|
||||||
printText("Some files from old installation may persist.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FormUpdater::doExtractionAndCopying() {
|
|
||||||
qApp->processEvents();
|
|
||||||
|
|
||||||
printNewline();
|
|
||||||
printHeading("Extraction of update package");
|
|
||||||
|
|
||||||
QStringList extractor_arguments;
|
|
||||||
QProcess process_extractor(this);
|
|
||||||
|
|
||||||
extractor_arguments << "x" << "-r" << "-y" <<
|
|
||||||
QString("-o%1").arg(m_parsedArguments["output_temp_path"]) <<
|
|
||||||
m_parsedArguments["update_file_path"];
|
|
||||||
|
|
||||||
printText(QString("Calling extractor \'%1\' with these arguments:").arg(APP_7ZA_EXECUTABLE));
|
|
||||||
|
|
||||||
foreach(const QString &argument, extractor_arguments) {
|
|
||||||
printText(QString(" -> '%1'").arg(argument));
|
|
||||||
}
|
|
||||||
|
|
||||||
process_extractor.setEnvironment(QProcessEnvironment::systemEnvironment().toStringList());
|
|
||||||
process_extractor.setWorkingDirectory(qApp->applicationDirPath());
|
|
||||||
|
|
||||||
process_extractor.start(APP_7ZA_EXECUTABLE, extractor_arguments);
|
|
||||||
|
|
||||||
if (!process_extractor.waitForFinished()) {
|
|
||||||
process_extractor.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
printText(process_extractor.readAll());
|
|
||||||
printText(QString("Extractor finished with exit code \'%1\'.").arg(process_extractor.exitCode()));
|
|
||||||
|
|
||||||
if (process_extractor.exitCode() != 0 || process_extractor.exitStatus() != QProcess::NormalExit) {
|
|
||||||
printText("Extraction failed due errors. Update cannot continue.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find "rssguard" subfolder path in
|
|
||||||
QFileInfoList rssguard_temp_root = QDir(m_parsedArguments["output_temp_path"]).entryInfoList(QDir::Dirs |
|
|
||||||
QDir::NoDotAndDotDot |
|
|
||||||
QDir::NoSymLinks);
|
|
||||||
|
|
||||||
if (rssguard_temp_root.size() != 1) {
|
|
||||||
printText("Could not find root of downloaded application data.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
printNewline();
|
|
||||||
|
|
||||||
QString rssguard_single_temp_root = rssguard_temp_root.at(0).absoluteFilePath();
|
|
||||||
|
|
||||||
if (!IOFactory::copyDirectory(rssguard_single_temp_root, m_parsedArguments["rssguard_path"])) {
|
|
||||||
printText("Critical error appeared during copying of application files.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FormUpdater::doFinalCleanup() {
|
|
||||||
bool result_file;
|
|
||||||
bool result_path;
|
|
||||||
|
|
||||||
qApp->processEvents();
|
|
||||||
|
|
||||||
printNewline();
|
|
||||||
printHeading("Final cleanup");
|
|
||||||
|
|
||||||
result_path = IOFactory::removeDirectory(m_parsedArguments["output_temp_path"]);
|
|
||||||
result_file = QFile::remove(m_parsedArguments["update_file_path"]);
|
|
||||||
|
|
||||||
printText(QString("Removing temporary files\n -> %1 -> %2\n -> %3 -> %4").arg(
|
|
||||||
m_parsedArguments["output_temp_path"], result_path ? "success" : "failure",
|
|
||||||
m_parsedArguments["update_file_path"], result_file ? "success" : "failure"));
|
|
||||||
|
|
||||||
return result_file && result_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::keyPressEvent(QKeyEvent* event) {
|
|
||||||
if (event->matches(QKeySequence::Copy)) {
|
|
||||||
event->accept();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
event->ignore();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (m_state) {
|
|
||||||
case NoState:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ExitNormal:
|
|
||||||
case ExitError:
|
|
||||||
qApp->quit();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::printHeading(const QString &header) {
|
|
||||||
m_txtOutput->setAlignment(Qt::AlignCenter);
|
|
||||||
m_txtOutput->append(QString("****** %1 ******\n").arg(header));
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::printText(const QString &text) {
|
|
||||||
m_txtOutput->setAlignment(Qt::AlignLeft);
|
|
||||||
m_txtOutput->append(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::printNewline() {
|
|
||||||
m_txtOutput->append("");
|
|
||||||
}
|
|
||||||
|
|
||||||
void FormUpdater::moveToCenterAndResize() {
|
|
||||||
resize(600, 400);
|
|
||||||
move(qApp->desktop()->screenGeometry().center() - rect().center());
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
// This file is part of RSS Guard.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2011-2014 by Martin Rotter <rotter.martinos@gmail.com>
|
|
||||||
//
|
|
||||||
// RSS Guard is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// RSS Guard is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef FORMUPDATER_H
|
|
||||||
#define FORMUPDATER_H
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
|
|
||||||
#include <QtGlobal>
|
|
||||||
#include <QHash>
|
|
||||||
|
|
||||||
|
|
||||||
class QTextEdit;
|
|
||||||
class QKeyEvent;
|
|
||||||
|
|
||||||
class FormUpdater : public QMainWindow {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Describes the state of updater.
|
|
||||||
enum UpdaterState {
|
|
||||||
NoState,
|
|
||||||
ExitNormal,
|
|
||||||
ExitError
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constructors and destructors.
|
|
||||||
explicit FormUpdater(QWidget *parent = 0);
|
|
||||||
virtual ~FormUpdater();
|
|
||||||
|
|
||||||
// Prints various texts.
|
|
||||||
void printText(const QString &text);
|
|
||||||
void printNewline();
|
|
||||||
void printHeading(const QString &header);
|
|
||||||
|
|
||||||
// Starts the whole update process.
|
|
||||||
void startUpgrade();
|
|
||||||
|
|
||||||
// Various parts of update process.
|
|
||||||
void saveArguments();
|
|
||||||
void printArguments();
|
|
||||||
bool printUpdateInformation();
|
|
||||||
bool doPreparationCleanup();
|
|
||||||
bool doExtractionAndCopying();
|
|
||||||
bool doFinalCleanup();
|
|
||||||
void executeMainApplication();
|
|
||||||
|
|
||||||
// Used to trigger signal informaing about new debug message.
|
|
||||||
void triggerDebugMessageConsumption(QtMsgType type, const QString &message);
|
|
||||||
|
|
||||||
// Debug handlers for messages.
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
static void debugHandler(QtMsgType type,
|
|
||||||
const QMessageLogContext &placement,
|
|
||||||
const QString &message);
|
|
||||||
#else
|
|
||||||
static void debugHandler(QtMsgType type,
|
|
||||||
const char *message);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
// Should be always called on GUI thread which is enforced
|
|
||||||
// by signal/slot auto connection.
|
|
||||||
void consumeDebugMessage(QtMsgType type, const QString &message);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
// Emitted if new debug messaages is produced and should be printed.
|
|
||||||
void debugMessageProduced(QtMsgType type, QString message);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Catch the "press any key event" to exit the updater.
|
|
||||||
void keyPressEvent(QKeyEvent *event);
|
|
||||||
|
|
||||||
// Moves the window into the center of the screen and resizes it.
|
|
||||||
void moveToCenterAndResize();
|
|
||||||
|
|
||||||
// File/directory manipulators.
|
|
||||||
bool copyDirectory(QString source, QString destination);
|
|
||||||
bool removeDirectory(const QString & directory_name,
|
|
||||||
const QStringList &exception_file_list = QStringList(),
|
|
||||||
const QStringList &exception_folder_list = QStringList());
|
|
||||||
|
|
||||||
private:
|
|
||||||
UpdaterState m_state;
|
|
||||||
QTextEdit *m_txtOutput;
|
|
||||||
QHash<QString, QString> m_parsedArguments;
|
|
||||||
|
|
||||||
static FormUpdater *s_instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // FORMUPDATER_H
|
|
|
@ -1,55 +0,0 @@
|
||||||
// This file is part of RSS Guard.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2011-2014 by Martin Rotter <rotter.martinos@gmail.com>
|
|
||||||
//
|
|
||||||
// RSS Guard is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// RSS Guard is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with RSS Guard. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "definitions/definitions.h"
|
|
||||||
#include "qtsingleapplication/qtsingleapplication.h"
|
|
||||||
#include "updater/formupdater.h"
|
|
||||||
|
|
||||||
#include <QTranslator>
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QThread>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QDir>
|
|
||||||
|
|
||||||
|
|
||||||
// Main entry point to "rssguard_updater.exe".
|
|
||||||
// It expects 4 ARGUMENTS:
|
|
||||||
// 0) - the actual path of this process,
|
|
||||||
// 1) - string with current version,
|
|
||||||
// 2) - string with future version,
|
|
||||||
// 3) - path to RSS Guard ("rssguard.exe") file,
|
|
||||||
// 4) - path to update file (stored in TEMP folder).
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
// Instantiate base application object.
|
|
||||||
QtSingleApplication application(APP_LOW_NAME, argc, argv);
|
|
||||||
QtSingleApplication::setQuitOnLastWindowClosed(true);
|
|
||||||
|
|
||||||
FormUpdater main_form;
|
|
||||||
|
|
||||||
// Setup debug output system.
|
|
||||||
#if QT_VERSION >= 0x050000
|
|
||||||
qInstallMessageHandler(FormUpdater::debugHandler);
|
|
||||||
#else
|
|
||||||
qInstallMsgHandler(FormUpdater::debugHandler);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
main_form.show();
|
|
||||||
main_form.startUpgrade();
|
|
||||||
|
|
||||||
return application.exec();
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue