Mac OSX: how to know if app automatically launched

2019-04-29 14:21发布

The users of my app can choose if they want (or not) launch my app at their session startup.

To do this, I use LSSharedFileListRef as described here : How do you make your App open at login?

What I want now is to know if my app has been launched automatically at session startup or via a click on the icon in the dock. Indeed, I have to do different actions in these two cases.

I have got the feeling that it is not possible to use the parameters of the notification in the following delegate method to do this:

- (void)applicationDidFinishLaunching:(NSNotification *)notification

I have seen the following posts but they do not help:

How can I know how my app was launched on Mac OS? => NO ANSWER except some links to other posts which do not help more...

Know if the user launched an app => I don't see how to set/get the "Y" parameter defined in this post

Mac OS X: open application at login, without showing the main window => deals with the fact to hide or not the main window at startup ; what I want is more general: how to know how the app has been launched?

Anybody can help me ?

Thanks !

4条回答
Evening l夕情丶
2楼-- · 2019-04-29 14:57

Open a Terminal window, type last | grep '^reboot' | awk 'END { print $3" "$4" "$5" "$6 }' to get the reboot time and match the time of the specific application launch, as @AnoopVaidya pointed out.

查看更多
贼婆χ
3楼-- · 2019-04-29 15:03

If application is set to run at startup, it will run (why not?). So you can save the application start time somewhere. And on the later run (for instance, user quit your application and run again) check if there is this parameter, and if it is later than system boot time, than application this time is not run automatically.

You can check the system boot time via [NSProcessInfo systemUptime]

查看更多
我命由我不由天
4楼-- · 2019-04-29 15:09

I'd check Parent Process ID. If it equals 1 it means it was launched by launchd at start up time.

struct kinfo_proc info;
size_t length = sizeof(struct kinfo_proc);
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
if (sysctl(mib, 4, &info, &length, NULL, 0) < 0)
    return OPProcessValueUnknown;
if (length == 0)
    return OPProcessValueUnknown;

 //info.kp_eproc.e_ppid is what you need 
查看更多
霸刀☆藐视天下
5楼-- · 2019-04-29 15:09

If you can't get @bioffe's answer to work, here it is again with a little more:

From: http://www.objectpark.net/parentpid.html

#include <sys/sysctl.h>

#define OPProcessValueUnknown UINT_MAX

//Returns the parent process id for the given process id (pid).
int OPParentIDForProcessID(int pid)
{
    struct kinfo_proc info;
    size_t length = sizeof(struct kinfo_proc);
    int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
    if (sysctl(mib, 4, &info, &length, NULL, 0) < 0)
        return OPProcessValueUnknown;
    if (length == 0)
        return OPProcessValueUnknown;
    return info.kp_eproc.e_ppid;
}
查看更多
登录 后发表回答