如何确保Applescript对话框集中在OS X 10.10(Yosemite)?

时间:2014-10-05 20:44:17

标签: applescript

在OS X 10.10(Yosemite)之前,我可以通过告诉当前应用程序"来确保AppleScript对话框具有焦点。激活:

tell current application
        activate
        set output to (do shell script "printf '" & hostsLine & commentString & "' >> /private/etc/hosts" with administrator privileges)
end tell

这会将密码对话框置于前面以输入。对话框不再出现焦点在Yosemite中,您必须先点击它才能输入。

在堆栈交换和其他地方搜索没有提供任何解决方案/解决方法。

有没有人有办法在OS X 10.10中运行?

更新1:如果其他人遇到此问题,它似乎是一个新的沙盒问题。非密码对话框可以正确聚焦。事实上,在"之前的非密码对话框具有管理员权限"密码对话框将使密码对话框也具有焦点。我添加了一个对话框,确认Safari在测试时仍然是前端应用,并发现了这一点。作为一种解决方法,我添加了一个前面的对话框,超时为1(秒),直到找到更好的解决方案。

tell me -- alternate method: tell current application
    activate
    display dialog "Trying to get focus…" with title "Can't focus in Yosemite" buttons {"Cancel", "Idle"} cancel button "Cancel" giving up after (1)
    set output to (do shell script "printf '" & hostsLine & commentString & "' >> /etc/hosts" with administrator privileges)
end tell

有趣的是,BBedit的Authenticated Save帮助程序脚本(适用于应用程序的MAS版本)使用具有管理员权限的""密码对话框。但它在优胜美地得到了适当的关注。对于应用程序,应用程序调用applescript与Applescript tell命令之间有什么不同吗?

on documentShouldFinalizeAuthenticatedSave(theDocument, tempFilePath, destinationPath)

    -- on input: tempFilePath points to the contents of the document written to a temp file, ready to move to the destination; destinationPath is where the file should be copied.

    -- on exit: if the operation succeeded, delete the temp file (or else the application will assume the operation failed) and return YES for success

    --  this is pretty straightforward: "cp tmpFilePath destinationPath"

    do shell script "cp" & " " & quoted form of tempFilePath & " " & quoted form of destinationPath with administrator privileges

    --  now remove the temp file, this indicates to the application that we did the work

    do shell script "rm" & " " & quoted form of tempFilePath

    return true
end documentShouldFinalizeAuthenticatedSave

更新2:如果有人好奇,我的妻子的Safari助手脚本的这部分将阻止像mackeeper.zeobit.com这样具有模态对话框的垃圾邮件弹出广告网站。编辑/ etc / hosts有点太复杂/令人生畏,她想要一个交钥匙解决方案。如果有兴趣,我可以发布整个脚本。它在10.9下工作正常,但密码问题的焦点在10.10中很烦人。

8 个答案:

答案 0 :(得分:0)

你可以试试......告诉我而不是告诉当前的应用程序。 “告诉我”基本上告诉applescript激活并运行“do shell script”命令。这更有意义。 “do shell script”是一个applescript命令,因此请求AppleScript运行它是有意义的。也许这会对你的问题有所帮助。

祝你好运。

答案 1 :(得分:0)

就个人而言,我不需要输入密码。最简单的方法是将以下行附加到/ private / etc / sudoers文件。

wife_user_name  ALL=(ALL) NOPASSWD:ALL

要删除所有管理员帐户的密码需求,请更改/ private / etc / sudoers文件中的以下行

%admin  ALL=(ALL) ALL

%admin  ALL=(ALL) NOPASSWD: ALL

接下来,从

更改Applecript行
    set output to (do shell script "printf '" & hostsLine & commentString & "' >> /private/etc/hosts" with administrator privileges)

    set output to (do shell script "sudo printf '" & hostsLine & commentString & "' >> /private/etc/hosts")

可以使用Terminal和TextEdit应用程序更改/ private / etc / sudoers文件。打开终端应用程序并键入以下命令:

cd ~/desktop
sudo cp -n /etc/sudoers /etc/sudoers.orignal
sudo cp /etc/sudoers sudoers.txt
sudo chmod ug+w sudoers.txt
open sudoers.txt
visudo -c -f sudoers.txt
sudo cp -X sudoers.txt /etc/sudoers

完成后,桌面上的sudoers.txt文件可以放入垃圾箱。

要撤消更改,请使用以下命令:

sudo cp /etc/sudoers.original /etc/sudoers

使用OS X 10.10.1进行了测试

以下是每个命令的作用的简要说明:

cd ~/desktop

这可以确保您使用的是桌面文件夹。

sudo cp -n /etc/sudoers /etc/sudoers.original

这会备份您的sudoers文件。备份可用于撤消更改。 -n选项确保不会覆盖现有的sudoers.original文件。

sudo cp /etc/sudoers sudoers.txt

将sudoers文件复制到桌面。添加.txt扩展名,以便OS X知道这是一个文本文件。

sudo chmod ug+w sudoers.txt

更改文件的权限以允许写访问权限。

open sudoers.txt

在TextEdit应用程序中打开文件。您需要编辑文件并保存更改。

visudo -c -f sudoers.txt

