Reputation: 12963
Using the Mac OSX SDK, I wrote this simple test application to extract the version string from running applications.
int main()
{
NSWorkspace * ws = [NSWorkspace sharedWorkspace];
NSArray * apps = [ws runningApplications];
NSUInteger max= [apps count];
for (NSUInteger i = 0; i < max; i++)
{
NSRunningApplication *app = [apps objectAtIndex: i];
pid_t pid = [ app processIdentifier ];
ProcessSerialNumber psn = { kNoProcess, kNoProcess };
if ( GetProcessForPID(pid, &psn) != noErr )
continue;
CFDictionaryRef dictionary
= ProcessInformationCopyDictionary(&psn, kProcessDictionaryIncludeAllInformationMask);
const NSString * version
= reinterpret_cast<const NSString*>(CFDictionaryGetValue( dictionary, CFSTR("CFBundleShortVersionString") ));
printf( "version for pid %d: \"%s\"\n", pid, [ version UTF8String ] );
}
}
but this does not work, it prints lines like:
version for pid 34: "(null)"
SECOND TRY
I get a bit closer if I try retrieving CFBundleVersion
by changing the two last lines to:
const NSNumber * version
= reinterpret_cast<const NSNumber *>(CFDictionaryGetValue( dictionary, CFSTR("CFBundleVersion") ));
printf( "version for pid %d: \"%s\"\n", pid, [ [ version stringValue ] UTF8String ] );
but now the version is an integer, like 257633863, and I would like something like 1.23.0
Upvotes: 1
Views: 1572
Reputation: 221
You can use a method like this to check for a specific app version.
+(BOOL) isCorrectApp:(NSString*) appIdentifier forVersion: (NSString*) appVersion {
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSArray *apps = [ws runningApplications];
for (NSRunningApplication *app in apps)
{
NSBundle *bundle = [NSBundle bundleWithURL:[app bundleURL]];
NSDictionary *info = [bundle infoDictionary];
NSString *identifier = info[@"CFBundleIdentifier"];
if ([identifier containsString:appIdentifier]) { // appIdentifier is com.apple.iTunesHelper or such
NSString *name = info[@"CFBundleName"];
NSString *version = info[@"CFBundleVersion"];
NSString *shortVersion = info[@"CFBundleShortVersionString"];
if ([version hasPrefix:appVersion]) {
NSLog(@"Name: %@, Identifier: %@, Version: %@ (%@)", name, identifier, version, shortVersion);
} else {
// NSLog(@"Waiting for the right version.");
return false;
}
}
}
return true;
}
Please be sure to test this before using in commercial software.
Upvotes: 1
Reputation: 92345
It's probably easier to just read the bundle's Info.plist
dictionary:
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSArray *apps = [ws runningApplications];
for (NSRunningApplication *app in apps)
{
pid_t pid = [app processIdentifier ];
NSBundle *bundle = [NSBundle bundleWithURL:[app bundleURL]];
NSDictionary *info = [bundle infoDictionary];
NSString *name = info[@"CFBundleName"];
NSString *identifier = info[@"CFBundleIdentifier"];
NSString *version = info[@"CFBundleVersion"];
NSString *shortVersion = info[@"CFBundleShortVersionString"];
NSLog(@"PID: %ld, Name: %@, Identifier: %@, Version: %@ (%@)", (long)pid, name, identifier, version, shortVersion);
}
Upvotes: 1