Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /* |
---|---|
2 | This file is part of the KDE libraries |
3 | Copyright (c) 2007 Ralf Habacker <ralf.habacker@freenet.de> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License version 2 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | /* |
21 | kde application starter |
22 | - allows starting kde application without any additional path settings [1] |
23 | - supports multiple root installation which is often used by packagers |
24 | (adds bin/lib directories from KDEDIRS environment to PATH environment) |
25 | - designed to start kde application from windows start menu entries |
26 | - support for reading KDEDIRS setting from flat file |
27 | (located in <path-of-kwrapper.exe>/../../kdedirs.cache) |
28 | - planned: automatic KDEDIRS detection support |
29 | |
30 | [1] recent kde cmake buildsystem on win32 installs shared libraries |
31 | into lib instead of bin. This requires to have the lib directory |
32 | in the PATH environment variable too (required for all pathes in KDEDIRS) |
33 | |
34 | TODO: There is an prelimary concept of setting KDEDIRS environment variable |
35 | from a cache file located on a well known path relative from the requested |
36 | application. |
37 | The recent implementation expects a file name 'kdedirs.cache' two level |
38 | above this executable which will be <ProgramFiles> in case kwrapper4 lives |
39 | in <Programfiles>/kde4/bin. |
40 | This works not in any case especially when running application inside the |
41 | build directory. |
42 | |
43 | */ |
44 | |
45 | #include <stdio.h> |
46 | #include <assert.h> |
47 | #include <stdlib.h> |
48 | #include <process.h> |
49 | #include <windows.h> |
50 | |
51 | #include <QString> |
52 | #include <QProcess> |
53 | #include <QtDebug> |
54 | #include <QFileInfo> |
55 | #include <QCoreApplication> |
56 | #include <QList> |
57 | |
58 | bool verbose = 0; |
59 | |
60 | int main(int argc, char **argv) |
61 | { |
62 | QCoreApplication app(argc,argv); |
63 | |
64 | QStringList envPath; /// pathes for using in environment of started process |
65 | QStringList searchPath; /// pathes for using to find executable |
66 | QString exeToStart; |
67 | QString myAppName = "kwrapper4:"; |
68 | QStringList exeParams; |
69 | int firstParam = 1; |
70 | |
71 | if (QCoreApplication::arguments().size() == 1) |
72 | { |
73 | qDebug() << myAppName << "no application given"; |
74 | return 1; |
75 | } |
76 | |
77 | if (QCoreApplication::arguments().at(1) == "--verbose") |
78 | { |
79 | verbose = 1; |
80 | firstParam = 2; |
81 | } |
82 | |
83 | exeToStart = QCoreApplication::arguments().at(firstParam); |
84 | |
85 | for(int i=firstParam+1; i < QCoreApplication::arguments().size(); i++) |
86 | exeParams << QCoreApplication::arguments().at(i); |
87 | |
88 | QString path = QString::fromLocal8Bit(qgetenv("PATH")).toLower().replace( |
89 | |
90 | /** add pathes from PATH environment |
91 | - all to client path environment |
92 | - pathes not ending with lib to application search path |
93 | */ |
94 | foreach(const QString &a, path.split( |
95 | { |
96 | if (!envPath.contains(a)) |
97 | envPath << a; |
98 | if (!a.endsWith(QLatin1String("/lib")) && !a.endsWith(QLatin1String( "/lib/")) && !searchPath.contains(a)) |
99 | searchPath << a; |
100 | } |
101 | |
102 | // add current install path |
103 | path = QCoreApplication::applicationDirPath().toLower().replace( |
104 | if (!envPath.contains(path)) |
105 | envPath << path; |
106 | |
107 | // detect directory where kdedirs.cache lives |
108 | // this is not complete, KDEDIRS path should be used as base too |
109 | QFileInfo fi(path + "/../.."); |
110 | QString rootPath = fi.canonicalPath(); |
111 | |
112 | if (verbose) |
113 | qDebug() << "try to find kdedirs.cache in"<< rootPath; |
114 | |
115 | // add current lib path to client path environment |
116 | path = path.replace("bin", "lib"); |
117 | if (!envPath.contains(path)) |
118 | envPath << path; |
119 | |
120 | /** |
121 | add bin and lib pathes from KDEDIRS |
122 | - bin/lib to client path environment |
123 | - bin to application search path |
124 | */ |
125 | path = QString::fromLocal8Bit(qgetenv("KDEDIRS")).toLower().replace( |
126 | QStringList kdedirs; |
127 | |
128 | if (path.size() > 0) |
129 | kdedirs = path.split( |
130 | |
131 | bool changedKDEDIRS = 0; |
132 | // setup kdedirs if not present |
133 | if (kdedirs.size() == 0) |
134 | { |
135 | QStringList kdedirsCacheList; |
136 | #ifdef Q_CC_MSVC |
137 | kdedirsCacheList << rootPath + "/kdedirs.cache.msvc"; |
138 | #endif |
139 | kdedirsCacheList << rootPath + "/kdedirs.cache"; |
140 | |
141 | bool found = false; |
142 | foreach(const QString &kdedirsCachePath,kdedirsCacheList) |
143 | { |
144 | QFile f(kdedirsCachePath); |
145 | if (f.exists()) |
146 | { |
147 | f.open(QIODevice::ReadOnly); |
148 | QByteArray data = f.readAll(); |
149 | f.close(); |
150 | kdedirs = QString(data).split( |
151 | if (verbose) |
152 | qDebug() << "load kdedirs cache from "<< kdedirsCachePath << "values="<< kdedirs; |
153 | found = true; |
154 | break; |
155 | } |
156 | } |
157 | if (!found) |
158 | { |
159 | /* |
160 | f.open(QIODevice::WriteOnly); |
161 | // search all pathes one level above for a directory share/apps |
162 | // write entries into a cache |
163 | f.write(kdedirs.join(";").toLatin1()); |
164 | f.close(); |
165 | */ |
166 | } |
167 | changedKDEDIRS = 1; |
168 | } |
169 | if (verbose) |
170 | qDebug() << "found KDEDIRS\n\t"<< kdedirs.join( "\n\t"); |
171 | |
172 | foreach(const QString &a, kdedirs) |
173 | { |
174 | if (!envPath.contains(a+"/bin")) |
175 | envPath << a + "/bin"; |
176 | if (!envPath.contains(a+"/lib")) |
177 | envPath << a + "/lib"; |
178 | if (!searchPath.contains(a+"/bin")) |
179 | searchPath << a + "/bin"; |
180 | } |
181 | |
182 | // find executable |
183 | WCHAR _appName[MAX_PATH+1]; |
184 | |
185 | if (verbose) |
186 | qDebug() << "search "<< exeToStart << "in"; |
187 | |
188 | bool found = false; |
189 | foreach(const QString &a, searchPath) |
190 | { |
191 | if (verbose) |
192 | qDebug() << "\t"<< a; |
193 | #ifndef _WIN32_WCE |
194 | if (SearchPathW((LPCWSTR)a.utf16(),(LPCWSTR)exeToStart.utf16(), |
195 | L".exe",MAX_PATH+1,(LPWSTR)_appName,NULL)) |
196 | { |
197 | found = true; |
198 | break; |
199 | } |
200 | #else |
201 | if (QFile::exists(a+"/"+exeToStart+ ".exe")) |
202 | { |
203 | found = true; |
204 | break; |
205 | } |
206 | #endif |
207 | } |
208 | QString appName = QString::fromUtf16((unsigned short*)_appName); |
209 | |
210 | if (!found) |
211 | { |
212 | qWarning() << myAppName << "application not found"; |
213 | return 3; |
214 | } |
215 | |
216 | if (verbose) |
217 | qDebug() << "run"<< exeToStart << "with params"<< exeParams << "and PATH environment\n\t"<< envPath.join( "\n\t"); |
218 | |
219 | // setup client process envirionment |
220 | QStringList env = QProcess::systemEnvironment(); |
221 | env.replaceInStrings(QRegExp("^PATH=(.*)", Qt::CaseInsensitive), QLatin1String( "PATH=") + envPath.join( ";")); |
222 | if (changedKDEDIRS) |
223 | env << QLatin1String("KDEDIRS=") + kdedirs.join( ";"); |
224 | |
225 | QProcess *process = new QProcess; |
226 | process->setEnvironment(env); |
227 | process->start(appName,exeParams); |
228 | if (process->state() == QProcess::NotRunning) |
229 | { |
230 | qWarning() << myAppName << "process not running"; |
231 | return 4; |
232 | } |
233 | process->waitForStarted(); |
234 | |
235 | return 0; |
236 | } |
237 |
Warning: That file was not part of the compilation database. It may have many parsing errors.