【问题标题】:Embed Executable inside Mac Application在 Mac 应用程序中嵌入可执行文件
【发布时间】:2012-08-17 20:31:13
【问题描述】:

如果您访问/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 会允许吗?

【问题讨论】:

  • 一般来说,只需在构建时将它们作为应用程序包的一部分就可以了。不幸的是,我对问题的应用商店部分一无所知。
  • @Lvsti 你到底是什么意思?如,我应该在哪里添加可执行文件?我将如何“在构建时使它们成为应用程序包的一部分”?我该怎么称呼它 - setPathLaunch 是什么?
  • 我怀疑应用商店不允许允许此类恶作剧,因为沙盒可能不允许启动外部任务。 Other people have been thinking about this question as well.

标签: objective-c macos embed executable mac-app-store


【解决方案1】:

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

let bundle = Bundle.main
let task = Process()
let path = bundle.path(forResource: "executableName", ofType: "")
task.launchPath = path

【讨论】:

    【解决方案2】:

    只是为了更新和澄清,我发现以下内容适用于 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)")
    }
    

    【讨论】:

      【解决方案3】:

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

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

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

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

      还有哒哒!

      【讨论】:

      • 感谢您的回答。请问您可以使用这种方法通过 App Store 分发吗?
      【解决方案4】:

      在 Swift 中,您可以这样做:

      let bundle = NSbundle.mainBundle()
      let task = NSTask()
      
      task.launchPath = bundle.pathForResource("executableName", ofType: "")
      

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

      【讨论】:

        【解决方案5】:

        我更新了 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.
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-06
          • 2011-10-22
          • 2022-01-19
          • 2013-08-27
          • 2011-08-30
          相关资源
          最近更新 更多