检查已编辑的文件是否存在语法错误。输出应为sudoers.txt: parsed OK

sudo cp -X sudoers.txt /etc/sudoers

将文件复制回/ etc目录。

答案 2 :(得分:0)

2015-01-08编辑

迈克,我理解你的问题是:"我有一个带有do shell script的AppleScript要求输入管理员密码,但我必须先单击密码对话框才能输入密码。如何确保对话框具有焦点,省去了点击它的麻烦?"

我对你的回答是:"如果你的AppleScript从未问过密码怎么办?你不高兴吗?"

如果是,那么here's a solution。该问题演示了如何通过提供password参数以及with administrator privileges参数来绕过对话框。

答案 3 :(得分:0)

我偶然发现这篇文章试图获取密码对话框,以便将焦点放在我正在处理的Alfred脚本中。我终于通过在shell命令之前添加tell me to activate来可靠地工作。结果脚本是:

tell me to activate
do shell script "<command>" with administrator privileges

希望这适合你。

答案 4 :(得分:0)

好的,迈克,这是我第二次尝试答案。

而不是使用

tell current application
    activate
    set output to (do shell script "printf '" & hostsLine & commentString & "' >> /private/etc/hosts" with administrator privileges)
end tell 

正如您在上述问题开头时提出的那样,请尝试使用

tell current application
    activate
    tell me to set output to (doShellScript for "printf '" & hostsLine & commentString & "' >> /private/etc/hosts" with administratorPrivileges)
end tell 

doShellScript处理程序

on doShellScript for command as text given administratorPrivileges:adminPriv as boolean : false
    if adminPriv then
        set message to (name of current application) & " wants to make changes. Type your password to allow this."
        set again to ""
        set pw to ""
        set icn to 1
        repeat
            set fullCommand to "printf '%s\\n' " & (quoted form of pw) & " | sudo  -p '' -S " & command
            try
                return do shell script fullCommand
            on error eStr number eNum partial result rList from badObj to expectedType
                set errorMessage to "Sorry, try again." & return & return & "sudo: 1 incorrect password attempt"
                if eStr ≠ errorMessage or eNum ≠ 1 then
                    error eStr number eNum partial result rList from badObj to expectedType
                end if
            end try
            set actual to again & message
            set values to display dialog actual default answer "" with icon icn with hidden answer
            set again to "Sorry, incorrect passord. Try again." & linefeed
            set pw to text returned of values
            set icn to 2
        end repeat
    end if
    return do shell script command
end doShellScript

示例对话框如下所示。

Sample dialog box

您的应用程序名称和图标将有所不同。主要的是 当弹出对话框时,焦点将出现在密码文本框中

戴夫。

答案 5 :(得分:0)

我有一个类似的问题,我有一个AppleScript脚在终端执行连续ping,然后会弹出一个对话框,以便用户单击OK以终止该ping并启动另一个ping。问题类似于终端窗口后面显示的对话框。由于我必须在非常有限的时间内在紧急情况下多次执行此脚本,这非常烦人。我终于能够通过告诉系统事件在开始连续ping之后等待1秒来解决它,然后在打开对话框之前按键CMD + Tab切换回正在运行的脚本。 CMD + Tab最初只是间歇性地解决了它,直到我添加了延迟1。

问题示例:

tell application "Terminal" to do script pingCommand
set userDialog to display dialog "Client Connection Test Completed" buttons {"Ping Server", "Cancel"} 

使用上面的代码,对话框将始终位于终端窗口后面。

解决方案示例:

tell application "Terminal" to do script pingCommand
delay 1  
tell application "System Events" to key code 48 using {command down}
set userDialog to display dialog "Client Connection Test Completed" buttons {"Ping Server", "Cancel"} 

答案 6 :(得分:0)

我遇到了同样的问题,并创建了一个解决方案,可以将我的applet对话框放在前面。

我写了一个名为ActivateMe()的函数来取代&#34;激活&#34;或者&#34;告诉我激活&#34;将继续&#34;显示对话框的命令&#34;命令。

此函数获取当前进程名称,然后通过shell脚本执行以下AppleScript命令。

    delay 0.1
    tell application "System Events"
        set frontmost of process \"" & processName & "\" to true
    end tell"

这是功能。享受。

on ActivateMe()

    set myPath to path to me as text
    if myPath ends with ":" then
        set n to -2
    else
        set n to -1
    end if
    set AppleScript's text item delimiters to ":"
    set processName to text item n of myPath
    if (processName contains ".") then
        set AppleScript's text item delimiters to "."
        set processName to text 1 thru text item -2 of processName
    end if
    set AppleScript's text item delimiters to ""

    set a to "delay 0.1"
    set b to "tell application \"System Events\""
    set c to "set frontmost of process \"" & processName & "\" to true"
    set d to "end tell"
    do shell script "osascript -e '" & a & "' -e '" & b & "' -e '" & c & "' -e '" & d & "'"

end ActivateMe

答案 7 :(得分:0)

似乎是10.10.x中的一个错误,很可能是由于沙盒造成的。修复了10.11(El Cap),因为未修改的脚本再次从activate命令获得焦点,就像在10.9及更早版本中一样。