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
58bool verbose = 0;
59
60int 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.