【问题标题】:Setting default application for given file extension on Mac OS X from code从代码为 Mac OS X 上的给定文件扩展名设置默认应用程序
【发布时间】:2011-03-21 15:00:09
【问题描述】:

我有给定文件扩展名的应用程序列表(使用 LSCopyApplicationURLsForURL)。从上述调用中选择一个应用程序后,我想从代码中更改默认文件关联。 有没有办法做到这一点?

【问题讨论】:

    标签: objective-c macos cocoa launch-services


    【解决方案1】:

    这是一个非常相关的任务的代码:将自己设置为给定文件扩展名的默认应用程序:

    #import <ApplicationServices/ApplicationServices.h>
    #import "LaunchServicesWrapper.h"
    
    @implementation LaunchServicesWrapper
    
    
    + (NSString *) UTIforFileExtension:(NSString *) extension {
        NSString * UTIString = (NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, 
                                                                           (CFStringRef)extension, 
                                                                           NULL);
    
        return [UTIString autorelease];
    }
    
    + (BOOL) setMyselfAsDefaultApplicationForFileExtension:(NSString *) fileExtension {
        OSStatus returnStatus = LSSetDefaultRoleHandlerForContentType (
                                                                       (CFStringRef) [LaunchServicesWrapper UTIforFileExtension:fileExtension],
                                                                       kLSRolesAll,
                                                                       (CFStringRef) [[NSBundle mainBundle] bundleIdentifier]
                                                                       );
    
        if (returnStatus != 0) {
            NSLog(@"Got an error when setting default application - %d", returnStatus);
            // Please see the documentation or LSInfo.h
    
            return NO;
        }
    
        return YES;
    }
    
    
    @end
    

    【讨论】:

    • 谢谢,但已经找到了答案(见我的答案)——你的和我的有点不同,因为它只为扩展找到了 UTI。如果还有更多呢?
    • 遗憾的是,这不再适用于沙盒应用程序。
    【解决方案2】:

    这是 Guillaume 解决方案的略微修改且符合 ARC 的版本:

    #import <Foundation/Foundation.h>
    
    @interface LaunchServicesWrapper : NSObject
    
    + (BOOL)setMyselfAsDefaultApplicationForFileExtension:
      (NSString *)fileExtension;
    
    @end
    
    
    #import <ApplicationServices/ApplicationServices.h>
    #import "LaunchServicesWrapper.h"
    
    @implementation LaunchServicesWrapper
    
    + (NSString *)UTIforFileExtension:(NSString *)extension
    {
      return (NSString *)CFBridgingRelease(
        UTTypeCreatePreferredIdentifierForTag(
          kUTTagClassFilenameExtension, (__bridge CFStringRef)extension,
          NULL
        )
      );
    }
    
    + (BOOL)setMyselfAsDefaultApplicationForFileExtension:
      (NSString *)fileExtension
    {
      return LSSetDefaultRoleHandlerForContentType(
        (__bridge CFStringRef) [LaunchServicesWrapper
        UTIforFileExtension:fileExtension], kLSRolesAll,
        (__bridge CFStringRef) [[NSBundle mainBundle]
        bundleIdentifier]
      );
    }
    
    @end
    

    【讨论】:

    • 这仍然是解决此问题的最佳方法吗?我正在使用 Swift 开发一个 mac 应用程序,如果是这样,我会将其翻译成 Swift。
    【解决方案3】:
    - (void) setApplication:(NSString *)applicationName forExtension:(NSString *)extension {
    
        NSArray *appPaths = [self getApplicationListForExtension:extension];
    
        for (NSString *appPath in appPaths) {
            if ([appPath rangeOfString:applicationName].location != NSNotFound) {
                NSArray *UTIs = (NSArray *)UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension,
                                                                            (CFStringRef)extension,
                                                                            nil);
                for (NSString *UTI in UTIs) {
                    LSSetDefaultRoleHandlerForContentType((CFStringRef)UTI,
                                                          kLSRolesEditor,
                                                          (CFStringRef)[[NSBundle bundleWithPath:appPath] bundleIdentifier]);
                }
    
                [UTIs release];
    
                break;
            }
        }
    }
    

    【讨论】:

    • 这段代码得到thisAppName,但没有做任何事情。
    • getApplicationListForExtension: 未定义。
    • 未定义,但它只返回一个 NSArray 字符串。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 2015-05-27
    • 2013-11-20
    • 2010-10-20
    • 2012-03-11
    • 1970-01-01
    • 2021-12-30
    相关资源
    最近更新 更多