【问题标题】:Getting NSRunningApplication using a ProcessSerialNumber使用 ProcessSerialNumber 获取 NSRunningApplication
【发布时间】:2014-08-15 04:43:21
【问题描述】:

我有一个AppleEventDescriptor,我需要在其中获取发送应用程序的包标识符。 Apple Event 包含一个typeProcessSerialNumber,可以强制转换为ProcessSerialNumber

问题在于 GetProcessPID() 在 10.9 中已被弃用,并且似乎没有经过批准的方法来获得可用于使用 -runningApplicationWithProcessIdentifier: 实例化 NSRunningApplicationpid_t

我发现的所有其他选项都存在于 Processes.h 中,并且也已弃用。

我是否遗漏了什么,或者我必须忍受这个弃用警告?

【问题讨论】:

    标签: objective-c applescript nsrunningapplication


    【解决方案1】:

    Brian 和 Daniel 都提供了很好的线索,帮助我找到了正确的答案,但他们建议的内容有点不对劲。以下是我最终解决问题的方法。

    Brian 关于获取进程 ID 的 Apple 事件描述符而不是序列号的代码是正确的:

    // get the process id for the application that sent the current Apple Event
    NSAppleEventDescriptor *appleEventDescriptor = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
    NSAppleEventDescriptor* processSerialDescriptor = [appleEventDescriptor attributeDescriptorForKeyword:keyAddressAttr];
    NSAppleEventDescriptor* pidDescriptor = [processSerialDescriptor coerceToDescriptorType:typeKernelProcessID];
    

    问题是,如果您从该描述符中获取-int32Value,则返回值 0(即没有进程 ID。)我不知道为什么会发生这种情况:理论上,pid_tSInt32是有符号整数。

    相反,您需要获取字节值(以小端序存储)并将它们转换为进程 ID:

    pid_t pid = *(pid_t *)[[pidDescriptor data] bytes];
    

    从那时起,很容易获得有关正在运行的进程的信息:

    NSRunningApplication *runningApplication = [NSRunningApplication runningApplicationWithProcessIdentifier:pid];
    NSString *bundleIdentifer = [runningApplication bundleIdentifier];
    

    此外,Daniel 使用keySenderPIDAttr 的建议在很多情况下都行不通。在我们新的沙盒世界中,存储在那里的值可能是 /usr/libexec/lsboxd 的进程 ID,也称为启动服务沙盒守护程序,而不是发起事件的应用程序的进程 ID。

    再次感谢 Brian 和 Daniel 提供的帮助,促成了这个解决方案!

    【讨论】:

      【解决方案2】:

      您可以使用 Apple 事件描述符强制将 ProcessSerialNumber 描述符转换为 pid_t 描述符,如下所示:

      NSAppleEventDescriptor* processSerialDescriptor = [myEvent attributeDescriptorForKeyword:keyAddressAttr];
      NSAppleEventDescriptor* pidDescriptor = [processSerialDescriptor coerceToDescriptorType:typeKernelProcessID];
      pid_t pid = [pidDescriptor int32Value];
      

      【讨论】:

      • 另外,您可以使用 keySenderPIDAttr 直接获取 PID,而无需查找发送者并强制它:[[event attributeDescriptorForKeyword:keySenderPIDAttr] int32Value]
      猜你喜欢
      • 2018-01-12
      • 1970-01-01
      • 2015-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 2012-12-13
      • 1970-01-01
      相关资源
      最近更新 更多