/* Copyright (c) 2015 Stanislaw Halik * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ #pragma once #include #include #if defined _WIN32 #include #include template static QStringList get_all_executable_names() { QStringList ret; HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (h == INVALID_HANDLE_VALUE) return ret; PROCESSENTRY32 e; e.dwSize = sizeof(e); if (Process32First(h, &e) != TRUE) { CloseHandle(h); return ret; } do { ret.append(e.szExeFile); } while (Process32Next(h, &e) == TRUE); CloseHandle(h); return ret; } #elif defined __APPLE__ #include #include #include #include #include #include #include template static QStringList get_all_executable_names() { QStringList ret; std::vector vec; while (true) { int numproc = proc_listpids(PROC_ALL_PIDS, 0, nullptr, 0); if (numproc == -1) { qDebug() << "proc_listpids numproc failed" << errno; return ret; } vec.resize(numproc); int cnt = proc_listpids(PROC_ALL_PIDS, 0, &vec[0], sizeof(int) * numproc); if (cnt <= numproc) { std::vector arglist; int mib[2] { CTL_KERN, KERN_ARGMAX }; size_t sz = sizeof(int); int maxarg = 0; if (sysctl(mib, 2, &maxarg, &sz, NULL, 0) == -1) { qDebug() << "sysctl KERN_ARGMAX" << errno; return ret; } arglist.resize(maxarg); for (int i = 0; i < numproc; i++) { size_t maxarg_ = (size_t)maxarg; int mib[3] { CTL_KERN, KERN_PROCARGS2, vec[i] }; if (sysctl(mib, 3, &arglist[0], &maxarg_, NULL, 0) == -1) { //qDebug() << "sysctl KERN_PROCARGS2" << vec[i] << errno; continue; } QStringList cmdline; for (unsigned j = sizeof(int) + strlen(&arglist[sizeof(int)]); j < maxarg_; j++) { QString arg(&arglist[j]); if (arg.size() != 0) { cmdline << arg; j += arg.size(); } } if (cmdline.size() > 0) { int idx = cmdline[0].lastIndexOf('/'); if (idx != -1) { QString tmp = cmdline[0].mid(idx+1); if (cmdline.size() > 1 && (tmp == "wine.bin" || tmp == "wine")) { idx = cmdline[1].lastIndexOf('/'); if (idx == -1) idx = cmdline[1].lastIndexOf('\\'); if (idx != -1) { ret.append(cmdline[1].mid(idx+1)); } else ret.append(cmdline[1]); } else { ret.append(tmp); } } else ret.append(cmdline[0]); } } return ret; } } } #elif defined __linux #include #include template static QStringList get_all_executable_names() { QStringList ret; proc_t** procs = readproctab(PROC_FILLCOM); if (procs == nullptr) { qDebug() << "readproctab" << errno; return ret; } for (int i = 0; procs[i]; i++) { // note, wine sets argv[0] so no parsing like in OSX case auto proc = procs[i]; if (proc->cmdline && proc->cmdline[0]) { QString tmp(proc->cmdline[0]); const int idx = std::max(tmp.lastIndexOf('\\'), tmp.lastIndexOf('/')); tmp = tmp.mid(idx == -1 ? 0 : idx+1); ret.append(tmp); } freeproc(procs[i]); } free(procs); return ret; } #else template static QStringList get_all_executable_names() { return QStringList(); } #endif