我正在试验用Python编写的osx应用程序,需要检测是否已经存在Python.app版用特定的脚本运行。该脚本将CFBundleName
从Python
动态修改为MyApp
,以更改菜单栏中的应用程序标题。在
bundle = NSBundle.mainBundle()
info = bundle.localizedInfoDictionary() or bundle.infoDictionary()
info['CFBundleName'] = 'MyApp'
如果我启动另一个实例并检查正在运行的应用程序的CFBundleName
,它只会告诉我原始值,即Python
:
我得想个办法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))
有几种方法可以解决这个问题。其中:
其中许多在this post的答案中描述。在
唯一实例的配方是here。在
一个不那么微妙的解决方案是使用应用程序的名称调用
killall
,而不从命令行中使用.app
。这可以在Python脚本中使用os.command()
完成。在相关问题 更多 >
编程相关推荐