10
10
#include < QJsonObject>
11
11
12
12
#include " utilities.h"
13
- #include " version.h"
13
+
14
+ #ifdef Q_OS_WINDOWS
15
+ QString printErrorMessage (DWORD errorCode) {
16
+ LPVOID lpMsgBuf;
17
+
18
+ DWORD dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
19
+ FORMAT_MESSAGE_FROM_SYSTEM |
20
+ FORMAT_MESSAGE_IGNORE_INSERTS;
21
+
22
+ DWORD dwLanguageId = MAKELANGID (LANG_ENGLISH, SUBLANG_ENGLISH_US);
23
+
24
+ FormatMessageW (
25
+ dwFlags,
26
+ NULL ,
27
+ errorCode,
28
+ dwLanguageId,
29
+ (LPWSTR)&lpMsgBuf,
30
+ 0 ,
31
+ NULL
32
+ );
33
+
34
+ QString errorMsg = QString::fromWCharArray ((LPCWSTR)lpMsgBuf);
35
+ LocalFree (lpMsgBuf);
36
+ return errorMsg.trimmed ();
37
+ }
38
+
39
+ QString Utils::getNextDriverLetter ()
40
+ {
41
+ DWORD drivesBitmask = GetLogicalDrives ();
42
+ if (drivesBitmask == 0 ) {
43
+ DWORD error = GetLastError ();
44
+ qDebug () << " GetLogicalDrives failed. Error code:" << error;
45
+ return " " ;
46
+ }
47
+
48
+ QString letters = " FGHIJKLMNOPQRSTUVWXYZ" ;
49
+ QString availableLetter;
50
+
51
+ for (int i = letters.size () - 1 ; i >= 0 ; --i) {
52
+ QChar letterChar = letters.at (i);
53
+ int driveIndex = letterChar.toLatin1 () - ' A' ;
54
+
55
+ if ((drivesBitmask & (1 << driveIndex)) == 0 ) {
56
+ availableLetter = letterChar;
57
+ break ;
58
+ }
59
+ }
60
+
61
+ if (availableLetter.isEmpty ()) {
62
+ qDebug () << " Can't find free drive letter" ;
63
+ return " " ;
64
+ }
65
+
66
+ return availableLetter;
67
+ }
68
+ #endif
14
69
15
70
QString Utils::getRandomString (int len)
16
71
{
@@ -108,30 +163,34 @@ QString Utils::usrExecutable(const QString &baseName)
108
163
bool Utils::processIsRunning (const QString &fileName, const bool fullFlag)
109
164
{
110
165
#ifdef Q_OS_WIN
111
- QProcess process ;
112
- process. setReadChannel (QProcess::StandardOutput);
113
- process. setProcessChannelMode (QProcess::MergedChannels) ;
114
- process. start ( " wmic.exe " ,
115
- QStringList () << " /OUTPUT:STDOUT "
116
- << " PROCESS "
117
- << " get "
118
- << " Caption " );
119
- process. waitForStarted ();
120
- process. waitForFinished ();
121
- QString processData (process. readAll () );
122
- QStringList processList = processData. split ( QRegularExpression ( " [ \r\n ] " ), Qt::SkipEmptyParts) ;
123
- foreach ( const QString &rawLine, processList) {
124
- const QString line = rawLine. simplified ();
125
- if (line. isEmpty ()) {
126
- continue ;
127
- }
166
+ HANDLE hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 ) ;
167
+ if (hSnapshot == INVALID_HANDLE_VALUE) {
168
+ qWarning () << " Utils::processIsRunning error CreateToolhelp32Snapshot " ;
169
+ return false ;
170
+ }
171
+
172
+ PROCESSENTRY32W pe32;
173
+ pe32. dwSize = sizeof (PROCESSENTRY32W );
174
+
175
+ if (! Process32FirstW (hSnapshot, &pe32)) {
176
+ CloseHandle (hSnapshot );
177
+ qWarning () << " Utils::processIsRunning error Process32FirstW " ;
178
+ return false ;
179
+ }
180
+
181
+ do {
182
+ QString exeFile = QString::fromWCharArray (pe32. szExeFile );
128
183
129
- if (line == fileName) {
184
+ if (exeFile.compare (fileName, Qt::CaseInsensitive) == 0 ) {
185
+ CloseHandle (hSnapshot);
130
186
return true ;
131
187
}
132
- }
188
+ } while (Process32NextW (hSnapshot, &pe32));
189
+
190
+ CloseHandle (hSnapshot);
133
191
return false ;
134
- #elif defined(Q_OS_IOS)
192
+
193
+ #elif defined(Q_OS_IOS) || defined(Q_OS_ANDROID)
135
194
return false ;
136
195
#else
137
196
QProcess process;
@@ -149,13 +208,45 @@ bool Utils::processIsRunning(const QString &fileName, const bool fullFlag)
149
208
#endif
150
209
}
151
210
152
- void Utils::killProcessByName (const QString &name)
211
+ bool Utils::killProcessByName (const QString &name)
153
212
{
154
213
qDebug ().noquote () << " Kill process" << name;
155
214
#ifdef Q_OS_WIN
156
- QProcess::execute (" taskkill" , QStringList () << " /IM" << name << " /F" );
157
- #elif defined Q_OS_IOS
158
- return ;
215
+ HANDLE hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0 );
216
+ if (hSnapshot == INVALID_HANDLE_VALUE)
217
+ return false ;
218
+
219
+ PROCESSENTRY32W pe32;
220
+ pe32.dwSize = sizeof (PROCESSENTRY32W);
221
+
222
+ bool success = false ;
223
+
224
+ if (Process32FirstW (hSnapshot, &pe32)) {
225
+ do {
226
+ QString exeFile = QString::fromWCharArray (pe32.szExeFile );
227
+
228
+ if (exeFile.compare (name, Qt::CaseInsensitive) == 0 ) {
229
+ HANDLE hProcess = OpenProcess (PROCESS_TERMINATE, FALSE , pe32.th32ProcessID );
230
+ if (hProcess != NULL ) {
231
+ if (TerminateProcess (hProcess, 0 )) {
232
+ success = true ;
233
+ } else {
234
+ DWORD error = GetLastError ();
235
+ qCritical () << " Can't terminate process" << exeFile << " (PID:" << pe32.th32ProcessID << " ). Error:" << printErrorMessage (error);
236
+ }
237
+ CloseHandle (hProcess);
238
+ } else {
239
+ DWORD error = GetLastError ();
240
+ qCritical () << " Can't open process for termination" << exeFile << " (PID:" << pe32.th32ProcessID << " ). Error:" << printErrorMessage (error);
241
+ }
242
+ }
243
+ } while (Process32NextW (hSnapshot, &pe32));
244
+ }
245
+
246
+ CloseHandle (hSnapshot);
247
+ return success;
248
+ #elif defined Q_OS_IOS || defined(Q_OS_ANDROID)
249
+ return false ;
159
250
#else
160
251
QProcess::execute (QString (" pkill %1" ).arg (name));
161
252
#endif
0 commit comments