如何通过应用程序关闭窗口并传递文件名?


9

我试图产生一个基于Applescript的shell命令,该命令告诉Mac OS X中的Preview应用程序关闭特定窗口。

#!/bin/sh

osascript <<EOF
tell application "Preview"
   close "$1"
end tell
EOF

但这不起作用:我收到错误消息

25:52: execution error: Preview got an error: "musixdoc.pdf" doesn’t understand the close message. (-1708)

相关问题:如何使用.bash_profile中定义的别名从命令行关闭OS X应用程序?


这应该按预期工作。您究竟如何调用脚本?注意:您的脚本不会关闭特定窗口。它将退出应用程序,从而关闭该应用程序可能已打开的所有文档窗口。为了关闭特定文档,应用程序已打开但本身并未退出,您需要其他脚本。尽管大多数应用程序在关闭最后一个文档窗口时都退出了,但并非全部退出-这还取决于您使用的OS X版本。
slhck

@slhck:“关闭应用程序打开的特定文档,但不退出应用程序本身”正是我需要的。您是否偶然知道某个地方解释了这样的“不同脚本”?
Ewan Delanoy 2013年

Answers:


10

获取Preview.app接受AppleScript命令

默认情况下,AppleScripting Preview无法使用,因为Preview缺少必需的字典。要解决此问题,请在此处查看Lauri的答案,其中解释NSAppleScriptEnabled了Preview.app的设置。

退出Preview.app,然后打开一个终端并输入:

sudo defaults write /Applications/Preview.app/Contents/Info NSAppleScriptEnabled -bool true
sudo chmod 644 /Applications/Preview.app/Contents/Info.plist
sudo codesign -f -s - /Applications/Preview.app


从应用程序关闭窗口

1)通过窗口索引或窗口名称

关闭任何已命名应用程序窗口的命令如下所示:

tell application "Preview" to close window 1

…或者如果您想关闭一个命名文档窗口,例如foo.jpg

告诉应用程序“ Preview”关闭(每个名为“ foo.jpg ”的窗口)

因此,在您的shell脚本中,将是:

#!/bin/sh
osascript <<EOF
tell application "Preview"
  close (every window whose name is "$1")
end tell
EOF

在这里,传递给脚本的第一个参数是您要关闭的窗口的名称,例如./quit.sh foo.jpg。请注意,如果文件中包含空格,则必须引用文件名,例如./quit.sh "foo bar.jpg"

或者,如果您想从任何应用程序中关闭任意窗口,请使用以下命令:

#!/bin/sh
osascript <<EOF
tell application "$1"
  close (every window whose name is "$2")
end tell
EOF

在这里,您将使用./quit.sh Preview foo.jpg例如。

2)按文件名

如果要关闭属于某个文档的窗口,但要提供文件名,则需要其他操作。这是因为多页PDF可能显示为foo.pdf (Page 1 of 42),但是您只想传递foo.pdf给AppleScript。

在这里,我们遍历窗口,并将文件名与传递给脚本的参数进行比较:

osascript <<EOF
tell application "Preview"
    set windowCount to number of windows
    repeat with x from 1 to windowCount
        set docName to (name of document of window x)
        if (docName is equal to "$1") then
            close window x
        end if
    end repeat
end tell
EOF

现在您可以简单地致电./quit.sh foo.pdf。以一种通用的方式,对于所有具有命名文档窗口的应用程序,将是:

osascript <<EOF
tell application "$1"
    set windowCount to number of windows
    repeat with x from 1 to windowCount
        set docName to (name of document of window x)
        if (docName is equal to "$2") then
            close window x
        end if
    end repeat
end tell
EOF


警告:自动关闭Preview.app

Preview.app是这些应用程序之一,一旦关闭了它的最后一个文档窗口,它们就会自动退出。这样做是为了节省内存并“清理”。若要禁用此行为,请运行以下命令:

defaults write -g NSDisableAutomaticTermination -bool TRUE

当然,要撤消该更改,请更改TRUEFALSE


使用函数代替脚本

最后,我建议将脚本放入外壳中始终可用的函数中。为此,请将脚本添加到中~/.bash_profile。如果该文件不存在,则创建它。

cw() {
osascript <<EOF
tell application "$1"
    set windowCount to number of windows
    repeat with x from 1 to windowCount
        set docName to (name of document of window x)
        if (docName is equal to "$2") then
            close window x
        end if
    end repeat
end tell
EOF
}

保存bash配置文件并重新启动Shell后,您可以cw Preview foo.pdf从任何地方进行调用。


我试过了 这次我没有收到任何错误消息,但是脚本仍然不起作用:窗口在屏幕上保持可见。
Ewan Delanoy

它为我工作。如果在Preview.app中打开文档,然后打开AppleScript编辑器,然后输入tell application "Preview" to windows,这是否会给您带来任何结果?您正在运行什么确切的脚本?
slhck

我不使用AppleScript编辑器,仅在bash脚本中使用“嵌入式applescript代码”,如OP中所述,存储在.sh文件中。
Ewan Delanoy

实际上,我通常对shell脚本很满意,这是我的第一个applescript。我只是按照您在上一条评论中的建议进行操作,并得到了“ {应用程序“ Preview”的窗口ID 113”}}作为答案。那是我应该得到的吗?
Ewan Delanoy 2013年

另外,当我使用applescript编辑器编译<<告诉应用程序“ Preview”以关闭“ musixdoc.pdf” >>时,它也不起作用:musixdoc.pdf窗口在屏幕上保持可见。
Ewan Delanoy 2013年

0

slhck的回答看起来很好而且很彻底。当心,执行第三行代码

sudo codesign -f -s - /Applications/Preview.app

“似乎”已导致预览在每次启动时因以下原因崩溃:

Application Specific Information:
XPC domain creation failed: The code signature is not valid: The operation couldn’t be completed. (OSStatus error -67061.)

根据codesign手册,这-f是强制“替换现有的代码符号”,并且-s是“在给定的路径上对代码签名”……在这种情况下-

显然,预览现在签名不正确,无法使用。:(

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.