在参考同一应用程序的多个实例时,有没有人能想到osascript逐个索引瓶颈的解决方法?
如果我们获得两个进程ID - 一个用于同一个应用程序的两个不同实例中的每一个,osascript返回相同的实例以换取pid - 就好像它首先将pid映射到应用程序名称,然后检索第一个具有该名称的申请流程。
例如,启动两个不同的VLC.app实例,播放两个不同的视频文件,例如:
open -na /Applications/VLC.app ~/fileA.m4v
open -na /Applications/VLC.app ~/fileB.m4v
然后获取两个单独的应用程序进程ID,例如:
echo "$(ps -ceo pid=,comm= | awk '/VLC/ { print $1}')"
然后我们可以使用Applescript或Yosemite JXA Javascript从pid获取对应用程序对象的引用。
然而,事实证明,无论我们提供哪个进程ID,我们总是返回对同一实例的引用,运行相同的视频文件,就像osascript只是将pid转换为应用程序名称一样,然后始终返回与该名称匹配的第一个进程。
Yosemite Javascript for applications:
function run() {
var app = Application.currentApplication();
app.includeStandardAdditions = true;
var lstVLC = app.doShellScript(
"echo \"$(ps -ceo pid=,comm= | awk '/VLC/ { print $1}')\""
).split(/[\r\n]/).map(Number).map(Application);
return {
firstInstance: lstVLC[0].windows[0].name(),
secondInstance: lstVLC[1].windows[0].name()
};
}
AppleScript的:
on run {}
set strCMD to "echo \"$(ps -ceo pid=,comm= | awk '/VLC/ { print $1}')\""
set lstNum to paragraphs of (do shell script strCMD)
repeat with i from 1 to length of lstNum
set item i of lstNum to (item i of lstNum) as number
end repeat
tell application "System Events"
set oProcA to first application process where unix id = (item 1 of lstNum)
set oProcB to first application process where unix id = (item 2 of lstNum)
end tell
return [name of first window of oProcA, name of first window of oProcB]
end run
有关分别编写每个实例脚本的路线的想法吗?
答案 0 :(得分:1)
对于每个实例,请从与特定进程相同的行询问窗口名称,如下所示:
set windowNames to {}
set lstNum to paragraphs of (do shell script "ps -ceo pid=,comm= | awk '/VLC/ { print $1}'")
tell application "System Events" to repeat with i in lstNum
set end of windowNames to name of first window of (first application process where unix id = i)
end repeat
return windowNames
答案 1 :(得分:1)
这似乎已在El Capitan修复,因为您的JavaScript代码在我的计算机上正常运行。
答案 2 :(得分:0)
在Javascript中使用jackjr300的方法,至少要获得UI脚本(但不是到应用程序对象界面):
function run() {
var appSE = Application("System Events");
app = Application.currentApplication();
app.includeStandardAdditions = true;
function uiWidgets(lngID) {
return appSE.processes.whose({
unixId: lngID
})[0].windows[0].uiElements();
}
var lstWidgets = app.doShellScript(
"ps -ceo pid=,comm= | awk '/VLC/ { print $1}'"
).split(/\r/).map(Number).map(uiWidgets);
return lstWidgets;
}
答案 3 :(得分:0)
JXA是一堆错误和缺陷设计。它没有做到这样right这样的事情令人沮丧,但完全不足为奇(AS团队has form)。
对于AppleScript,它从未提供过通过PID定位应用程序的直接方法。在过去,我可能通过启用远程Apple事件并使用eppc://USER@HOST/APPNAME?pid=PID
网址定位该流程来欺骗它,但是如果我能够让它继续工作,那么在10.10时尝试它会因为它始终返回"不允许远程访问"错误。
Appscript可以在睡眠中完成这些工作,但由于Apple的“碳战争”和糟糕的“替换”,我dropped公众支持它。 Cocoa API迫使它进入"遗产"状态,所以你自己在那里。
可能有效的官方支持选项是OS X的Scripting Bridge框架,它提供了一种通过PID定位进程的方法。虽然像JXA一样,它充斥着设计缺陷,缺少功能和应用程序兼容性问题,所以YMWV。