在运行时在Mac OS X上设置进程名称

Mar*_*ser 19 macos posix process

我想,因为它似乎在改变我的进程的名称ps,并Activity Monitor在运行时.我发现有几个笔记说没有可移植的方法(我不关心).

这是我尝试过的.这些方法都不适合我.

  • 改变argv[0](似乎是在某些Unix系统上的方式)
  • 调用 [[NSProcessInfo processInfo] setProcessName:@"someName"]
  • 调用setprogname(调用getprogname返回我设置的名称,但这是无关紧要的)

我还读到了一个被调用的函数setproctitle,stdlib.h如果它可用,应该定义它,但它不存在.

必须有一种方法可以实现这一点,因为QTKitServer-- QuickTime Player X的无面解码器 - 在其进程名称中具有相应的QuickTime Player的PID.

有没有人知道如何做到这一点?我非常喜欢使用Core Foundation或POSIXy方法来实现Objective-C方法.

谢谢,

马尔科

编辑:如果它有任何相关性,我使用的是Mac OS X 10.6.5和Xcode 3.2.5

nal*_*ply 11

有充分的理由更改进程名称.Java软件应该更改进程名称,因为在运行不同的java工具时,我想查看哪个java进程适用于哪个工具.

Chromium这样做:http://src.chromium.org/viewvc/chrome/trunk/src/base/mac/mac_util.mm.

Node.js使用相同的代码来实现Process.title = 'newtitle':https://github.com/joyent/node/blob/master/src/platform_darwin_proctitle.cc

注意:如果有人su对不同的未登录用户执行此操作,则会失败:https://github.com/joyent/node/issues/1727

这里的源代码完全是复杂的荣耀.顺便说一句,有人告诉我它也适用于Mac OS X Lion,也失败了su.

// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
void SetProcessName(CFStringRef process_name) {
  if (!process_name || CFStringGetLength(process_name) == 0) {
    NOTREACHED() << "SetProcessName given bad name.";
    return;
  }

  if (![NSThread isMainThread]) {
    NOTREACHED() << "Should only set process name from main thread.";
    return;
  }

  // Warning: here be dragons! This is SPI reverse-engineered from WebKit's
  // plugin host, and could break at any time (although realistically it's only
  // likely to break in a new major release).
  // When 10.7 is available, check that this still works, and update this
  // comment for 10.8.

  // Private CFType used in these LaunchServices calls.
  typedef CFTypeRef PrivateLSASN;
  typedef PrivateLSASN (*LSGetCurrentApplicationASNType)();
  typedef OSStatus (*LSSetApplicationInformationItemType)(int, PrivateLSASN,
                                                          CFStringRef,
                                                          CFStringRef,
                                                          CFDictionaryRef*);

  static LSGetCurrentApplicationASNType ls_get_current_application_asn_func =
      NULL;
  static LSSetApplicationInformationItemType
      ls_set_application_information_item_func = NULL;
  static CFStringRef ls_display_name_key = NULL;

  static bool did_symbol_lookup = false;
  if (!did_symbol_lookup) {
    did_symbol_lookup = true;
    CFBundleRef launch_services_bundle =
        CFBundleGetBundleWithIdentifier(CFSTR("com.apple.LaunchServices"));
    if (!launch_services_bundle) {
      LOG(ERROR) << "Failed to look up LaunchServices bundle";
      return;
    }

    ls_get_current_application_asn_func =
        reinterpret_cast<LSGetCurrentApplicationASNType>(
            CFBundleGetFunctionPointerForName(
                launch_services_bundle, CFSTR("_LSGetCurrentApplicationASN")));
    if (!ls_get_current_application_asn_func)
      LOG(ERROR) << "Could not find _LSGetCurrentApplicationASN";

    ls_set_application_information_item_func =
        reinterpret_cast<LSSetApplicationInformationItemType>(
            CFBundleGetFunctionPointerForName(
                launch_services_bundle,
                CFSTR("_LSSetApplicationInformationItem")));
    if (!ls_set_application_information_item_func)
      LOG(ERROR) << "Could not find _LSSetApplicationInformationItem";

    CFStringRef* key_pointer = reinterpret_cast<CFStringRef*>(
        CFBundleGetDataPointerForName(launch_services_bundle,
                                      CFSTR("_kLSDisplayNameKey")));
    ls_display_name_key = key_pointer ? *key_pointer : NULL;
    if (!ls_display_name_key)
      LOG(ERROR) << "Could not find _kLSDisplayNameKey";

    // Internally, this call relies on the Mach ports that are started up by the
    // Carbon Process Manager.  In debug builds this usually happens due to how
    // the logging layers are started up; but in release, it isn't started in as
    // much of a defined order.  So if the symbols had to be loaded, go ahead
    // and force a call to make sure the manager has been initialized and hence
    // the ports are opened.
    ProcessSerialNumber psn;
    GetCurrentProcess(&psn);
  }
  if (!ls_get_current_application_asn_func ||
      !ls_set_application_information_item_func ||
      !ls_display_name_key) {
    return;
  }

  PrivateLSASN asn = ls_get_current_application_asn_func();
  // Constant used by WebKit; what exactly it means is unknown.
  const int magic_session_constant = -2;
  OSErr err =
      ls_set_application_information_item_func(magic_session_constant, asn,
                                               ls_display_name_key,
                                               process_name,
                                               NULL /* optional out param */);
  LOG_IF(ERROR, err) << "Call to set process name failed, err " << err;
}
Run Code Online (Sandbox Code Playgroud)

编辑:这是一个复杂而混乱的问题.

在OS X上没有setproctitle(3).一个人必须写入argv数组(丑陋且有点危险,因为有可能用伪造的东西覆盖一些环境变量).做得对,它的效果非常好.

此外,Apple还有ActivityMonitor应用程序,类似于Windows下的任务管理器.上面的代码操纵ActivityMonitor,但Apple似乎没有鼓励这种操作(因此使用了未记录的函数).

重要提示:ps和ActivityMonitor不显示相同的信息.

同样重要的是:如果您没有GUI,则ActivityMonitor不可用.如果您进入远程Apple盒并且没有人通过GUI登录,则会发生这种情况.可悲的是,Apple IMO存在一个错误.只查询是否有GUI向stderr发送恼人的警告消息.

简介:如果需要更改ActivityMonitor,请使用上面的代码.如果您没有GUI的情况并且不喜欢stderr上的警告,请在调用期间将stderr临时重定向到/ dev/null SetProcessName.如果您需要更改ps信息,请写入argv.


yai*_*chu 5

您可以使用lsappinfomacOS 附带的工具,至少从 10.6 到现在(10.13.2):

贝壳:

lsappinfo setinfo <PID> --name <NAME>
Run Code Online (Sandbox Code Playgroud)

C++:

#include <sstream>
#include <string>
#include <stdlib.h>

void setProcessName (pid_t pid, std::string name)
{
    std::ostringstream cmd;
    cmd << "/usr/bin/lsappinfo setinfo " << pid;
    cmd << " --name \"" << name << "\"";
    system (cmd.str().c_str());
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为这仅适用于 GUI 应用程序,不适用于从终端运行的脚本,对于那些您将得到 err=-600 意味着不是有效 PID 的应用程序 (4认同)
  • 我尝试使用它来重命名 Python 进程,但没有成功。`lsappinfo processList` 的输出只列出图形应用程序,而不是在 shell 上运行的进程,所以我认为它只适用于那种应用程序。 (3认同)
  • 我在 Catalina 上看到 `err=-600` (3认同)