Mac App的可执行路径

6 投票
3 回答
2641 浏览
提问于 2025-04-16 07:41

在一个py2app/Mac应用程序包中,有没有办法从应用内部启动同一个应用的另一个实例,并传递不同的命令行参数?

或者,给定一个Mac应用程序包,我该如何从命令行运行它并传递一些参数呢?

编辑1:分叉(forking)是一个有限的选项,可能不适用于与应用程序一起打包的第三方可执行文件+我需要在Mac和Windows上运行这个。
编辑2:问题是如何使用subprocess模块运行一个打包的Python脚本

详细信息:

我正在使用py2app为我的应用程序生成一个应用程序包。我的应用程序有两个部分:

  1. 主应用(MainApp):这是用户界面
  2. 后台应用(BackgroundApp):这是一个后台进程,负责实际的工作

主应用和后台应用都是用Python脚本实现的,实际上它们是同一个Python脚本,只是命令行参数不同,例如:

python myapp.py
python myapp.py --backgroundprocess

所以当我运行python myapp.py时,它会自动根据程序路径启动后台进程,但由于我现在已经将我的应用打包为py2app,我不确定应该调用哪个可执行文件并传递--backgroundprocess选项?

我尝试过的

  1. $ open MyApp.app/ 这个命令可以打开应用,但我无法传递参数,因为这些参数会被当作open命令的参数,而不会传递给我的应用

  2. $ MyApp.app/Contents/MacOS/MyApp --backgroundprocess 这个命令可以打开应用,但并没有启动后台进程,因为参数似乎没有传递给应用

而且它还会抛出错误

  Traceback (most recent call last):
  File "/Users/agyey/projects/myapp/release4.26/py2exe/dist/MyApp.app/Contents/Resources/run.py", line 4, in <module>
    from renderprocess import RenderEngineApp
  File "renderprocess/RenderEngineApp.pyc", line 6, in <module>
  File "wx/__init__.pyc", line 45, in <module>
  File "wx/_core.pyc", line 4, in <module>
  File "wx/_core_.pyc", line 18, in <module>
  File "wx/_core_.pyc", line 11, in __load
ImportError: dlopen(/Users/agyey/projects/myapp/release4.26/py2exe/dist/MyApp.app/Contents/Resources/lib/python2.5/lib-dynload/wx/_core_.so, 2): Library not loaded: @executable_path/../Frameworks/libwx_macud-2.8.0.dylib
  Referenced from: /Users/agyey/projects/myapp/release4.26/py2exe/dist/MyApp.app/Contents/Resources/lib/python2.5/lib-dynload/wx/_core_.so
  Reason: Incompatible library version: _core_.so requires version 7.0.0 or later, but libwx_macud-2.8.0.dylib provides version 2.6.0

结论:看起来这可能是不可能的。在OS X上用命令行启动应用

open不接受参数。

3 个回答

0

我没能让py2app正常工作,不过应用程序的可执行文件在 AppName.app/Contents/MacOS/AppName 这个路径下。你可以在 AppName.app/Contents/Info.plist 文件里找到一个叫 <key>CFBundleExecutable</key> 的键,它指向了在 AppName.app/Contents/MacOS 文件夹里的可执行文件。

所以你可以这样调用它: AppName.app/Contents/MacOS/AppName --backgroundprocess

如果你想让 BackgroundApp 在后台运行而不需要任何参数,有两个选择:a) 从Python脚本制作一个包,这个脚本可以在没有参数的情况下运行后台进程;b) 在 Info.plist 文件中把 <key>CFBundleExecutable</key> 改成 BackGroundApp_shell,然后制作一个名为 Contents/MacOS/BackgroundApp_shell 的shell脚本,内容如下:

#!/bin/sh

`dirname "$0"`/BackgroundApp --backgroundprocess

假设可执行文件是 BackgroundApp

0

先创建一个应用程序,然后只需为这个应用程序调用 --bakgroundproccess 这个选项。接着,为这个后台进程创建一个快捷方式。或者你也可以创建两个不同的应用文件。无论哪种方式都可以。

1

如何找到当前工作目录并执行任意提供的二进制文件

首先,把二进制文件放在 AppName.app/Contents/Resources 这个文件夹里,然后在 Python 脚本中运行以下代码:

import subprocess
process=subprocess.Popen((os.getcwd() + "/3rd_party_binary","--subprocess")) 
process.poll() # is running?

如何正确地启动你 Python 应用的两个版本

在 MacOSX(类 Unix 系统)上,使用 Fork 是一种老办法。

#!/usr/bin/env python
import os, sys

pid = os.fork()
if pid:
    # we are the parent
    background_process.start()
    os.waitpid(pid, 0) # make sure the child process gets cleaned up
else:
    # we are the child
    gui_app.start()
    sys.exit(0)

print "parent: got it; text =", txt

Python 中的多进程 显然在 Windows 上也能用,我想这对你来说可能会很有趣(?)。

撰写回答