2010-11-18 15 views
15

पर मैक ओएस एक्स पर प्रक्रिया का नाम सेट करना मैं अपनी प्रक्रिया का नाम बदलने की कोशिश कर रहा हूं क्योंकि यह ps और Activity Monitor रनटाइम पर दिखाई देता है। मुझे कई नोट्स मिले कि ऐसा करने के लिए कोई पोर्टेबल तरीका नहीं है (जिसकी मुझे परवाह नहीं है)।रनटाइम

यहां मैंने जो कोशिश की है। इनमें से कोई भी दृष्टिकोण मेरे लिए काम नहीं करता है।

  • argv[0] बदलने
  • कॉलिंग [[NSProcessInfo processInfo] setProcessName:@"someName"]
  • कॉलिंग setprogname (कुछ यूनिक्स प्रणालियों पर जाने का रास्ता हो रहा है) (getprogname रिटर्न नाम मैं सेट बुला, लेकिन वह अप्रासंगिक है)

मैंने setproctitle नामक फ़ंक्शन के बारे में भी पढ़ा है जिसे stdlib.h में परिभाषित किया जाना चाहिए, लेकिन यह वहां नहीं है।

इसे पूरा करने का एक तरीका होना चाहिए क्योंकि QTKitServer - क्विकटाइम प्लेयर एक्स के लिए बेकार डिकोडर - इसके प्रोसेस नाम में इसके संबंधित क्विकटाइम प्लेयर की पीआईडी ​​है।

क्या किसी के पास इस बारे में कोई जानकारी है कि इसे कैसे पूरा किया जाए? ऐसा करने के लिए मैं एक उद्देश्य-सी विधि पर कोर फाउंडेशन या POSIXy तरीका बहुत पसंद करेंगे।

धन्यवाद,

मार्को

संपादित करें: अच्छे कारणों यदि यह प्रासंगिक किसी भी तरह से है, मैं मैक ओएस एक्स 10.6.5 और Xcode 3.2.5 का उपयोग कर रहा

+0

@ एलेक्स ब्राउन (जिन्होंने टैग संपादित किए हैं): मैंने जानबूझकर इस प्रश्न के लिए टैग "पॉज़िक्स" के बजाय "मैक" पर सेट किया है क्योंकि मुझे ऐसा करने के लिए मिले पॉसिक्स-तरीके मेरे लिए काम नहीं करते थे ('argv [0] ' और 'setproctitle() ')। –

उत्तर

11

रहे हैं प्रक्रिया का नाम बदलने के लिए। जावा सॉफ़्टवेयर को प्रक्रिया नामों को बदलना चाहिए क्योंकि विभिन्न जावा उपकरण चलाते समय मैं देखना चाहता हूं कि कौन सी जावा प्रक्रिया किस उपकरण के लिए है।

क्रोमियम यह करता है: 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

यहाँ अपनी पूरी में स्रोत कोड जटिल महिमा वैसे, किसी ने मुझे बताया कि यह मैक ओएस एक्स शेर के लिए भी काम करता है और 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; 
} 

संपादित: यह एक जटिल और भ्रामक समस्या है।

ओएस एक्स पर कोई सेटप्रोक्टीटल (3) नहीं है। किसी को argv सरणी (बदसूरत और थोड़ा खतरनाक में लिखना है क्योंकि फर्जी सामान के साथ कुछ पर्यावरण चर को ओवरराइट करना संभव है)। सही ढंग से हो गया यह बहुत अच्छी तरह से काम करता है।

इसके अतिरिक्त ऐप्पल में गतिविधि मॉनिटर एप्लिकेशन है, जो विंडोज के तहत टास्क मैनेजर जैसा कुछ है। उपरोक्त कोड गतिविधि मॉनिटर में हेरफेर करता है लेकिन यह हेरफेर एप्पल द्वारा प्रोत्साहित नहीं किया जाता है (इसलिए अनियंत्रित कार्यों का उपयोग)।

महत्वपूर्ण: पीएस और गतिविधि मॉनिटर एक ही जानकारी नहीं दिखाता है।

यह भी महत्वपूर्ण है: यदि आपके पास GUI नहीं है तो गतिविधि मॉनिटर उपलब्ध नहीं है। ऐसा तब हो सकता है जब आप रिमोट ऐप्पल बॉक्स में एसएसएच करते हैं और जीयूआई द्वारा लॉग इन नहीं किया जाता है। अफसोस की बात है कि ऐप्पल आईएमओ द्वारा एक बग है। बस पूछताछ कर रहा है कि क्या कोई GUI stderr को एक कष्टप्रद चेतावनी संदेश भेजता है।

सारांश: यदि आपको गतिविधि मॉनिटर बदलने की आवश्यकता है, तो ऊपर दिए गए कोड का उपयोग करें। यदि आपके पास stderr पर GUI-कम स्थितियां और नापसंद चेतावनियां हैं, तो SetProcessName की कॉल के दौरान अस्थायी रूप से/dev/null पर stderr को रीडायरेक्ट करें। यदि आपको पीएस जानकारी बदलने की जरूरत है, तो argv में लिखें।

+0

धन्यवाद, यह एक आकर्षण की तरह काम करता है! –

+1

वैसे, क्या आपका प्रोजेक्ट ओपन सोर्स है? यदि नहीं, तो कॉपीराइट के बारे में सोचें क्योंकि कोड क्रोमियम प्रोजेक्ट से संबंधित है। – nalply

+0

नहीं, जिस परियोजना के लिए मुझे इसकी आवश्यकता है वह खुला स्रोत नहीं है। लेकिन चिंता न करें, मैं कोड को कॉपी नहीं करूँगा जैसा कि यह है। जो मैं खोज रहा था वह अनिवार्य रूप से जानकारी है जो _LSSetAplicationInformationItem() को कॉल करता है जो मुझे चाहिए। कोड जो मैं उस फ़ंक्शन के चारों ओर लिखूंगा वह हमारी अपनी लाइब्रेरी के संदर्भ में काफी अलग दिखाई देगा और इसलिए जीपीएल का उल्लंघन नहीं करना चाहिए। –

2

आप lsappinfo उपकरण जो कम से कम 10.6 के बाद से MacOS के साथ आता है (10.13.2) का उपयोग करें और ऊपर दिन पेश करने के लिए कर सकते हैं:

शेल:

lsappinfo setinfo <PID> --name <NAME> 

सी ++:

#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()); 
} 
+1

वाह, मुझे इस आदेश के बारे में पता नहीं था, बहुत दिलचस्प लगता है। इस तरह के नाम को एक आकर्षण की तरह काम करना! @ lsappinfo' @ nalply के कोड द्वारा वर्णित कार्यक्षमता के लिए फ्रंट-एंड प्रतीत होता है। सात साल बाद, ऐसा करने की आवश्यकता समाप्त हो गई है, हालांकि –

+0

मुझे डर था कि पिछले जवाब में कोड काम करना बंद कर सकता है या रखरखाव की आवश्यकता हो सकती है, इसलिए उस जवाब को देखने के बाद मैंने देखा और 'lsappinfo' के बारे में पाया। उम्मीद है कि एक "गुप्त एपीआई" की बजाय सार्वजनिक एपीआई होने के कारण यह टूल भविष्य के ओएस में अच्छी तरह से काम करेगा ... – yairchu