KInit
kwrapper_win.cpp
Go to the documentation of this file.
00001 /* 00002 This file is part of the KDE libraries 00003 Copyright (c) 2007 Ralf Habacker <ralf.habacker@freenet.de> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License version 2 as published by the Free Software Foundation. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 /* 00021 kde application starter 00022 - allows starting kde application without any additional path settings [1] 00023 - supports multiple root installation which is often used by packagers 00024 (adds bin/lib directories from KDEDIRS environment to PATH environment) 00025 - designed to start kde application from windows start menu entries 00026 - support for reading KDEDIRS setting from flat file 00027 (located in <path-of-kwrapper.exe>/../../kdedirs.cache) 00028 - planned: automatic KDEDIRS detection support 00029 00030 [1] recent kde cmake buildsystem on win32 installs shared libraries 00031 into lib instead of bin. This requires to have the lib directory 00032 in the PATH environment variable too (required for all pathes in KDEDIRS) 00033 00034 TODO: There is an prelimary concept of setting KDEDIRS environment variable 00035 from a cache file located on a well known path relative from the requested 00036 application. 00037 The recent implementation expects a file name 'kdedirs.cache' two level 00038 above this executable which will be <ProgramFiles> in case kwrapper4 lives 00039 in <Programfiles>/kde4/bin. 00040 This works not in any case especially when running application inside the 00041 build directory. 00042 00043 */ 00044 00045 #include <stdio.h> 00046 #include <assert.h> 00047 #include <stdlib.h> 00048 #include <process.h> 00049 #include <windows.h> 00050 00051 #include <QString> 00052 #include <QProcess> 00053 #include <QtDebug> 00054 #include <QFileInfo> 00055 #include <QCoreApplication> 00056 #include <QList> 00057 00058 bool verbose = 0; 00059 00060 int main(int argc, char **argv) 00061 { 00062 QCoreApplication app(argc,argv); 00063 00064 QStringList envPath; 00065 QStringList searchPath; 00066 QString exeToStart; 00067 QString myAppName = "kwrapper4:"; 00068 QStringList exeParams; 00069 int firstParam = 1; 00070 00071 if (QCoreApplication::arguments().size() == 1) 00072 { 00073 qDebug() << myAppName << "no application given"; 00074 return 1; 00075 } 00076 00077 if (QCoreApplication::arguments().at(1) == "--verbose") 00078 { 00079 verbose = 1; 00080 firstParam = 2; 00081 } 00082 00083 exeToStart = QCoreApplication::arguments().at(firstParam); 00084 00085 for(int i=firstParam+1; i < QCoreApplication::arguments().size(); i++) 00086 exeParams << QCoreApplication::arguments().at(i); 00087 00088 QString path = QString::fromLocal8Bit(qgetenv("PATH")).toLower().replace('\\','/'); 00089 00094 foreach(const QString &a, path.split(';')) 00095 { 00096 if (!envPath.contains(a)) 00097 envPath << a; 00098 if (!a.endsWith(QLatin1String("/lib")) && !a.endsWith(QLatin1String("/lib/")) && !searchPath.contains(a)) 00099 searchPath << a; 00100 } 00101 00102 // add current install path 00103 path = QCoreApplication::applicationDirPath().toLower().replace('\\','/'); 00104 if (!envPath.contains(path)) 00105 envPath << path; 00106 00107 // detect directory where kdedirs.cache lives 00108 // this is not complete, KDEDIRS path should be used as base too 00109 QFileInfo fi(path + "/../.."); 00110 QString rootPath = fi.canonicalPath(); 00111 00112 if (verbose) 00113 qDebug() << "try to find kdedirs.cache in" << rootPath; 00114 00115 // add current lib path to client path environment 00116 path = path.replace("bin","lib"); 00117 if (!envPath.contains(path)) 00118 envPath << path; 00119 00125 path = QString::fromLocal8Bit(qgetenv("KDEDIRS")).toLower().replace('\\','/'); 00126 QStringList kdedirs; 00127 00128 if (path.size() > 0) 00129 kdedirs = path.split(';'); 00130 00131 bool changedKDEDIRS = 0; 00132 // setup kdedirs if not present 00133 if (kdedirs.size() == 0) 00134 { 00135 QStringList kdedirsCacheList; 00136 #ifdef Q_CC_MSVC 00137 kdedirsCacheList << rootPath + "/kdedirs.cache.msvc"; 00138 #endif 00139 kdedirsCacheList << rootPath + "/kdedirs.cache"; 00140 00141 bool found = false; 00142 foreach(const QString &kdedirsCachePath,kdedirsCacheList) 00143 { 00144 QFile f(kdedirsCachePath); 00145 if (f.exists()) 00146 { 00147 f.open(QIODevice::ReadOnly); 00148 QByteArray data = f.readAll(); 00149 f.close(); 00150 kdedirs = QString(data).split(';'); 00151 if (verbose) 00152 qDebug() << "load kdedirs cache from " << kdedirsCachePath << "values=" << kdedirs; 00153 found = true; 00154 break; 00155 } 00156 } 00157 if (!found) 00158 { 00159 /* 00160 f.open(QIODevice::WriteOnly); 00161 // search all pathes one level above for a directory share/apps 00162 // write entries into a cache 00163 f.write(kdedirs.join(";").toAscii()); 00164 f.close(); 00165 */ 00166 } 00167 changedKDEDIRS = 1; 00168 } 00169 if (verbose) 00170 qDebug() << "found KDEDIRS\n\t" << kdedirs.join("\n\t"); 00171 00172 foreach(const QString &a, kdedirs) 00173 { 00174 if (!envPath.contains(a+"/bin")) 00175 envPath << a + "/bin"; 00176 if (!envPath.contains(a+"/lib")) 00177 envPath << a + "/lib"; 00178 if (!searchPath.contains(a+"/bin")) 00179 searchPath << a + "/bin"; 00180 } 00181 00182 // find executable 00183 WCHAR _appName[MAX_PATH+1]; 00184 00185 if (verbose) 00186 qDebug() << "search " << exeToStart << "in"; 00187 00188 bool found = false; 00189 foreach(const QString &a, searchPath) 00190 { 00191 if (verbose) 00192 qDebug() << "\t" << a; 00193 #ifndef _WIN32_WCE 00194 if (SearchPathW((LPCWSTR)a.utf16(),(LPCWSTR)exeToStart.utf16(), 00195 L".exe",MAX_PATH+1,(LPWSTR)_appName,NULL)) 00196 { 00197 found = true; 00198 break; 00199 } 00200 #else 00201 if (QFile::exists(a+"/"+exeToStart+".exe")) 00202 { 00203 found = true; 00204 break; 00205 } 00206 #endif 00207 } 00208 QString appName = QString::fromUtf16((unsigned short*)_appName); 00209 00210 if (!found) 00211 { 00212 qWarning() << myAppName << "application not found"; 00213 return 3; 00214 } 00215 00216 if (verbose) 00217 qDebug() << "run" << exeToStart << "with params" << exeParams << "and PATH environment\n\t" << envPath.join("\n\t"); 00218 00219 // setup client process envirionment 00220 QStringList env = QProcess::systemEnvironment(); 00221 env.replaceInStrings(QRegExp("^PATH=(.*)", Qt::CaseInsensitive), QLatin1String("PATH=") + envPath.join(";")); 00222 if (changedKDEDIRS) 00223 env << QLatin1String("KDEDIRS=") + kdedirs.join(";"); 00224 00225 QProcess *process = new QProcess; 00226 process->setEnvironment(env); 00227 process->start(appName,exeParams); 00228 if (process->state() == QProcess::NotRunning) 00229 { 00230 qWarning() << myAppName << "process not running"; 00231 return 4; 00232 } 00233 process->waitForStarted(); 00234 00235 return 0; 00236 }
KDE 4.6 API Reference