在我看来Linux使用/ proc/self/exe很容易.但我想知道是否有一种方便的方法可以在C/C++中使用跨平台接口查找当前应用程序的目录.我已经看到一些项目与argv [0]混在一起,但它似乎并不完全可靠.
如果你曾经不得不支持Mac OS X,它没有/ proc /,你会做什么?使用#ifdefs隔离特定于平台的代码(例如NSBundle)?或者尝试从argv [0],$ PATH等等推断出可执行文件的路径,冒着在边缘情况下发现错误的风险?
在Linux上,应用程序可以通过查询轻松获得其绝对路径/proc/self/exe.在FreeBSD上,它更复杂,因为你必须建立一个sysctl调用:
int mib[4];
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
char buf[1024];
size_t cb = sizeof(buf);
sysctl(mib, 4, buf, &cb, NULL, 0);
Run Code Online (Sandbox Code Playgroud)
但它仍然是完全可行的.然而,我找不到在OS X上为命令行应用程序确定这一点的方法.如果您是在应用程序包中运行[[NSBundle mainBundle] bundlePath],则可以通过运行来确定它,但由于命令行应用程序不在捆绑包中,因此无效.
(注意:咨询argv[0]不是一个合理的答案,因为,如果从符号链接启动,argv[0]将是那个符号链接 - 不是所谓的可执行文件的最终路径.argv[0]如果一个哑的应用程序使用一个exec()调用而忘记正确初始化argv ,也可能会失败 我在野外见过的.)
我知道我可以PID通过使用来获取进程ps,但是如何找到该进程的完整路径?
我是 GO 和 mac 的新手,我正在尝试使用 sysctl 来查找正在运行的进程的完整路径名。
kprocs, err := unix.SysctlKinfoProcSlice("kern.proc.all")
if err != nil {
fmt.Println("error: ", err)
}
for _, proc := range kprocs {
name := string(proc.Proc.P_comm[:])
pid := proc.Proc.P_pid
extName, err := unix.SysctlKinfoProc("kern.proc.pathname", int(pid))
if err != nil {
fmt.Println("error: ", err)
}
Run Code Online (Sandbox Code Playgroud)
并收到错误:没有这样的文件或目录
我正确使用这个功能吗?
编辑
如果我像这样运行进程: ./processName ,那么我没有得到它的完整路径,例如 /Users/username/go/src/processName - 这就是我需要的。所有的解决方案ps都会给出相对路径,而我需要一些给出过程的绝对路径的东西。
使用案例:我以" user1 " 身份登录并启动Safari,然后点击右上角的" user1 "并将用户切换为" user2 ".现在,我正在尝试检测Safari是否正在运行" user1 ",但我无法使用标准调用.我使用OS X 10.8 Mountain Lion来开发和运行我的代码.
我使用了以下但是徒劳无功:
[[NSWorkspace sharedWorkspace] runningApplications] - 列表中没有SafariGetNextProcess() - Safari没有出现GetProcessForPID() - 我收到错误"没有这样的过程"但是当我ps -aef | grep Safari从终端做一个时,我可以看到Safari.(这不仅适用于Safari,也适用于其他应用程序.)
有人可以请帮助.非常感谢你.
macos objective-c switch-user nsworkspace nsrunningapplication
macos ×5
c ×2
c++ ×1
executable ×1
go ×1
linux ×1
nsworkspace ×1
objective-c ×1
path ×1
pid ×1
process ×1
ps ×1
switch-user ×1
unix ×1