4

如果你去/usr/bin你会看到数百个可执行文件或可执行文件的链接。

我的应用程序(在 Xcode 中用 Obj-C 编写的 Mac 应用程序)依赖于其中一些可执行文件。不幸的是,必须手动安装可执行文件——我必须检查它们,然后提示用户安装它们。

我的代码是:

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/executable"];

NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
NSFileHandle *file = [pipe fileHandleForReading];

[task setArguments:[NSArray arrayWithObjects:sender, target, nil]];
[task launch];

我想知道是否可以将可执行文件复制到我的应用程序中的某个地方,然后从那里调用它。这样,用户就不必自己去获取它。

Mac App Store 会允许吗?

4

5 回答 5

1

如果你想知道,在 Swift 3 中你可以这样做:

let bundle = Bundle.main
let task = Process()
let path = bundle.path(forResource: "executableName", ofType: "")
task.launchPath = path
于 2016-11-02T12:51:26.970 回答
1

只是为了更新和澄清,我发现以下内容适用于 Xcode 11 和 Swift 5。

首先,将所需的可执行文件(在我的例子中是 pandoc)拖放到我的 Xcode 项目中。我把它放在一个名为“bin”的组/文件夹中。

确保选择我希望包含可执行文件的所需目标!

然后使用以下代码:

let task = Process()
let bundle = Bundle.main
let execURL = bundle.url(forResource: "pandoc", withExtension: nil)
guard execURL != nil else {
    print("Pandoc executable could not be found!")
    return 
}
task.executableURL = execURL!
task.arguments = ["--version"]
do {
    try task.run()
    print("Pandoc executed successfully!")
} catch {
    print("Error running Pandoc: \(error)")
}
于 2020-01-25T22:30:45.563 回答
0

好的,所以我开始尝试自己寻找答案。而且,我很高兴地说我想通了!

因此,只需将其复制executable到 Xcode 项目中您想要的任何位置。然后,改变

[task setLaunchPath:@"/usr/bin/executable"];

[task setLaunchPath:[[NSBundle mainBundle] pathForResource:@"executable" ofType:@""]];

和达!

于 2012-08-18T05:08:36.680 回答
0

在 Swift 中,你可以这样做:

let bundle = NSbundle.mainBundle()
let task = NSTask()

task.launchPath = bundle.pathForResource("executableName", ofType: "")

确保捆绑的可执行文件位于目录树的顶层,而不是像 /lib 这样的子目录,否则它可能不起作用。

于 2016-06-05T12:37:07.250 回答
0

我更新了 hbowie 的答案,将从 shell 接收到的值作为字符串返回:

func safeShell(_ strExecutable:String, _ arrArguments:Array<String>) throws -> String {
        
        let task = Process()
        let pipe = Pipe()
        let bundle = Bundle.main
        let execURL = bundle.url(forResource: strExecutable, withExtension: nil)
        
        //no point in going on if we can't find the program
        guard execURL != nil else {
            print("\(strExecutable) executable could not be found!")
            return ""
        }
        
        task.executableURL = execURL!
        task.arguments = arrArguments
        task.standardOutput = pipe
        task.standardError = pipe
        //task.arguments = ["-c", command]
        //task.executableURL = URL(fileURLWithPath: "/bin/zsh") //<--updated

        do {
            try task.run() //<--updated
        }
        catch{ throw error }
        
        let data = pipe.fileHandleForReading.readDataToEndOfFile()
        let output = String(data: data, encoding: .utf8)!
        
        return output
    }
    
}

使用示例:

let strOutput = try myAppManager.safeShell("pandoc", ["--version"])
print(strOutput)

回报:

pandoc 2.16.2
Compiled with pandoc-types 1.22.1, texmath 0.12.3.2, skylighting 0.12.1,
citeproc 0.6, ipynb 0.1.0.2
User data directory: /Users/stevesuranie/Library/Containers/MartianTribe.MD2HTML/Data/.local/share/pandoc
Copyright (C) 2006-2021 John MacFarlane. Web:  https://pandoc.org
This is free software; see the source for copying conditions. There is no
warranty, not even for merchantability or fitness for a particular purpose.
于 2021-12-30T16:09:04.253 回答