检测是否特定Python.app版实例已在运行

2024-06-17 13:13:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在试验用Python编写的osx应用程序,需要检测是否已经存在Python.app版用特定的脚本运行。该脚本将CFBundleNamePython动态修改为MyApp,以更改菜单栏中的应用程序标题。在

bundle = NSBundle.mainBundle()
info = bundle.localizedInfoDictionary() or bundle.infoDictionary()
info['CFBundleName'] = 'MyApp'

如果我启动另一个实例并检查正在运行的应用程序的CFBundleName,它只会告诉我原始值,即Python

^{pr2}$

我得想个办法Python.app版运行MyApp脚本以中止启动重复实例的实例。在

有这样的方法吗?在

更新:

在有更好的解决方案之前,我将使用lockf

import fcntl
lockfile = open('/tmp/myapp.lock', 'w')
fcntl.lockf(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)

更新2:

好吧,我还需要找到我的应用程序来集中精力。目前,我只是循环所有Python.app版实例并逐一聚焦。正常情况下,只有一个,但如果只有几个,可能会很混乱。在

from Foundation import NSWorkspace
from Cocoa import NSApplicationActivateAllWindows, NSApplicationActivateIgnoringOtherApps

try:
    import fcntl
    lockfile = open('/tmp/myapp.lock', 'w')
    fcntl.lockf(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)

except IOError as e:
    assert (e.errno, e.strerror) == (35, 'Resource temporarily unavailable')

    for app in NSWorkspace.sharedWorkspace().runningApplications():
        if app.bundleIdentifier() == 'org.python.python':
            app.activateWithOptions_(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)
    exit()

更新3:

在找到更好的解决方案之前,我将使用pid文件

LOCK_FILE = '/tmp/myapp.lock'
PID_FILE = '/tmp/myapp.pid'

try:
    import fcntl
    # NOTE: needs to be assigned to a variable for the lock to be preserved
    lockfile = open(LOCK_FILE, 'w')
    fcntl.lockf(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)

except IOError as e:    
    try:
        with open(PID_FILE) as f:
            pid = int(f.read())
    except:
        pid = None

    for app in NSWorkspace.sharedWorkspace().runningApplications():
        if app.bundleIdentifier() == 'org.python.python':
            if not pid or pid == app.processIdentifier():
                app.activateWithOptions_(NSApplicationActivateAllWindows | NSApplicationActivateIgnoringOtherApps)
    exit()

from Foundation import NSProcessInfo
info = NSProcessInfo.processInfo()
pid = info.processIdentifier()
with open(PID_FILE, 'w+') as f:
    f.write(str(pid))

Tags: 实例importinfolockapp应用程序openpid
2条回答

有几种方法可以解决这个问题。其中:

  • libunique-专门为此设计的库
  • dbus-内部通信系统

其中许多在this post的答案中描述。在

唯一实例的配方是here。在

一个不那么微妙的解决方案是使用应用程序的名称调用killall,而不从命令行中使用.app。这可以在Python脚本中使用os.command()完成。在

相关问题 更多 >