如何检索应用程序的版本字符串?

Posted

技术标签:

【中文标题】如何检索应用程序的版本字符串?【英文标题】:How to retrieve an application's version string? 【发布时间】:2014-11-09 14:13:23 【问题描述】:

使用 Mac OSX SDK,我编写了这个简单的测试应用程序来从正在运行的应用程序中提取版本字符串。

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 ] );
    

但这不起作用,它会打印如下行:

pid 34 的版本:“(null)”

第二次尝试 如果我尝试通过将最后两行更改为来检索CFBundleVersion,我会更接近:

 const NSNumber * version
     = reinterpret_cast<const NSNumber *>(CFDictionaryGetValue( dictionary, CFSTR("CFBundleVersion") ));
 printf( "version for pid %d: \"%s\"\n", pid, [ [ version stringValue ] UTF8String ] );

但现在版本是一个整数,比如 257633863,我想要像 1.23.0 这样的数字

【问题讨论】:

从阅读您的最后一行开始,版本不应该保存为字符串吗?另外,你不能在常量头文件中定义一个版本字符串吗?并在每次更新时手动更改。 #define kVersion @"1.23.0" 并在您想要的任何地方调用“kversion”,只要您导入了文件。 你检查过这篇文章吗?它适用于 ios,但可能会提示您在 OS X 上做同样的事情。***.com/questions/7608632/… 关于您的代码的几点说明:您忘记了CFRelease(dictionary);(CoreFoundation 函数ProcessInformationCopyDictionary 的名称中有Copy,因此您拥有返回的引用)。你为什么要做那些const XY * 演员?我以前从未见过这个,所以我只是好奇原因。 @DarkDust 感谢您的评论!我来自 C/C++,所以const-ness 只是一种反射。 @Zil:我首先开始将它作为字符串检索,但我有一个运行时警告说“找不到 NSNumber 的选择器 UTF8String”(或类似的东西),所以我认为 CFDictionaryGetValue 正在返回一个 NSNumber 【参考方案1】:

阅读捆绑包的Info.plist 字典可能更容易:

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);

【讨论】:

【参考方案2】:

您可以使用这样的方法来检查特定的应用版本。

+(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;

请务必在用于商业软件之前对此进行测试。

【讨论】:

以上是关于如何检索应用程序的版本字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 JSON 数组中检索字符串数组?

如何检索用于编译给定 ELF 可执行文件的 GCC 版本?

如何检索 MySQL 数据库管理系统 (DBMS) 的当前版本?

如何在颤动中检索android安装的包图标?

如何将命名空间检索到字符串 C#

如何从 App.config 中检索连接字符串 [重复]