如何从Cocoa应用程序运行二进制文件?

时间:2015-02-11 13:12:19

标签: objective-c cocoa

我正在为二进制文件制作一个简单的启动器,所以我可以让它出现在我的启动板中。

我最初的想法是运行system("./myProgram");就足够了,但它实际上并没有做任何事情,因为它运行的终端实例在运行命令后没有保持打开状态,立即关闭其他任务该计划确实如此。

所以我的问题是,有没有办法让我这样做,让它无限期地开放?

编辑:我希望我的发射器在启动程序后立即关闭,因此依靠需要它保持打开的东西并不理想

编辑:以下所有工作,但只有从xcode运行时,独立运行时才会启动该程序

system("open /Applications/Utilities/Terminal.app myProgram");
system("open myProgram");
system("/bin/sh -c ./myProgram&");
system("./myProgram&");

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/bash"];
[task setArguments: @[@"-c", @"./myProgram"]];
[task launch];

NSTask不会出现任何错误,也不会在应用运行时抛出任何异常

从程序的每个其他方面都可以工作,它不会启动,也不会说明为什么

基于所有“反馈”,这是我到目前为止所得到的。除非我提供绝对路径(如果我想稍后移动它并不好),它仍然无法工作。

//
//  AppDelegate.m
//  DFLauncher
//
//  Created by Electric Coffee on 11/02/15.
//  Copyright (c) 2015 Electric Coffee. All rights reserved.
//

#import "AppDelegate.h"

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@end

NSString *CURRENT_DIR;
NSString *FILE_PATH;
NSString *INIT_PATH  = @"/data/init/init.txt";
NSString *VOLUME_ON  = @"[SOUND:YES]";
NSString *VOLUME_OFF = @"[SOUND:NO]";

BOOL contains(NSString *a, NSString *b) {
    return [a rangeOfString: b].location != NSNotFound;
}

NSData *replaceString(NSString *fileContents, NSString *from, NSString *to) {
    return [[fileContents stringByReplacingOccurrencesOfString: from withString: to]
            dataUsingEncoding: NSUTF8StringEncoding];
}

@implementation AppDelegate

- (void)applicationDidFinishLaunching: (NSNotification *)aNotification {
    CURRENT_DIR = [[NSFileManager new] currentDirectoryPath]; //[[NSBundle mainBundle] bundlePath];
    //NSLog(@"%@", CURRENT_DIR);

    FILE_PATH = [CURRENT_DIR stringByAppendingString: INIT_PATH];
    _fileContents = [NSString stringWithContentsOfFile: FILE_PATH
                                              encoding: NSUTF8StringEncoding
                                                 error: NULL];
    if (contains(_fileContents, VOLUME_OFF))
        [_toggleMute setState: YES];
    if (contains(_fileContents, VOLUME_ON))
        [_toggleMute setState: NO];
}

- (void)applicationWillTerminate:(NSNotification *)aNotification {

 }

- (IBAction)playButtonClick: (id)sender {
    //system("open /Applications/Utilities/Terminal.app df"); // doesn't quite work
    //system("open /Applications/df_osx/df");
    //system("/bin/sh -c /Applications/df_osx/df&");
    //system("/Applications/df_osx/df&");

    NSString *gamePath = [CURRENT_DIR stringByAppendingString: @"/df&"];

    NSTask *task = [NSTask new];
    [task setLaunchPath: @"/bin/bash"];
    [task setArguments: @[@"-c", gamePath]];
    NSError *error = task.standardError;
    [task launch];

    [NSAlert alertWithError: error];

    //[NSApp terminate: self];
}

- (IBAction)folderButtonClick: (id)sender {
    system("open .");
}

- (IBAction)quitButtonClick: (id)sender {
    [NSApp terminate: self];
}

- (IBAction)mute: (id)sender {
    NSData *result;
    NSFileManager *fm = [NSFileManager defaultManager];
    if ([sender state] == NSOffState)
        result = replaceString(_fileContents, VOLUME_OFF, VOLUME_ON);
    else
        result = replaceString(_fileContents, VOLUME_ON, VOLUME_OFF);

    [fm createFileAtPath: FILE_PATH contents: result attributes: nil];
}
@end

1 个答案:

答案 0 :(得分:0)

Hacky解决方案有效(但根本不优雅)

我不得不替换

FILE_PATH = [CURRENT_DIR stringByAppendingString: INIT_PATH];

CURRENT_DIR = [[[[NSBundle mainBundle] bundlePath] stringByDeletingPathExtension] stringByDeletingLastPathComponent];

要获取文件的正确路径,但现在可以正常工作。