Macos 用于检查正在运行的应用程序并关闭上次打开的实例的AppleScript(或备选方案)

Macos 用于检查正在运行的应用程序并关闭上次打开的实例的AppleScript(或备选方案),macos,process,applescript,Macos,Process,Applescript,我有一个OSX应用程序,我们叫它TestOSX.app。这是它显示的名称(据我所知,取自Info.plistCFBundleName键) 出于各种原因(可以通过将应用程序复制到另一个地方或从终端打开应用程序来规避此问题;如果CbundleExecutable不是二进制文件本身,而是在启动二进制文件之前设置某些内容的脚本,则此问题不起作用……),我不能依靠OS X的内置策略阻止某人启动应用程序的第二个实例,也不能使用lsmultipleinstancesprohibed键。但我确实希望确保由同一用

我有一个OSX应用程序,我们叫它
TestOSX.app
。这是它显示的名称(据我所知,取自
Info.plist
CFBundleName
键)

出于各种原因(可以通过将应用程序复制到另一个地方或从终端打开应用程序来规避此问题;如果
CbundleExecutable
不是二进制文件本身,而是在启动二进制文件之前设置某些内容的脚本,则此问题不起作用……),我不能依靠OS X的内置策略阻止某人启动应用程序的第二个实例,也不能使用
lsmultipleinstancesprohibed
键。但我确实希望确保由同一用户启动的每一个实例在能够修改某些资源之前都将退出。不同的用户应该能够同时运行他们自己的应用程序的单个Instance(这就是为什么
LSMultipleInstancesProhibited
不可行的原因)

(我想建立一个依赖于
flock(1)
的机制,但它在OSX下不存在。)

因此,策略是:当用户启动我的应用程序时,首先检查旧版本是否已经在运行;如果存在,则向这个最新的应用程序实例(脚本已“从”执行)发送退出请求,并将旧实例置于前台

我不能使用进程本身的名称,因为应用程序可能使用一些嵌入式工具(如专有更新程序),这些工具的名称与应用程序本身的名称不同。这就是为什么这样的事情不起作用:

tell application "System Events"
  set listOfProcesses to (name of every process where background only is false)
end tell
,正如所识别的过程可以简单地说,
updater
(它是TestOSX捆绑包的一部分)

我有一个片段,可能是“大事件”的一部分,但它没有按预期工作:

tell application "System Events"
  set theProcess to first application process whose displayed name is "TestOSX"
  set theOtherProcess to second application process whose displayed name is "TestOSX"
  set frontmost of theOtherProcess to true
end tell
,此应用程序始终只显示第一个应用程序的流程

我不明白为什么它不能像预期的那样工作,只要:

tell application "System events"
  set listOfProcesses to (name of every process whose (dsiplayed name is "TestOSX"))
end tell
返回两个实例。我猜在某个地方,进程和名称之间的映射正在丢失

[编辑] 尝试使用以下命令修改上面的代码段:

tell application "System Events"
  set theOtherProcess to id of second application process whose displayed name is "TestOSX"
  set frontmost of theOtherProcess to true
end tell
,但我得到了一个错误:

"Can't set frontmost of 680102 to true."

(这可能是因为我有一个实际启动二进制文件的脚本,如上所述?

好吧,我想出了一个丑陋的解决方案

双击app图标启动的bash脚本将检查我的app有多少实例正在运行(借助AppleScript)。如果答案不止一个,bash脚本将结束,因此我的整个应用程序将终止

我的
launcher.command
脚本:

#!/bin/bash
val=$(osascript ./instances_counter.scpt "TestOSX")
实例\u counter.scpt
,利用我传递的参数:

on run argv
    tell application "System Events"
        set theProcessList to every application process whose displayed name is item 1 of argv
        set noOfProcesses to count of theProcessList
    end tell
    return noOfProcesses
end run
就这样