Mercurial > trustbridge
comparison 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 |
comparison
equal
deleted
inserted
replaced
363:d10d9bc2e84f | 364:dc4efb0a70cb |
---|---|
1 #include "installwrapper.h" | 1 #include "installwrapper.h" |
2 | 2 |
3 #include <QFileInfo> | 3 #include <QFileInfo> |
4 #include <QProcess> | |
4 #include <QTemporaryFile> | 5 #include <QTemporaryFile> |
5 #include <QApplication> | 6 #include <QApplication> |
6 #include <QDir> | 7 #include <QDir> |
7 #include <QDebug> | 8 #include <QDebug> |
8 | 9 |
9 #include "logging.h" | 10 #include "logging.h" |
10 | 11 |
11 #define INSTALL_TIMEOUT 3600000 /* Wait up to an hour */ | 12 #define INSTALL_TIMEOUT 3600000 /* Wait up to an hour */ |
12 | 13 |
13 InstallWrapper::InstallWrapper(QObject* parent, | 14 InstallWrapper::InstallWrapper(QObject* parent, |
14 const QString& path, const QStringList& instructions): | 15 const QString& path, const QStringList& choices): |
15 QThread(parent), | 16 QThread(parent), |
16 mCertListFile(path), | 17 mCertListFile(path), |
17 mInstructions(instructions) | 18 mChoices(choices) |
18 { | 19 { |
19 } | 20 } |
20 | 21 |
21 QFileInfo getCinstProcInfo() { | 22 QFileInfo getCinstProcInfo() { |
22 QFileInfo fi(QCoreApplication::applicationFilePath()); | 23 QFileInfo fi(QCoreApplication::applicationFilePath()); |
26 instProcName += "." + fi.suffix(); | 27 instProcName += "." + fi.suffix(); |
27 } | 28 } |
28 return QFileInfo(myDir.absoluteFilePath(instProcName)); | 29 return QFileInfo(myDir.absoluteFilePath(instProcName)); |
29 } | 30 } |
30 | 31 |
31 #ifdef WIN32 | 32 bool InstallWrapper::writeChoices(QTemporaryFile* choicesFile) const |
33 { | |
34 if (!choicesFile->open()) { | |
35 return false; | |
36 } | |
37 | |
38 foreach (const QString &b64data, mChoices) { | |
39 if (!choicesFile->write(b64data.toLatin1())) { | |
40 return false; | |
41 } | |
42 if (!choicesFile->write("\n")) { | |
43 return false; | |
44 } | |
45 } | |
46 | |
47 choicesFile->close(); | |
48 | |
49 return true; | |
50 } | |
51 | |
32 void InstallWrapper::run() | 52 void InstallWrapper::run() |
33 { | 53 { |
34 /* TODO: We need errorcodes here so that we can see if a user | 54 /* TODO: We need errorcodes here so that we can see if a user |
35 * cancled the UAC elevation */ | 55 * cancled the UAC elevation */ |
36 QTemporaryFile instructionsFile; | 56 QTemporaryFile choicesFile; |
37 QFileInfo cinstProcInfo = getCinstProcInfo(); | 57 QFileInfo cinstProcInfo = getCinstProcInfo(); |
38 DWORD retval = 0; | |
39 SHELLEXECUTEINFOW shExecInfo; | |
40 memset (&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW)); | |
41 | 58 |
42 QString cinstFileName = QDir::toNativeSeparators( | 59 QString cinstFileName = QDir::toNativeSeparators( |
43 getCinstProcInfo().absoluteFilePath()); | 60 getCinstProcInfo().absoluteFilePath()); |
44 | 61 |
45 if (!cinstProcInfo.isExecutable()) { | 62 if (!cinstProcInfo.isExecutable()) { |
46 emit error(tr("Could not find certificate installation process.")); | 63 emit error(tr("Could not find certificate installation process.")); |
47 return; | 64 return; |
48 } | 65 } |
49 | 66 |
50 instructionsFile.open(); | 67 if (!writeChoices(&choicesFile)) { |
51 | 68 emit error(tr("Failed to write temporary file.")); |
52 foreach (const QString &b64data, mInstructions) { | 69 return; |
53 instructionsFile.write(b64data.toLatin1()); | |
54 instructionsFile.write("\n"); | |
55 } | 70 } |
56 | 71 |
57 instructionsFile.close(); | 72 QString parameters = "\"list=" + mCertListFile + |
73 "\" \"choices=" + choicesFile.fileName() + "\""; | |
58 | 74 |
59 QString parameters = "\"list=" + mCertListFile + | 75 #ifdef WIN32 |
60 "\" \"instructions=" +instructionsFile.fileName() + "\""; | 76 /* QProcess on Windows uses CreateProcess but we have to |
77 * use the runas shell command to get the UAC prompt if necessary. | |
78 * So we have to handle the process ourself. Starting with | |
79 * shell execute also means that we can not have stdout and stderr | |
80 * redirection. This is the reason we use command line parameters | |
81 * and not a pipe for communication. In debug mode the installer | |
82 * also makes use of output debug string. */ | |
83 DWORD retval = 0; | |
84 SHELLEXECUTEINFOW shExecInfo; | |
85 | |
86 memset (&shExecInfo, 0, sizeof(SHELLEXECUTEINFOW)); | |
61 | 87 |
62 shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW); | 88 shExecInfo.cbSize = sizeof(SHELLEXECUTEINFOW); |
63 shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; | 89 shExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS; |
64 shExecInfo.lpVerb = L"runas"; | 90 shExecInfo.lpVerb = L"runas"; |
65 shExecInfo.lpFile = reinterpret_cast<LPCWSTR> (cinstFileName.utf16()); | 91 shExecInfo.lpFile = reinterpret_cast<LPCWSTR> (cinstFileName.utf16()); |
104 | 130 |
105 if (retval != 0) { | 131 if (retval != 0) { |
106 /* TODO make this nicer */ | 132 /* TODO make this nicer */ |
107 emit error (tr("The process failed with return code. %1").arg(retval)); | 133 emit error (tr("The process failed with return code. %1").arg(retval)); |
108 } | 134 } |
135 return; | |
136 #else /* WIN32 */ | |
137 QProcess installerProcess; | |
138 installerProcess.setProgram(cinstProcInfo.absoluteFilePath()); | |
139 installerProcess.waitForStarted(); | |
140 if (installerProcess.state() == QProcess::NotRunning) { | |
141 emit error (tr("Failed to start installer process.")); | |
142 return; | |
143 } | |
144 | |
145 installerProcess.waitForFinished(); | |
146 | |
147 if (installerProcess.exitStatus() == QProcess::CrashExit) { | |
148 /* Woops */ | |
149 qWarning() << "Installer process crashed"; | |
150 } else if (installerProcess.exitStatus() != QProcess::NormalExit) { | |
151 /* Can not Happen. there are only those two values but maybe | |
152 * qt changed.. */ | |
153 qWarning() << "Exit status neither normal nor crash."; | |
154 return; | |
155 } | |
156 | |
157 if (installerProcess.exitCode() == 0) { | |
158 qDebug() << "output: " << installerProcess.readAllStandardOutput(); | |
159 } else { | |
160 /* TODO handle errors defined by errorcodes.h */ | |
161 qDebug() << "Installer Process returned: " << installerProcess.exitCode(); | |
162 qDebug() << "output: " << installerProcess.readAllStandardOutput(); | |
163 return; | |
164 } | |
165 #endif | |
109 } | 166 } |
110 #else | |
111 void InstallWrapper::run() | |
112 { | |
113 } | |
114 #endif |