diff --git a/CMakeLists.txt b/CMakeLists.txt index e1da792b4..d04702239 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ 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) @@ -362,6 +363,7 @@ set(APP_SOURCES src/miscellaneous/databasefactory.cpp src/miscellaneous/skinfactory.cpp src/miscellaneous/iconfactory.cpp + src/miscellaneous/iofactory.cpp # CORE sources. src/core/messagesmodel.cpp @@ -505,6 +507,31 @@ set(APP_TEXT resources/text/COPYING_BSD ) +if(WIN32) + set(APP_DLLS_QT4_MSVC2010 + resources/binaries/windows/deployment/qt4-msvc2010/libeay32.dll + resources/binaries/windows/deployment/qt4-msvc2010/msvcp100.dll + resources/binaries/windows/deployment/qt4-msvc2010/msvcr100.dll + resources/binaries/windows/deployment/qt4-msvc2010/QtCore4.dll + resources/binaries/windows/deployment/qt4-msvc2010/QtGui4.dll + resources/binaries/windows/deployment/qt4-msvc2010/QtNetwork4.dll + resources/binaries/windows/deployment/qt4-msvc2010/QtSql4.dll + resources/binaries/windows/deployment/qt4-msvc2010/QtWebKit4.dll + resources/binaries/windows/deployment/qt4-msvc2010/QtXml4.dll + resources/binaries/windows/deployment/qt4-msvc2010/ssleay32.dll + ) + + set(APP_DLLS_QT4_MSVC2010_IMAGEFORMATS + resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qgif4.dll + resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qico4.dll + resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qjpeg4.dll + resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qmng4.dll + resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qsvg4.dll + resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtga4.dll + resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtiff4.dll + ) +endif(WIN32) + # Setup source & header files for "rssguard_updater". if(WIN32 OR OS2) set(UPDATER_SOURCES @@ -513,6 +540,7 @@ if(WIN32 OR OS2) src/qtsingleapplication/qtsingleapplication.cpp # MAIN sources. + src/miscellaneous/iofactory.cpp src/updater/formupdater.cpp src/updater/main.cpp ) @@ -652,7 +680,25 @@ if(WIN32 OR OS2) install(TARGETS ${EXE_NAME} RUNTIME DESTINATION ./) install(TARGETS ${UPDATER_EXE_NAME} - RUNTIME DESTINATION ./) + RUNTIME DESTINATION ./${UPDATER_SUBFOLDER}) + + # Copy DLLs and other binary files for main installation and updater. + if(WIN32) + # 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} + DESTINATION ./) + install(FILES ${APP_DLLS_QT4_MSVC2010_IMAGEFORMATS} + DESTINATION ./imageformats) + + install(FILES ${APP_DLLS_QT4_MSVC2010} + DESTINATION ./${UPDATER_SUBFOLDER}) + endif(NOT ${USE_QT_5}) + endif(WIN32) if(BUNDLE_ICON_THEMES) install(DIRECTORY resources/graphics/icons/mini-kfaenza @@ -675,12 +721,6 @@ if(WIN32 OR OS2) DESTINATION ./l10n) install(FILES ${APP_TEXT} DESTINATION ./) - - if(WIN32) - # Copy "7za" utility on Windows, OS/2 uses built-in "7za". - install(FILES resources/7za/7za.exe resources/7za/7za_license.txt - DESTINATION ./) - endif(WIN32) elseif(APPLE) message(STATUS "[${APP_LOW_NAME}] You will probably install on Mac OS X.") diff --git a/resources/7za/7za.exe b/resources/binaries/windows/7za/7za.exe similarity index 100% rename from resources/7za/7za.exe rename to resources/binaries/windows/7za/7za.exe diff --git a/resources/7za/7za_license.txt b/resources/binaries/windows/7za/7za_license.txt similarity index 100% rename from resources/7za/7za_license.txt rename to resources/binaries/windows/7za/7za_license.txt diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/QtCore4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/QtCore4.dll new file mode 100755 index 000000000..56077683e Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/QtCore4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/QtGui4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/QtGui4.dll new file mode 100755 index 000000000..21b125553 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/QtGui4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/QtNetwork4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/QtNetwork4.dll new file mode 100755 index 000000000..3d4ba3e33 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/QtNetwork4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/QtSql4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/QtSql4.dll new file mode 100755 index 000000000..83b86239a Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/QtSql4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/QtWebKit4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/QtWebKit4.dll new file mode 100755 index 000000000..160aadf2e Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/QtWebKit4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/QtXml4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/QtXml4.dll new file mode 100755 index 000000000..90b35da81 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/QtXml4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qgif4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qgif4.dll new file mode 100755 index 000000000..a08b5ecac Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qgif4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qico4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qico4.dll new file mode 100755 index 000000000..d8d0f43b6 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qico4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qjpeg4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qjpeg4.dll new file mode 100755 index 000000000..53465a1a7 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qjpeg4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qmng4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qmng4.dll new file mode 100755 index 000000000..a0cba359b Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qmng4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qsvg4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qsvg4.dll new file mode 100755 index 000000000..77b238f02 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qsvg4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtga4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtga4.dll new file mode 100755 index 000000000..f95e9fd8f Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtga4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtiff4.dll b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtiff4.dll new file mode 100755 index 000000000..6aad74ae1 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtiff4.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/libeay32.dll b/resources/binaries/windows/deployment/qt4-msvc2010/libeay32.dll new file mode 100755 index 000000000..10222e7a7 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/libeay32.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/msvcp100.dll b/resources/binaries/windows/deployment/qt4-msvc2010/msvcp100.dll new file mode 100755 index 000000000..e9eae444e Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/msvcp100.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/msvcr100.dll b/resources/binaries/windows/deployment/qt4-msvc2010/msvcr100.dll new file mode 100755 index 000000000..fd91c89d8 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/msvcr100.dll differ diff --git a/resources/binaries/windows/deployment/qt4-msvc2010/ssleay32.dll b/resources/binaries/windows/deployment/qt4-msvc2010/ssleay32.dll new file mode 100755 index 000000000..6338590f6 Binary files /dev/null and b/resources/binaries/windows/deployment/qt4-msvc2010/ssleay32.dll differ diff --git a/src/definitions/definitions.h.in b/src/definitions/definitions.h.in index 39019f522..9bbf86c31 100755 --- a/src/definitions/definitions.h.in +++ b/src/definitions/definitions.h.in @@ -35,8 +35,9 @@ #define APP_VERSION "@APP_VERSION@" #define APP_USERAGENT QString("@APP_NAME@/@APP_VERSION@ (@APP_URL@) on @CMAKE_SYSTEM@") -#define APP_UPDATER_EXECUTABLE "rssguard_updater.exe" -#define APP_7ZA_EXECUTABLE "7za.exe" +#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 DEFAULT_LOCALE "en_GB" diff --git a/src/gui/formupdate.cpp b/src/gui/formupdate.cpp index 11a030e61..9042cd281 100755 --- a/src/gui/formupdate.cpp +++ b/src/gui/formupdate.cpp @@ -20,6 +20,7 @@ #include "definitions/definitions.h" #include "miscellaneous/systemfactory.h" #include "miscellaneous/iconfactory.h" +#include "miscellaneous/iofactory.h" #include "network-web/networkfactory.h" #include "network-web/webfactory.h" #include "network-web/downloader.h" @@ -198,9 +199,29 @@ void FormUpdate::startUpdate() { // via self-update feature. close(); - qDebug("Preparing to launch external updater '%s'.", APP_UPDATER_EXECUTABLE); + // Now we need to copy updater to temporary path and launch it + // 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 - if (!QProcess::startDetached(APP_UPDATER_EXECUTABLE, + QString source_updater_directory = QDir::toNativeSeparators(qApp->applicationDirPath() + QDir::separator() + + 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 << diff --git a/src/miscellaneous/iofactory.cpp b/src/miscellaneous/iofactory.cpp new file mode 100755 index 000000000..7f448825a --- /dev/null +++ b/src/miscellaneous/iofactory.cpp @@ -0,0 +1,85 @@ +// This file is part of RSS Guard. +// +// Copyright (C) 2011-2014 by Martin Rotter +// +// 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 . + +#include "miscellaneous/iofactory.h" + +#include +#include +#include + + +IOFactory::IOFactory() { +} + +bool IOFactory::removeDirectory(const QString& directory_name, + const QStringList& exception_file_list, + const QStringList& exception_folder_list) { + bool result = true; + QDir dir(directory_name); + + if (dir.exists(directory_name)) { + foreach (QFileInfo info, + dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | + QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) { + if (info.isDir()) { + if (!exception_folder_list.contains(info.fileName())) { + result &= removeDirectory(info.absoluteFilePath(), exception_file_list); + } + } + else if (!exception_file_list.contains(info.fileName())) { + result &= QFile::remove(info.absoluteFilePath()); + } + } + + result &= dir.rmdir(directory_name); + } + + return result; +} + +bool IOFactory::copyDirectory(QString source, QString destination) { + QDir dir(source); + + if (!dir.exists()) { + return false; + } + + foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { + QString dst_path = destination + QDir::separator() + d; + dir.mkpath(dst_path); + copyDirectory(source + QDir::separator() + d, dst_path); + } + + foreach (QString f, dir.entryList(QDir::Files)) { + QString original_file = source + QDir::separator() + f; + QString destination_file = destination + QDir::separator() + f; + + if (!QFile::exists(destination_file) || QFile::remove(destination_file)) { + if (QFile::copy(original_file, destination_file)) { + qDebug("Copied file \'%s\'.", qPrintable(f)); + } + else { + qDebug("Failed to copy file \'%s\'.", qPrintable(QDir::toNativeSeparators(original_file))); + } + } + else { + qDebug("Failed to remove file \'%s\'.", qPrintable(QDir::toNativeSeparators(original_file))); + } + } + + return true; +} diff --git a/src/miscellaneous/iofactory.h b/src/miscellaneous/iofactory.h new file mode 100755 index 000000000..41e262b59 --- /dev/null +++ b/src/miscellaneous/iofactory.h @@ -0,0 +1,36 @@ +// This file is part of RSS Guard. +// +// Copyright (C) 2011-2014 by Martin Rotter +// +// 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 . + +#ifndef IOFACTORY_H +#define IOFACTORY_H + +#include + + +class IOFactory { + private: + IOFactory(); + + public: + static bool copyDirectory(QString source, QString destination); + + static bool removeDirectory(const QString &directory_name, + const QStringList &exception_file_list = QStringList(), + const QStringList &exception_folder_list = QStringList()); +}; + +#endif // IOFACTORY_H diff --git a/src/updater/formupdater.cpp b/src/updater/formupdater.cpp index a6c087d1b..5edd6bd04 100755 --- a/src/updater/formupdater.cpp +++ b/src/updater/formupdater.cpp @@ -18,6 +18,7 @@ #include "updater/formupdater.h" #include "definitions/definitions.h" +#include "miscellaneous/iofactory.h" #include "qtsingleapplication/qtsingleapplication.h" #include @@ -133,7 +134,7 @@ void FormUpdater::triggerDebugMessageConsumption(QtMsgType type, const QString & void FormUpdater::consumeDebugMessage(QtMsgType type, const QString &message) { switch (type) { case QtDebugMsg: - printText(QString("DEBUG: %1").arg(message)); + printText(message); break; case QtWarningMsg: @@ -241,7 +242,7 @@ bool FormUpdater::doPreparationCleanup() { // Remove old folders. if (QDir(m_parsedArguments["output_temp_path"]).exists()) { - if (!removeDirectory(m_parsedArguments["output_temp_path"])) { + if (!IOFactory::removeDirectory(m_parsedArguments["output_temp_path"])) { printText("Cleanup of old temporary files failed."); return false; } @@ -250,20 +251,14 @@ bool FormUpdater::doPreparationCleanup() { } } - if (!removeDirectory(m_parsedArguments["rssguard_path"], - QStringList() << APP_7ZA_EXECUTABLE, - QStringList() << "data")) { + 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."); } - // TODO: Přidat obecně rekurzivní funkci renameDirectory - // která ke všem souborům a složkám (mimo vyjimky) přidá dohodnutý suffix. - // Tydle soubory budou pak smazaný hlavní aplikací při startu. - if (!QFile::rename(m_parsedArguments["updater_path"], m_parsedArguments["updater_path"] + ".old")) { - printText("Updater executable was not renamed and it will not be updated."); - } - return true; } @@ -280,14 +275,14 @@ bool FormUpdater::doExtractionAndCopying() { 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)); + 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(m_parsedArguments["rssguard_path"]); + process_extractor.setWorkingDirectory(qApp->applicationDirPath()); process_extractor.start(APP_7ZA_EXECUTABLE, extractor_arguments); @@ -296,7 +291,7 @@ bool FormUpdater::doExtractionAndCopying() { } printText(process_extractor.readAll()); - printText(QString("Extractor finished with exit code %1.").arg(process_extractor.exitCode())); + 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."); @@ -317,7 +312,7 @@ bool FormUpdater::doExtractionAndCopying() { QString rssguard_single_temp_root = rssguard_temp_root.at(0).absoluteFilePath(); - if (!copyDirectory(rssguard_single_temp_root, m_parsedArguments["rssguard_path"])) { + if (!IOFactory::copyDirectory(rssguard_single_temp_root, m_parsedArguments["rssguard_path"])) { printText("Critical error appeared during copying of application files."); return false; } @@ -334,7 +329,7 @@ bool FormUpdater::doFinalCleanup() { printNewline(); printHeading("Final cleanup"); - result_path = removeDirectory(m_parsedArguments["output_temp_path"]); + 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( @@ -385,62 +380,3 @@ void FormUpdater::moveToCenterAndResize() { resize(600, 400); move(qApp->desktop()->screenGeometry().center() - rect().center()); } - -bool FormUpdater::removeDirectory(const QString& directory_name, - const QStringList& exception_file_list, - const QStringList& exception_folder_list) { - bool result = true; - QDir dir(directory_name); - - if (dir.exists(directory_name)) { - foreach (QFileInfo info, - dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | - QDir::Hidden | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) { - if (info.isDir()) { - if (!exception_folder_list.contains(info.fileName())) { - result &= removeDirectory(info.absoluteFilePath(), exception_file_list); - } - } - else if (!exception_file_list.contains(info.fileName())) { - result &= QFile::remove(info.absoluteFilePath()); - } - } - - result &= dir.rmdir(directory_name); - } - - return result; -} - -bool FormUpdater::copyDirectory(QString source, QString destination) { - QDir dir(source); - - if (! dir.exists()) { - return false; - } - - foreach (QString d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { - QString dst_path = destination + QDir::separator() + d; - dir.mkpath(dst_path); - copyDirectory(source + QDir::separator() + d, dst_path); - } - - foreach (QString f, dir.entryList(QDir::Files)) { - QString original_file = source + QDir::separator() + f; - QString destination_file = destination + QDir::separator() + f; - - if (!QFile::exists(destination_file) || QFile::remove(destination_file)) { - if (QFile::copy(original_file, destination_file)) { - printText(QString("Copied file %1").arg(f)); - } - else { - printText(QString("Failed to copy file %1").arg(original_file)); - } - } - else { - printText(QString("Failed to remove file %1").arg(original_file)); - } - } - - return true; -}