diff ui/installwrapper.cpp @ 364:dc4efb0a70cb

Add Linux support
author Andre Heinecke <aheinecke@intevation.de>
date Mon, 14 Apr 2014 16:58:20 +0000
parents f23e0ccd5d14
children 72487438a180
line wrap: on
line diff
--- a/ui/installwrapper.cpp	Mon Apr 14 16:57:41 2014 +0000
+++ b/ui/installwrapper.cpp	Mon Apr 14 16:58:20 2014 +0000
@@ -1,6 +1,7 @@
 #include "installwrapper.h"
 
 #include <QFileInfo>
+#include <QProcess>
 #include <QTemporaryFile>
 #include <QApplication>
 #include <QDir>
@@ -11,10 +12,10 @@
 #define INSTALL_TIMEOUT 3600000 /* Wait up to an hour */
 
 InstallWrapper::InstallWrapper(QObject* parent,
-        const QString& path, const QStringList& instructions):
+        const QString& path, const QStringList& choices):
     QThread(parent),
     mCertListFile(path),
-    mInstructions(instructions)
+    mChoices(choices)
 {
 }
 
@@ -28,16 +29,32 @@
     return QFileInfo(myDir.absoluteFilePath(instProcName));
 }
 
-#ifdef WIN32
+bool InstallWrapper::writeChoices(QTemporaryFile* choicesFile) const
+{
+    if (!choicesFile->open()) {
+        return false;
+    }
+
+    foreach (const QString &b64data, mChoices) {
+       if (!choicesFile->write(b64data.toLatin1())) {
+           return false;
+       }
+       if (!choicesFile->write("\n")) {
+           return false;
+       }
+    }
+
+    choicesFile->close();
+
+    return true;
+}
+
 void InstallWrapper::run()
 {
     /* TODO: We need errorcodes here so that we can see if a user
      * cancled the UAC elevation */
-    QTemporaryFile instructionsFile;
+    QTemporaryFile choicesFile;
     QFileInfo cinstProcInfo = getCinstProcInfo();
-    DWORD retval = 0;
-    SHELLEXECUTEINFOW shExecInfo;
-    memset (&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW));
 
     QString cinstFileName = QDir::toNativeSeparators(
             getCinstProcInfo().absoluteFilePath());
@@ -47,17 +64,26 @@
         return;
     }
 
-    instructionsFile.open();
-
-    foreach (const QString &b64data, mInstructions) {
-       instructionsFile.write(b64data.toLatin1());
-       instructionsFile.write("\n");
+    if (!writeChoices(&choicesFile)) {
+        emit error(tr("Failed to write temporary file."));
+        return;
     }
 
-    instructionsFile.close();
+    QString parameters = "\"list=" + mCertListFile +
+        "\" \"choices=" + choicesFile.fileName() + "\"";
 
-    QString parameters = "\"list=" + mCertListFile + 
-        "\" \"instructions=" +instructionsFile.fileName() + "\"";
+#ifdef WIN32
+    /* QProcess on Windows uses CreateProcess but we have to
+     * use the runas shell command to get the UAC prompt if necessary.
+     * So we have to handle the process ourself. Starting with
+     * shell execute also means that we can not have stdout and stderr
+     * redirection. This is the reason we use command line parameters
+     * and not a pipe for communication. In debug mode the installer
+     * also makes use of output debug string. */
+    DWORD retval = 0;
+    SHELLEXECUTEINFOW shExecInfo;
+
+    memset (&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW));
 
     shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
     shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
@@ -106,9 +132,35 @@
         /* TODO make this nicer */
         emit error (tr("The process failed with return code. %1").arg(retval));
     }
+    return;
+#else /* WIN32 */
+    QProcess installerProcess;
+    installerProcess.setProgram(cinstProcInfo.absoluteFilePath());
+    installerProcess.waitForStarted();
+    if (installerProcess.state() == QProcess::NotRunning) {
+        emit error (tr("Failed to start installer process."));
+        return;
+    }
+
+    installerProcess.waitForFinished();
+
+    if (installerProcess.exitStatus() == QProcess::CrashExit) {
+        /* Woops */
+        qWarning() << "Installer process crashed";
+    } else if (installerProcess.exitStatus() != QProcess::NormalExit) {
+        /* Can not Happen. there are only those two values but maybe
+         * qt changed.. */
+        qWarning() << "Exit status neither normal nor crash.";
+        return;
+    }
+
+    if (installerProcess.exitCode() == 0) {
+        qDebug() << "output: " << installerProcess.readAllStandardOutput();
+    } else {
+        /* TODO handle errors defined by errorcodes.h */
+        qDebug() << "Installer Process returned: " << installerProcess.exitCode();
+        qDebug() << "output: " << installerProcess.readAllStandardOutput();
+        return;
+    }
+#endif
 }
-#else
-void InstallWrapper::run()
-{
-}
-#endif

http://wald.intevation.org/projects/trustbridge/