Shell脚本作为默认浏览器

时间:2014-05-23 10:08:47

标签: macos

假设我有一个名为my_link_opener的可执行文件,如何将其设置为默认浏览器?

我已经尝试了以下内容,但没有成功:

将其包装为.app
我尝试使用Appify,然后将生成的.app设置为Safari中的默认浏览器 但是,因为OS X期望程序只有一个“实例”在其生命周期中打开许多链接,所以这不会有效 它不是在命令行上传递URL,而是发送-psn_xxxxx参数。

使用Automator包装
事实证明,if you add it as a workflow in Automator你可以将打开的文件作为参数 但是,这仅适用于文件和文件夹 据我所知,无法为Automator工作流程设置URL有效输入。

所以,我运气不好。我还能做其他任何包装魔法吗?

1 个答案:

答案 0 :(得分:1)

我无法找到任何已经存在的选项(但仍有一些可能存在)所以我最终写了一个。 基本上它的作用是告诉系统应用程序 IS 是一个浏览器,最终将自己设置为默认浏览器(请参阅#define SET_AS_DEFAULT_BROWSER),最后通过发送时收到正确的事件来管理网址url到位于应用程序包中的名为my_link_opener的脚本(即在.app目录中)。调用的bash命令是:

nohup /path/to/my_link_opener "_an_url_" >& /dev/null &

#import "ZFTAppDelegate.h"

NSString *runCommand(NSString *commandToRun)
{
    NSTask *task;
    task = [[NSTask alloc] init];
    [task setLaunchPath: @"/bin/sh"];

    NSArray *arguments = @[@"-c" ,[NSString stringWithFormat:@"%@", commandToRun]];
    [task setArguments: arguments];

    NSPipe *pipe;
    pipe = [NSPipe pipe];
    [task setStandardOutput: pipe];

    NSFileHandle *file;
    file = [pipe fileHandleForReading];

    [task launch];

    NSData *data;
    data = [file readDataToEndOfFile];

    NSString *output;
    output = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
    return output;
}

#define SET_AS_DEFAULT_BROWSER

@implementation ZFTAppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSAppleEventManager *em = [NSAppleEventManager sharedAppleEventManager];
    [em setEventHandler:self
            andSelector:@selector(getUrl:withReplyEvent:)
          forEventClass:kInternetEventClass
             andEventID:kAEGetURL];
    [em setEventHandler:self
            andSelector:@selector(getUrl:withReplyEvent:)
          forEventClass:'WWW!'
             andEventID:'OURL'];


#ifdef SET_AS_DEFAULT_BROWSER
    CFStringRef bundleID = (__bridge CFStringRef)[[NSBundle mainBundle] bundleIdentifier];
    LSSetDefaultHandlerForURLScheme(CFSTR("http"), bundleID);
    LSSetDefaultHandlerForURLScheme(CFSTR("https"), bundleID);
#endif


}

- (void)getUrl:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
    NSString *url = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
    NSString* scriptPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"my_link_opener"];
    runCommand([NSString stringWithFormat:@"nohup %@ \"%@\" >& /dev/null &", scriptPath, url]);
}

@end

请记住,在应用的info.plist中,您应该拥有此功能(需要通知操作系统您的应用处理http / s网址的功能):

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>https</string>
        </array>
        <key>CFBundleURLName</key>
        <string>Secure http URL</string>
    </dict>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>http</string>
        </array>
        <key>CFBundleURLName</key>
        <string>http URL</string>
    </dict>
</array>