如何确定应用程序是否没有响应?


11

我在OSX上有一个应用程序,该应用程序反复进入“无响应”状态,必须被强制杀死。我希望将其自动化,但是在使用ps检查进程时,没有看到与“无响应”状态相对应的任何内容。我查看了状态指示器,但无论是否响应,应用程序均显示为S。

state状态由一系列字符给出,例如``RWNA''。第一个字符指示进程的运行状态:

  • 我将一个进程标记为空闲(休眠时间超过约20秒)。
  • R标记可运行的进程。
  • S标记一个睡眠少于20秒的进程。
  • T标记已停止的进程。
  • U将进程标记为不间断等待。
  • Z标记死进程(``僵尸'')。

如何确定流程是否没有活动管理器那样响应


我也对AppleScript解决方案持开放态度。

Answers:


9

“无响应”状态不是进程状态,而是进程已停止与窗口管理器/图形引擎的通信。可以将它绑在一个循环中,挂在套接字,远程文件上,任何使它返回到处理事件的主循环的东西都可以。窗口管理器注意到事件正在排队,因此将其标记为“未响应”

您可能需要编写一个小的X11程序,该程序将虚拟事件发送到该进程,然后在没有响应的情况下将其杀死。


也许用AppleScript编写一些作为UI级别访问权限的东西。
Matthieu Riegler 2013年

@MatthieuRiegler您将如何在AppleScript中做到这一点?
C. Ross

我在另一个答案中提供了一个示例。
Matthieu Riegler

4

这是一个使用UI脚本的AppleScript,它查找无响应的进程并将其杀死。

它将与Mavericks的活动监视器配合使用。但是,由于这是UI脚本,并且由于活动监视器的UI已更改,因此,如果不作一些较小的修改,这很可能不适用于旧版OSX。

tell application "Activity Monitor" to run  --We need to run Activity Monitor
tell application "System Events" to tell process "Activity Monitor"
    tell radio button 1 of radio group 1 of group 1 of toolbar 1 of window 1 to click --Using the CPU View 
    tell outline 1 of scroll area 1 of window 1 -- working with the list 
        set notResponding to rows whose value of first static text contains "Not Responding" -- Looking for Not responding process
        repeat with aProcess in notResponding
            set pid to value of text field 5 of aProcess  -- For each non responding process retrieve the PID 
            if pid is not "" then do shell script ("kill -9 " & pid) -- KILL the PID. 
        end repeat
    end tell
end tell

我在网上遇到编译错误tell radio button 1 of radio。我删除了该文件,并进行了一些其他调整(我只想杀死特定程序),并得到运行时错误:'错误“系统事件出现错误:辅助设备的访问被禁用。” 进程“活动监视器”的窗口1中的数字-1719”
C. Ross

是否在OSX Mavericks上运行了该脚本?
Matthieu Riegler

OSX 10.8,所以没有。
C. Ross

在更改为tell radio button 1 of radio group 1 of group 2 of toolbar 1 of window 1 to click
Charlie Gorichanaz

0

(由于过长而无法放入评论中,因此将其作为单独的答案发布)

感谢@MatthieuRiegler提供原始脚本。

这在10.12.6上有效,是对原始脚本的较小修改(在我自己调查之后,看到@CharlieGorichanaz的评论):


set textToSearchForInProcessName to "Not Responding"

--  Run Activity Monitor 
tell application "Activity Monitor" to activate

tell application "System Events" to tell process "Activity Monitor"
    --  Wait for the Activity Monitor window to open
    repeat until (exists window 1)
        delay 1
    end repeat
    --display notification "Window appeared"

    --  Wait for the Menubar to be present
    repeat until (exists menu 1 of menu bar item "View" of menu bar 1)
        delay 1
    end repeat
    --display notification "Menubar appeared"

    --  Make sure View -> My Processes is selected 
    click menu item "My Processes" of menu 1 of menu bar item "View" of menu bar 1

    --  Click the 'CPU View' button  ( **1 ) 
    click radio button 1 of radio group 1 ¬
        of group 2 of toolbar 1 ¬
        of window 1

    --  Working with the list of processes 
    tell outline 1 of scroll area 1 of window 1
        --  Looking for Not responding process  
        set notResponding to rows whose value of ¬
            first static text contains textToSearchForInProcessName

        repeat with aProcess in notResponding

            --  For each non responding process retrieve the PID 
            set pid to value of text field 1 of aProcess -- ( **2 )

            --  Kill that process using pid 
            if pid is not "" then do shell script ("kill -9 " & pid)
        end repeat
    end tell
end tell

** 1 在MACOS 10.12.x,工具栏包含一个额外的在此处输入图片说明图标由于该组按钮(CPU,内存,能源等)都在 group 2 of toolbar 1代替group 1 of toolbar 1。如果没有该图标(我尚未在较早的macOS版本中确认),我相信CPU等按钮将位于group 1 of toolbar 1

** 2 如果您曾经将“活动”列中的PID列拖动到其他位置,则适用此规则。我将PID列拖到最左侧,因此在这一行上,我不得不将索引更改为1

set pid to value of text field 1 of aProcess

列从1的最左边开始编号。因此,如果需要,请在上一行中相应地调整突出显示的索引。

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.