OSX – 打包一个基于shell的交互式二进制文件
我已经创build了一个小的NodeJS脚本,使用EncloseJS编译,以便应用程序变成它自己的二进制文件。 该应用程序的目的是在terminal运行,并与用户交互。 我想把它打包在一个.app中,所以感觉像一个普通用户可以运行的完整应用程序。
我怎样才能解决这个问题? 到目前为止,我已经尝试了鸭嘴兽的结果混杂,因为它似乎不正确退出。
尝试以下操作:
- 使用
[Apple]Script Editor
创build一个新脚本并将其保存为应用程序 。 - 将你的二进制文件 – 我们称之为
foo
– 放在新的.app
软件包的Contents/MacOS
子文件夹中。 - 将下面的代码放在应用程序的AppleScript中:
set embeddedBinary to POSIX path of (path to me) & "Contents/MacOS/foo" tell application "Terminal" do script quoted form of embeddedBinary activate end tell
当您运行应用程序时,embedded式二进制文件将在您可以与之交互的新的“terminal”窗口中打开。
追加& "; exit"
do script
命令以自动closuresterminal窗口时,二进制终止。
但是,请注意,您的应用程序仅作为embedded式二进制文件的启动器 :
- terminal窗口创build完成后终止
- 所以它的Dock图标只显示一下,然后再次消失
- 并且你将不会得到应用程序菜单(无论如何,鉴于你的二进制文件在terminal中运行,这将不是一个选项)。
- 每次启动应用程序时,即使您的二进制文件已经在运行,也会打开一个新的terminal窗口。
有办法解决这些问题(菜单除外),但他们需要额外的工作 – 见下文。
解决上述问题的解决scheme,以获得更加完整的体验 :
- 它保持包装应用程序打开(显示自己的Dock图标)。
- 它将激活转发到运行embedded式二进制文件的启动terminal窗口,当应用程序被激活时(例如,通过点击Dock图标)
- 当启动的terminal窗口closures时,包装应用程序自动终止。
但是它有局限性 :
- 可悲的是,为了中继激活, 需要GUI脚本 ,这需要在任何给定机器上具有pipe理权限的一次性授权 ; 首次启动时提示用户,但需要几个步骤。
- 为了使应用程序能够在点击时快速中继激活,并在terminal窗口closures时快速退出,必须频繁地调用它
on idle
事件处理程序,这会占用CPU资源,尽pipeCPU的额外负载非常小 – 请参阅注释在源代码下面。
说明:
- 使用
[Apple]Script Editor
创build一个新脚本并将其保存为保持打开的 应用程序 :- 在
Save
为对话框中,select格式Application
然后选中Stay open after run handler
checkbox。
- 在
- 将你的二进制文件 – 我们称之为
foo
– 放在新的.app
软件包的Contents/MacOS
子文件夹中。 - 将下面的代码放在应用程序的AppleScript中:
# Global variable to track the launched Terminal window (tab). global g_winLaunched on run # Get full path of embedded binary. set embeddedBinary to POSIX path of (path to me) & "Contents/MacOS/foo" tell application "Terminal" # Launch embedded binary in new Terminal window, and # have the window closed when the binary terminates *successfully*. # This leaves the window open in case of error - whether on # initial launch or on existing - giving the user a chance to investigate. do script quoted form of embeddedBinary & " && exit" set g_winLaunched to front window end tell end run on idle if frontmost of me then # If this app is activated, relay activation to the launched Terminal window. try # Activate the running window using GUI scripting. # Sadly, `set index of g_winLaunched to 1` is NOT enough to activate the window. # NOTE: This requires that this app be authorized for assistive access via # System Preferences > Security & Privacy > Accessibility. tell application "System Events" perform action "AXRaise" of window (name of g_winLaunched) of process "Terminal" end tell activate application "Terminal" on error tell me to quit # Window is no longer alive, quit this app. end try else # See if tab is still alive, and, if not, quit this app. try id of g_winLaunched on error tell me to quit end try end if # Call this handler every N seconds. # This is a trade-off between responsiveness and CPU usage. # With 0.3 secs., CPU usage of this app is around 0.8% # on my 3.2 Ghz quad-core Intel Core i5 iMac. return 0.3 end idle
您可以尝试使用一个命令提供Node.JS应用程序的本机打包(自我执行)的JXcore,如:
$ jx package myapp.js MyApp -native
然后你可以在OSX(或其他Unix系统)上运行它:
$./MyApp
对于Windows(如果您需要它),文件名将是MyApp.exe
。
更多关于这里: 包装和代码保护 。