kpimutils
processes.cpp
Go to the documentation of this file.
00001 00029 #include "processes.h" 00030 using namespace KPIMUtils; 00031 00032 #ifdef Q_WS_WIN 00033 00034 #include <windows.h> 00035 #include <winperf.h> 00036 #include <psapi.h> 00037 #include <signal.h> 00038 #include <unistd.h> 00039 00040 #ifdef Q_OS_WINCE 00041 #include <Tlhelp32.h> 00042 #endif 00043 00044 #include <QtCore/QList> 00045 #include <QtCore/QtDebug> 00046 00047 static PPERF_OBJECT_TYPE FirstObject( PPERF_DATA_BLOCK PerfData ) 00048 { 00049 return (PPERF_OBJECT_TYPE)( (PBYTE)PerfData + PerfData->HeaderLength ); 00050 } 00051 00052 static PPERF_INSTANCE_DEFINITION FirstInstance( PPERF_OBJECT_TYPE PerfObj ) 00053 { 00054 return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfObj + PerfObj->DefinitionLength ); 00055 } 00056 00057 static PPERF_OBJECT_TYPE NextObject( PPERF_OBJECT_TYPE PerfObj ) 00058 { 00059 return (PPERF_OBJECT_TYPE)( (PBYTE)PerfObj + PerfObj->TotalByteLength ); 00060 } 00061 00062 static PPERF_COUNTER_DEFINITION FirstCounter( PPERF_OBJECT_TYPE PerfObj ) 00063 { 00064 return (PPERF_COUNTER_DEFINITION) ( (PBYTE)PerfObj + PerfObj->HeaderLength ); 00065 } 00066 00067 static PPERF_INSTANCE_DEFINITION NextInstance( PPERF_INSTANCE_DEFINITION PerfInst ) 00068 { 00069 PPERF_COUNTER_BLOCK PerfCntrBlk = 00070 (PPERF_COUNTER_BLOCK)( (PBYTE)PerfInst + PerfInst->ByteLength ); 00071 return (PPERF_INSTANCE_DEFINITION)( (PBYTE)PerfCntrBlk + PerfCntrBlk->ByteLength ); 00072 } 00073 00074 static PPERF_COUNTER_DEFINITION NextCounter( PPERF_COUNTER_DEFINITION PerfCntr ) 00075 { 00076 return (PPERF_COUNTER_DEFINITION)( (PBYTE)PerfCntr + PerfCntr->ByteLength ); 00077 } 00078 00079 static PPERF_COUNTER_BLOCK CounterBlock( PPERF_INSTANCE_DEFINITION PerfInst ) 00080 { 00081 return (PPERF_COUNTER_BLOCK) ( (LPBYTE) PerfInst + PerfInst->ByteLength ); 00082 } 00083 00084 #define GETPID_TOTAL 64 * 1024 00085 #define GETPID_BYTEINCREMENT 1024 00086 #define GETPID_PROCESS_OBJECT_INDEX 230 00087 #define GETPID_PROC_ID_COUNTER 784 00088 00089 static QString fromWChar( const wchar_t *string, int size = -1 ) 00090 { 00091 return ( sizeof(wchar_t) == sizeof(QChar) ) ? 00092 QString::fromUtf16( (ushort *)string, size ) 00093 : QString::fromUcs4( (uint *)string, size ); 00094 } 00095 00096 void KPIMUtils::getProcessesIdForName( const QString &processName, QList<int> &pids ) 00097 { 00098 qDebug() << "KPIMUtils::getProcessesIdForName" << processName; 00099 #ifndef Q_OS_WINCE 00100 PPERF_OBJECT_TYPE perfObject; 00101 PPERF_INSTANCE_DEFINITION perfInstance; 00102 PPERF_COUNTER_DEFINITION perfCounter, curCounter; 00103 PPERF_COUNTER_BLOCK counterPtr; 00104 DWORD bufSize = GETPID_TOTAL; 00105 PPERF_DATA_BLOCK perfData = (PPERF_DATA_BLOCK) malloc( bufSize ); 00106 00107 char key[64]; 00108 sprintf( key,"%d %d", GETPID_PROCESS_OBJECT_INDEX, GETPID_PROC_ID_COUNTER ); 00109 LONG lRes; 00110 while ( ( lRes = RegQueryValueExA( HKEY_PERFORMANCE_DATA, 00111 key, 00112 0, 00113 0, 00114 (LPBYTE) perfData, 00115 &bufSize ) ) == ERROR_MORE_DATA ) { 00116 // get a buffer that is big enough 00117 bufSize += GETPID_BYTEINCREMENT; 00118 perfData = (PPERF_DATA_BLOCK) realloc( perfData, bufSize ); 00119 } 00120 00121 // Get the first object type. 00122 perfObject = FirstObject( perfData ); 00123 if ( !perfObject ) { 00124 return; 00125 } 00126 00127 // Process all objects. 00128 for ( uint i = 0; i < perfData->NumObjectTypes; i++ ) { 00129 if ( perfObject->ObjectNameTitleIndex != GETPID_PROCESS_OBJECT_INDEX ) { 00130 perfObject = NextObject( perfObject ); 00131 continue; 00132 } 00133 pids.clear(); 00134 perfCounter = FirstCounter( perfObject ); 00135 perfInstance = FirstInstance( perfObject ); 00136 // retrieve the instances 00137 qDebug() << "INSTANCES: " << perfObject->NumInstances; 00138 for ( int instance = 0; instance < perfObject->NumInstances; instance++ ) { 00139 curCounter = perfCounter; 00140 const QString foundProcessName( 00141 fromWChar( ( wchar_t * )( (PBYTE)perfInstance + perfInstance->NameOffset ) ) ); 00142 qDebug() << "foundProcessName: " << foundProcessName; 00143 if ( foundProcessName == processName ) { 00144 // retrieve the counters 00145 for ( uint counter = 0; counter < perfObject->NumCounters; counter++ ) { 00146 if ( curCounter->CounterNameTitleIndex == GETPID_PROC_ID_COUNTER ) { 00147 counterPtr = CounterBlock( perfInstance ); 00148 DWORD *value = (DWORD*)( (LPBYTE) counterPtr + curCounter->CounterOffset ); 00149 pids.append( int( *value ) ); 00150 qDebug() << "found PID: " << int( *value ); 00151 break; 00152 } 00153 curCounter = NextCounter( curCounter ); 00154 } 00155 } 00156 perfInstance = NextInstance( perfInstance ); 00157 } 00158 } 00159 free( perfData ); 00160 RegCloseKey( HKEY_PERFORMANCE_DATA ); 00161 #else 00162 HANDLE h; 00163 PROCESSENTRY32 pe32; 00164 00165 h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); 00166 if ( h == INVALID_HANDLE_VALUE ) { 00167 return; 00168 } 00169 pe32.dwSize = sizeof(PROCESSENTRY32); 00170 if ( !Process32First( h, &pe32 ) ) { 00171 return; 00172 } 00173 pids.clear(); 00174 do 00175 { 00176 if ( QString::fromWCharArray( pe32.szExeFile ) == processName ) { 00177 pids.append( (int)pe32.th32ProcessID ); 00178 qDebug() << "found PID: " << (int)pe32.th32ProcessID; 00179 } 00180 00181 } while( Process32Next( h, &pe32 ) ); 00182 CloseToolhelp32Snapshot(h); 00183 #endif 00184 } 00185 00186 bool KPIMUtils::otherProcessesExist( const QString &processName ) 00187 { 00188 QList<int> pids; 00189 getProcessesIdForName( processName, pids ); 00190 int myPid = getpid(); 00191 foreach ( int pid, pids ) { 00192 if ( myPid != pid ) { 00193 // kDebug() << "Process ID is " << pid; 00194 return true; 00195 } 00196 } 00197 return false; 00198 } 00199 00200 bool KPIMUtils::killProcesses( const QString &processName ) 00201 { 00202 QList<int> pids; 00203 getProcessesIdForName( processName, pids ); 00204 if ( pids.empty() ) { 00205 return true; 00206 } 00207 00208 qWarning() << "Killing process \"" << processName << " (pid=" << pids[0] << ").."; 00209 int overallResult = 0; 00210 foreach ( int pid, pids ) { 00211 int result; 00212 #ifndef _WIN32_WCE 00213 result = kill( pid, SIGTERM ); 00214 if ( result == 0 ) { 00215 continue; 00216 } 00217 #endif 00218 result = kill( pid, SIGKILL ); 00219 if ( result != 0 ) { 00220 overallResult = result; 00221 } 00222 } 00223 return overallResult == 0; 00224 } 00225 00226 struct EnumWindowsStruct 00227 { 00228 EnumWindowsStruct() : windowId( 0 ) {} 00229 int pid; 00230 HWND windowId; 00231 }; 00232 00233 BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ) 00234 { 00235 if ( GetWindowLong( hwnd, GWL_STYLE ) & WS_VISIBLE ) { 00236 00237 DWORD pidwin; 00238 00239 GetWindowThreadProcessId( hwnd, &pidwin ); 00240 if ( pidwin == ( (EnumWindowsStruct *)lParam )->pid ) { 00241 ( (EnumWindowsStruct *)lParam )->windowId = hwnd; 00242 return FALSE; //krazy:exclude=captruefalse 00243 } 00244 } 00245 return TRUE; //krazy:exclude=captruefalse 00246 } 00247 00248 void KPIMUtils::activateWindowForProcess( const QString &executableName ) 00249 { 00250 QList<int> pids; 00251 KPIMUtils::getProcessesIdForName( executableName, pids ); 00252 int myPid = getpid(); 00253 int foundPid = 0; 00254 foreach ( int pid, pids ) { 00255 if ( myPid != pid ) { 00256 qDebug() << "activateWindowForProcess(): PID to activate:" << pid; 00257 foundPid = pid; 00258 break; 00259 } 00260 } 00261 if ( foundPid == 0 ) { 00262 return; 00263 } 00264 EnumWindowsStruct winStruct; 00265 winStruct.pid = foundPid; 00266 EnumWindows( EnumWindowsProc, (LPARAM)&winStruct ); 00267 if ( winStruct.windowId == 0 ) { 00268 return; 00269 } 00270 SetForegroundWindow( winStruct.windowId ); 00271 } 00272 00273 #endif // Q_WS_WIN
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 14 2012 04:44:53 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon May 14 2012 04:44:53 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.