mirror of
https://github.com/martinrotter/rssguard.git
synced 2025-01-30 17:15:01 +01:00
Rewrite updater logic for better robustness.
This commit is contained in:
parent
d59d0cee3e
commit
b3e1b5bbe9
@ -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.")
|
||||
|
||||
|
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtCore4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtCore4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtGui4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtGui4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtNetwork4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtNetwork4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtSql4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtSql4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtWebKit4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtWebKit4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtXml4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/QtXml4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qgif4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qgif4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qico4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qico4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qjpeg4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qjpeg4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qmng4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qmng4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qsvg4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qsvg4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtga4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtga4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtiff4.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/imageformats/qtiff4.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/libeay32.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/libeay32.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/msvcp100.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/msvcp100.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/msvcr100.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/msvcr100.dll
Executable file
Binary file not shown.
BIN
resources/binaries/windows/deployment/qt4-msvc2010/ssleay32.dll
Executable file
BIN
resources/binaries/windows/deployment/qt4-msvc2010/ssleay32.dll
Executable file
Binary file not shown.
@ -35,6 +35,7 @@
|
||||
#define APP_VERSION "@APP_VERSION@"
|
||||
#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"
|
||||
|
||||
|
@ -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 <<
|
||||
|
85
src/miscellaneous/iofactory.cpp
Executable file
85
src/miscellaneous/iofactory.cpp
Executable file
@ -0,0 +1,85 @@
|
||||
// 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 "miscellaneous/iofactory.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QFile>
|
||||
|
||||
|
||||
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;
|
||||
}
|
36
src/miscellaneous/iofactory.h
Executable file
36
src/miscellaneous/iofactory.h
Executable file
@ -0,0 +1,36 @@
|
||||
// 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 IOFACTORY_H
|
||||
#define IOFACTORY_H
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
|
||||
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
|
@ -18,6 +18,7 @@
|
||||
#include "updater/formupdater.h"
|
||||
|
||||
#include "definitions/definitions.h"
|
||||
#include "miscellaneous/iofactory.h"
|
||||
#include "qtsingleapplication/qtsingleapplication.h"
|
||||
|
||||
#include <QDesktopWidget>
|
||||
@ -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,
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user