@khagler 的评论提供了正确的指针:VLC 实例必须通过 System Events 上下文中的 PID(进程 ID;在 AppleScript 中称为 unix id)来区分。
下面的代码应该做你想做的事,经过大量的辛劳和麻烦 - 与 [AppleScript 障碍] 课程相当。一个障碍是 VLC 实例的主窗口没有立即创建。
cmets 提供了更多细节。
请注意,由于用户界面元素是通过编程方式操作的,因此出于安全原因,必须为运行您的脚本的应用程序授予 assistive access。
请注意,我使用 do shell script "open -na VLC.app" 启动实例,这取决于启动服务已知的应用程序的位置(如果由于某种原因不起作用,请恢复为指定完整路径的方法)。
# Specify the desired window bounds.
# !! In the "System Events" context, windows do not
# !! have `bounds` properties, but separate `position` and
# !! `size` properties.
set WIN_POSITIONS to {{13, 36}, {13, 544}, {13, 1043}}
set WIN_SIZES to {{790, 519}, {790, 519}, {790, 519}}
# Launch the VLC instances.
repeat with i from 1 to count of WIN_POSITIONS
do shell script "open -na VLC.app"
end repeat
# Note:
# Instance-specific manipulation must
# be performed in the "System Events" context, because
# we must distinguish the VLC instances by their
# PIDs (process IDs; called `unix id` in AppleScript).
tell application "System Events"
# Get the PIDs (process IDs) of all VLC instances.
set vlcPids to get the unix id of every process whose name is "VLC"
# Loop over all instance PIDs.
# !! It is imperative to *continue* to use object specifiers
# !! with *filters based on the PID* so as to ensure that the
# !! individual instances are targeted.
# !! Attempting to store references to these instances in
# !! variables fails subtly, as evidenced by the "Events"
# !! tab in AppleScript editor later showing the non-specific
# !! process "VLC" of application "System Events" specifiers.
set winNdx to 1
repeat with vlcPid in vlcPids
# WAIT for each instance to create its main window, wich
# sadly, is not available right away.
# Once created, position it.
set haveWin to false
tell (first process whose unix id is vlcPid)
repeat with i from 1 to 25 # times out after 25 * .2 == 5 secs.
if (count of windows of it) > 0 then
set haveWin to true
tell front window of it
# !! In the "System Events" context, windows do not
# !! have `bounds` properties, but separate `position` and
# !! `size` properties.
set position to item winNdx of WIN_POSITIONS
set size to item winNdx of WIN_SIZES
end tell
exit repeat
end if
delay 0.2 # no window yet; sleep some and try again
end repeat
end tell
if not haveWin then error "VLC instance " & vlcPid & " unexpectedly did not create a window within the timeout period."
set winNdx to winNdx + 1
end repeat
end tell
如何使用 Finder 进行这项工作:
Targeting Finder 改变方法有两个原因:
- 只有 一个 Finder 实例。
- 你不能用
open -na Finder.app打开多个窗口;谢天谢地,this answer 展示了如何做到这一点(请参阅那里的 cmets 了解怪癖)。
请注意,以下内容会盲目打开其他 Finder 窗口。
set WIN_POSITIONS to {{13, 36}, {13, 544}, {13, 1043}}
set WIN_SIZES to {{790, 519}, {790, 519}, {790, 519}}
# Sample target locations for the Finder windows.
# Note the use of the "System Events" context to faciliate use of
# POSIX-style *input* paths; note, however, that the paths are
# *stored* as HFS paths so that Finder accepts them.
tell application "System Events"
set WIN_TARGETS to {¬
path of desktop folder, ¬
path of folder "~/Downloads", ¬
path of folder "/Library/Audio"}
end tell
set winCount to count of WIN_POSITIONS
# Launch the Finder windows.
tell application "Finder"
# Create the windows in reverse orders.
repeat with i from winCount to 1 by -1
set newWin to make new Finder window
set target of newWin to item i of WIN_TARGETS
end repeat
end tell
tell application "System Events"
set i to 1
repeat with i from 1 to winCount
tell window i of application process "Finder"
# !! In the "System Events" context, windows do not
# !! have `bounds` properties, but separate `position` and
# !! `size` properties.
set position to item i of WIN_POSITIONS
set size to item i of WIN_SIZES
end tell
end repeat
end tell