Search code examples
iphonebundlejailbreaklaunchpid

get the bundle id of app from PID in ios


I am trying to get a list of all the background apps currently running on the iphone. I am able to do so but what I actually get is the a list of all the background app's PIDs.

So I have two questions,

First I am able to launch an app with its bundle id but not with its PID. Is launching an app with PID possible?

Second Is there a way to access the apps bundle id if all i have is its PID?

I understand this can be done on the mac with

[[NSRunningApplication runningApplicationWithProcessIdentifier:pid] bundleIdentifier]

but can it be done on the iphone?


Solution

  • I couldn't find NSRunningApplication in the iOS (public or private) 5.0 headers (I'm pretty sure I checked everywhere, but I could be wrong ...)

    There's probably multiple ways to do this, but one of these should work ...

    First, get information about the running processes. If you can't get the bundle ID, but can get the path to the app, then that's good enough. You could do that in one of a few ways:

    1) See this answer on stack overflow or maybe this one. I'm not sure the executable path is available with these techniques ... I didn't explore them in depth.

    2) You can get process information through the ps shell command. For example, with a ps -Aef command at the command line:

    iPhone4:~/Applications/8AA99EA8-9CFC-4C17-9BD1-7C2812EDAAD4/Starbucks.app mobile$ ps -Aef
      UID   PID  PPID   C     STIME TTY           TIME CMD
    
      501   281     1   0   0:00.00 ??         1:02.39 /Applications/MobilePhone.app/MobilePhone
      501   282     1   0   0:00.00 ??         2:26.40 /Applications/MobileMail.app/MobileMail
      501   479     1   0   0:00.00 ??         5:45.01 /Applications/MobileSafari.app/MobileSafari
      501   490     1   0   0:00.00 ??         0:45.62 /Applications/Music~iphone.app/Music~iphone
      501   912     1   0   0:00.00 ??         0:17.65 /var/mobile/Applications/8AA99EA8-9CFC-4237-9BD1-7C2812AAAAD4/Starbucks.app/Starbucks
      501  1933     1   0   0:00.00 ??         0:51.72 /var/mobile/Applications/9962D9AE-087C-4D2E-A6AB-151230DBCDB09/Skype.app/Skype
      501  2106     1   0   0:00.00 ??         1:11.68 /var/mobile/Applications/20DCED79-B1EE-48F4-B3E1-75E9C25A0908C/Netflix.app/Netflix
      501  2259     1   0   0:00.00 ??         0:03.83 /Applications/Stocks.app/Stocks
      501  2292     1   0   0:00.00 ??         0:07.05 /var/mobile/Applications/33713030-9D3D-4BAC-8182-282973B2E5E0/ZillowMap.app/ZillowMap
      501  2568     1   0   0:00.00 ??         0:12.91 /var/mobile/Applications/55216130-10D8-498C-B477-AD18A4982E18/eBay.app/eBay
      501  2587     1   0   0:00.00 ??         0:05.10 /var/mobile/Applications/2A8DEAAD-8244-45C0-BEA9-20DA290B0117/Moviefone.app/Moviefone
    

    I removed some of the output, but you can see some of the apps running (*.app).

    So, in your app, you could run "ps -Aef >> /var/mobile/Library/MyAppName/ps.txt" with a system or exec call, sending the output to a temporary file. Then, parse that file to get the results.

    3) I also found a copy of the Darwin open source online, and hacked it up a little to collect this kind of data into a C string buffer, that can be parsed programmatically. Get the header and .c file here:

    darwin.c

    darwin.h

    Include those two files in your Xcode project, and #include "darwin.h". Then, use it like so:

    OS_initialize();
    size_t buffSize = 20000;  // you may need to increase this!
    char buffer[buffSize];
    
    int bytes = OS_get_table(buffer, buffSize);
    if (bytes > 0) {
        self.textView.text = [NSString stringWithCString: buffer encoding: NSASCIIStringEncoding];
    }
    

    Now that you have the apps' install locations, open up the Info.plists under those directories

    NSString* filename = @"/var/mobile/Applications/8AA99EA8-9CFC-4237-9BD1-7C2812EDAAD4/Starbucks.app/Info.plist";
    NSDictionary* dict = 
        [[NSDictionary alloc] initWithContentsOfFile: filename];
    NSString* bundleID = [dict valueForKey: @"CFBundleIdentifier"];
    

    and read their bundle IDs.

    In order to make this work, you may need to gain root privileges for your app.

    See here on how to do that.