« [REALbasic]Mac OS Xでは、GlobalFloatingWindowのFloaterProcessが有効にならない問題 | Main | [REALbasic]AppleEvent VS. AppleScriptどっちが速い? »

2005.08.18

[REALbasic]特定のアプリケーションプロセスの存在の有無をAppleEventで確認する in Mac OS X

AppleEventを送る際、SystemEventの送信先が居ないとハングするっぽいので、対象プロセスが居るかどうか確認する必要がある。
それっぽいメソッドが見つけられなかったので、やっぱりAppleEventで実装。トホホ。

ScriptDebuggerで以下のスクリプトを実行。

tell app "finder" to exists application process "Safari"

AppleEventのログを見ると、Finder(MACS)からは値を返しておらず、System Eventsに下請けに出しており、そこから値が返ってきていることが分かる。Mac OS Xになってからは、Finderではプロセス管理をやらなくなっているようで、AppleEventは、最初からSystem Eventsに送信する必要がある。FinderにAppleEventを送っても、System Eventsへの引き継ぎはやってくれずnullとか0とかしか返してこない。

ScriptDebuggerのログでは、AppleEventの送信対象を記録してくれないので、ちとハマった。System Eventsのクリエータタイプってどうやって調べんのよ(笑)。

"/System/Library/CoreServices/System Events.app"に実体があることが分かったので、
"System Events.app/Resources/SystemEvents.scriptSuite"に、AppleEventCodeの記載があることを確認。めでたく"sevs"にAppleEventを送ればいいことが分かった。Cocoaでscriptableなアプリはこの手で調べられるみたい。Carbonアプリは、旧来の手法が使えるはず。

Dim ae as AppleEvent
Dim obj As AppleEventObjectSpecifier
ae = NewAppleEvent("core","doex","sevs")
obj = GetNamedObjectDescriptor("pcap", nil, "Safari") //プロセス名で探す
obj = GetPropertyObjectDescriptor(obj, "pvis") //Visible = Trueのみに
ae.ObjectSpecifierParam("----") = obj

If ae.Send() Then

If ae.ReplyBoolean = True Then
editfield1.text = "起動中"
Else
editfield1.text = "起動してない"
End If
End If

ちなみに、リファレンスのGetOrdinalObjectDescriptorに載っているサンプルコードも、Mac OS Xではもはやobsoleteで動かないはず。以下に書き換えればOK。

Dim a as AppleEvent
Dim i, count as Integer
a = NewAppleEvent("core", "cnte", "sevs")
a.MacTypeParam("doex") = "prcs"
a.ObjectSpecifierParam("----") = GetOrdinalObjectDescriptor("prcs", nil, "all ")
If a.Send then
count = Val(a.ReplyString)
End if
editfield1.text = str(count)

|

« [REALbasic]Mac OS Xでは、GlobalFloatingWindowのFloaterProcessが有効にならない問題 | Main | [REALbasic]AppleEvent VS. AppleScriptどっちが速い? »