以编程方式强制Cocoa应用程序以32位模式启动

以编程方式强制Cocoa应用程序以32位模式启动,cocoa,macos,32bit-64bit,launch,Cocoa,Macos,32bit 64bit,Launch,我有一个Cocoa应用程序,它通常在任何支持这种体系结构的Mac上以全64位模式运行 现在我有了一个外部API,它只能作为32位插件加载到主程序中。此API用于第三方输入设备,只有一小部分我的用户会购买,但这对这一小部分人来说很重要 我的问题是,只有在32位模式下执行时,程序才能使用此API。当然,最简单的方法是: 场景1:通过Finder的“获取信息”对话框更改程序信息,要求用户以32位模式启动程序。 这很容易做到,但很难做到优雅 场景2:始终以32位模式运行,从而避免出现问题 也不是我想做的

我有一个Cocoa应用程序,它通常在任何支持这种体系结构的Mac上以全64位模式运行

现在我有了一个外部API,它只能作为32位插件加载到主程序中。此API用于第三方输入设备,只有一小部分我的用户会购买,但这对这一小部分人来说很重要

我的问题是,只有在32位模式下执行时,程序才能使用此API。当然,最简单的方法是:

场景1:通过Finder的“获取信息”对话框更改程序信息,要求用户以32位模式启动程序。

这很容易做到,但很难做到优雅

场景2:始终以32位模式运行,从而避免出现问题

也不是我想做的。。为了一个奇特的功能惩罚98%的用户

场景3:自动更改应用程序的启动属性,以便下次启动时以及以后每次启动时都以32位模式启动

场景4:在启动时,确定正在使用的架构,然后在必要时以32位模式重新启动

场景3和场景4的问题是,关于如何做到这一点的文档很少,这可能会让我在Mac App Store指南中遇到麻烦

到目前为止,我已经确定:

  • 使用“arch”命令行工具将允许我以32位模式重新启动可执行文件
  • Finder脚本不允许我更改“以32位模式启动”标志
  • 该标志由Launch Services API()管理
  • 但是我还没有找到任何接口可以通过编程更改LaunchServices API中的标志
到目前为止,我只能看到这些选项,其中没有一个看起来特别好:

  • 使用NSTask和“arch”命令行工具重新启动应用程序
  • 直接写入com.apple.LaunchServices.plist
  • 将32位插件隔离到其自己的仅32位进程中,并使用IPC
  • 解决方案1可能会让我在提交MAS时遇到麻烦。解决方案2几乎肯定会在某个阶段这样做。。从用户的角度来看,只有解决方案3才是完美的,但却增加了巨大的复杂性以获得最低的回报

    任何关于如何“干净”和合理努力完成这项工作的建议都将不胜感激

    选项5:
    创建另一个始终以32位运行的可执行文件,其唯一目的是驱动相关的32位组件。从主应用程序启动该可执行文件,并使用某种类型的处理器独立io相互通信,可能是套接字。

    您可以通过更改此处的plist文件,以编程方式更改应用程序将以何种模式启动:

    ~/Library/Preferences/com.apple.LaunchServices.plist

    您需要更改位于的钥匙
    /LSArchitecturesForX86\u 64/[your.app.idenitifier]/Item 1/

    • 将其设置为x86_64将以64位运行
    • 将其设置为i386将以32位运行
    您可以使用内置的
    defaults
    命令或内置的
    plistbuddy
    命令来编辑此项。我从来没有幸运地得到过一个可以使用
    默认值更改的键,如果我弄清楚
    plistbuddy
    语法,我会发布它


    完成所有这些后,您可以创建一个简单的脚本,在登录时运行,测试输入设备(或其他属性、部门等)是否存在,并相应地设置启动模式。

    我找到了使用默认值设置密钥的方法

    给定一个bash shell变量:

    alias="<0000 .... 1234>"  #(there is a lot more hex data than that...)
    
    您可以这样设置键:

    defaults write com.apple.LaunchServices LSArchitecturesForX86_64 -dict-add $bundle "($alias, i386)"
    

    祝您生成二进制别名好运。我只是从com.plist.dock中窃取了cfurlaisdata,因为我试图设置为启动32位的程序在dock中安装了一个图标。另一种生成别名的方法是使用程序dockit.c,如果您可以使用它的话。我还没有找到那个程序。

    我的情况非常相似。我使用Ableton Live和Reason作为重新布线的奴隶。如果我在32位启动Ableton,我需要的理由是在32位模式。这就是我所做的

  • 制作一份你希望能够快速改变模式的应用程序副本
  • 调用copy 32.app(在我的例子中是Reason32.app)
  • 显示此新应用程序的软件包内容并删除内容文件夹(是包含所有内容的文件夹)
  • 现在进入原文,制作内容的符号链接
  • 将符号链接复制到appname32.app包中(旧的已删除的一个用于驻留)
  • 使用finder属性并为新副本勾选32位模式

  • 您现在有2个应用程序可以轻松启动/script。

    如果您的应用程序仅为32位,那又有什么关系呢?它是否需要大量内存(>2 GB)?是否总是在32位模式下运行?这是一个很大的惩罚?应用程序的可能副本使用垃圾收集,在64位模式下效果更好,所以,是的,这是一个由所有用户支付的巨大惩罚。这与另一个链接问题类似,但也没有令人满意的答案。如果我在plisteditor pro中查找,alias变量是否为捆绑包标识符下的0键?我想可能是的。不管怎么说,我认为这里有某种缓存。如果我使用上述Bash方法,除非我强制退出Finder,否则信息对话框的勾选框状态不会显示它已更改。它必须触发重建其内部缓存的内容。看这里,它似乎表明,即使强制退出,我发现该应用程序尤其只响应手动信息对话框滴答声。换句话说,即使我运行bash脚本,将其设置为32位,并在UI勾选框中看到它发生了更改,我的应用程序仍然以64位启动。我现在将尝试创建.app包的两个副本。
    defaults write com.apple.LaunchServices LSArchitecturesForX86_64 -dict-add $bundle "($alias, i386)"