我有一个可以使用不同参数多次启动的应用程序,我需要一种方法让一个应用程序实例查看其他参数的参数(主要是为了确保两个实例不使用相同的参数运行并且专注于类似的实例)。我目前正在使用pid文件,但想知道是否有办法以某种方式标记正在运行的实例从其他实例可见。我为每个实例更改CFBundleName,但它似乎不可见(只是原始名称,而不是更改)。有比pid文件更好的方法吗?
一些细节:主应用程序是一个容器,它运行另一个可以访问容器的内部应用程序(即更改CFBundleName等)。
答案 0 :(得分:1)
我假设“参数”是指命令行参数?您可以使用popen运行ps,然后捕获并解析输出以获取所需的信息。如果您已经知道其他进程的pid,那么您可以查找它,并使用grep获取应用程序的名称以减少您需要查看的输出。
这是一个例子。你可以看到参数。
$ /bin/ps -Axo pid,args|grep TextWrangler|grep -v grep
643 /Applications/TextWrangler.app/Contents/MacOS/TextWrangler
645 /Applications/TextWrangler.app/Contents/Helpers/Crash Reporter.app/Contents/Helpers/crash-catcher -targetPID 643 -targetBundlePath /Applications/TextWrangler.app -showEmailAddressField 1
以下是如何使用popen,并将输出传递给grep以查找命令名,pid和参数:
std::string cmdline("/bin/ps -Axo pid,args|grep '");
cmdline += appName;
cmdline += "'|grep -v grep";
// The output will look like: "S 428 APPNAME ARGS" with one space between entries.
// popen creates a pipe so we can read the output of the program we are invoking.
FILE *instream = popen(cmdline.c_str(), "r");
if(instream) {
// read the output, one line at a time.
const int MAX_BUFFER = 1024;
char buffer[MAX_BUFFER];
while (!feof(instream)){
if (fgets(buffer, MAX_BUFFER, instream) != NULL) {
std::string temp(buffer);
temp.trim(); // Get rid of leading and trailing whitespace. (Exercise for the reader.)
if(!temp.empty()) {
// First col is the state.
std::string::size_type i = temp.find(" ");
std::string state = temp.substr(0, i);
// Skip zombies.
if("Z" != state) {
// Second col is the pid.
// Advance i to the next char after the space.
++i;
std::string::size_type j = temp.find(" ", i);
std::string pidStr = temp.substr(i, j - i);
// Here we know the pid for APPNAME. You can further parse for the command line arguments here.
}
}
}
}
// close the pipe.
pclose(instream);