अधिकांश प्रमुख डेस्कटॉप प्लेटफ़ॉर्म को कवर करते हुए, संभवतः ऐसा करने का यह सबसे स्वाभाविक तरीका है। मैं निश्चित नहीं हूं, लेकिन मेरा मानना है कि यह सभी बीएसडी के साथ काम करना चाहिए, न कि फ्रीबीएसडी, अगर आप उन सभी को कवर करने के लिए प्लेटफॉर्म मैक्रो चेक को बदलते हैं। अगर मैं कभी सोलारिस स्थापित करने के लिए इधर-उधर हो जाता हूं, तो मुझे उस प्लेटफ़ॉर्म को समर्थित सूची में जोड़ना होगा।
विंडोज पर पूर्ण UTF-8 समर्थन की सुविधा है, जो हर कोई उस दूर जाने के लिए पर्याप्त परवाह नहीं करता है।
procinfo / Win32 / procinfo.cpp
#ifdef _WIN32
#include "../procinfo.h"
#include <windows.h>
#include <tlhelp32.h>
#include <cstddef>
#include <vector>
#include <cwchar>
using std::string;
using std::wstring;
using std::vector;
using std::size_t;
static inline string narrow(wstring wstr) {
int nbytes = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.length(), NULL, 0, NULL, NULL);
vector<char> buf(nbytes);
return string{ buf.data(), (size_t)WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.length(), buf.data(), nbytes, NULL, NULL) };
}
process_t ppid_from_pid(process_t pid) {
process_t ppid;
HANDLE hp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hp, &pe)) {
do {
if (pe.th32ProcessID == pid) {
ppid = pe.th32ParentProcessID;
break;
}
} while (Process32Next(hp, &pe));
}
CloseHandle(hp);
return ppid;
}
string path_from_pid(process_t pid) {
string path;
HANDLE hm = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
MODULEENTRY32W me = { 0 };
me.dwSize = sizeof(MODULEENTRY32W);
if (Module32FirstW(hm, &me)) {
do {
if (me.th32ProcessID == pid) {
path = narrow(me.szExePath);
break;
}
} while (Module32NextW(hm, &me));
}
CloseHandle(hm);
return path;
}
#endif
procinfo / MacOSX / procinfo.cpp
#if defined(__APPLE__) && defined(__MACH__)
#include "../procinfo.h"
#include <libproc.h>
using std::string;
string path_from_pid(process_t pid) {
string path;
char buffer[PROC_PIDPATHINFO_MAXSIZE];
if (proc_pidpath(pid, buffer, sizeof(buffer)) > 0) {
path = string(buffer) + "\0";
}
return path;
}
#endif
procinfo / linux / procinfo.cpp
#ifdef __linux__
#include "../procinfo.h"
#include <cstdlib>
using std::string;
using std::to_string;
string path_from_pid(process_t pid) {
string path;
string link = string("/proc/") + to_string(pid) + string("/exe");
char *buffer = realpath(link.c_str(), NULL);
path = buffer ? : "";
free(buffer);
return path;
}
#endif
procinfo / FreeBSD / procinfo.cpp
#ifdef __FreeBSD__
#include "../procinfo.h"
#include <sys/sysctl.h>
#include <cstddef>
using std::string;
using std::size_t;
string path_from_pid(process_t pid) {
string path;
size_t length;
// CTL_KERN::KERN_PROC::KERN_PROC_PATHNAME(pid)
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, pid };
if (sysctl(mib, 4, NULL, &length, NULL, 0) == 0) {
path.resize(length, '\0');
char *buffer = path.data();
if (sysctl(mib, 4, buffer, &length, NULL, 0) == 0) {
path = string(buffer) + "\0";
}
}
return path;
}
#endif
procinfo / procinfo.cpp
#include "procinfo.h"
#ifdef _WiN32
#include <process.h>
#endif
#include <unistd.h>
#include <cstddef>
using std::string;
using std::size_t;
process_t pid_from_self() {
#ifdef _WIN32
return _getpid();
#else
return getpid();
#endif
}
process_t ppid_from_self() {
#ifdef _WIN32
return ppid_from_pid(pid_from_self());
#else
return getppid();
#endif
}
string dir_from_pid(process_t pid) {
string fname = path_from_pid(pid);
size_t fp = fname.find_last_of("/\\");
return fname.substr(0, fp + 1);
}
string name_from_pid(process_t pid) {
string fname = path_from_pid(pid);
size_t fp = fname.find_last_of("/\\");
return fname.substr(fp + 1);
}
procinfo / procinfo.h
#ifdef _WiN32
#include <windows.h>
typedef DWORD process_t;
#else
#include <sys/types.h>
typedef pid_t process_t;
#endif
#include <string>
/* windows-only helper function */
process_t ppid_from_pid(process_t pid);
/* get current process process id */
process_t pid_from_self();
/* get parent process process id */
process_t ppid_from_self();
/* std::string possible_result = "C:\\path\\to\\file.exe"; */
std::string path_from_pid(process_t pid);
/* std::string possible_result = "C:\\path\\to\\"; */
std::string dir_from_pid(process_t pid);
/* std::string possible_result = "file.exe"; */
std::string name_from_pid(process_t pid);
यह बहुत अधिक किसी भी प्रक्रिया आईडी के निष्पादन योग्य के लिए पूर्ण पथ प्राप्त करने की अनुमति देता है, विंडोज पर छोड़कर कुछ प्रक्रियाएं सुरक्षा विशेषताओं के साथ होती हैं जो बस इसे अनुमति नहीं देंगी, इसलिए wysiwyg, यह समाधान सही नहीं है।
यह पता करने के लिए कि प्रश्न क्या अधिक सटीक पूछ रहा था, आप ऐसा कर सकते हैं:
procinfo.cpp
#include "procinfo/procinfo.h"
#include <iostream>
using std::string;
using std::cout;
using std::endl;
int main() {
cout << dir_from_pid(pid_from_self()) << endl;
return 0;
}
इस आदेश के साथ उपरोक्त फ़ाइल संरचना बनाएँ:
procinfo.sh
cd "${0%/*}"
g++ procinfo.cpp procinfo/procinfo.cpp procinfo/win32/procinfo.cpp procinfo/macosx/procinfo.cpp procinfo/linux/procinfo.cpp procinfo/freebsd/procinfo.cpp -o procinfo.exe
ऊपर सूचीबद्ध फ़ाइलों की एक प्रति डाउनलोड करने के लिए:
git clone git://github.com/time-killer-games/procinfo.git
अधिक क्रॉस-प्लेटफ़ॉर्म प्रक्रिया से संबंधित अच्छाई के लिए:
https://github.com/time-killer-games/enigma-dev
अधिकांश कार्यों की सूची के लिए रीडमी देखें।