BathyScaphe ネタ(その28)

Finder が起動していないとログファイルが削除できない件について。


BathyScaphe*1 は、ログファイルをゴミ箱に移動するのに Finder の力を借りている。CocoMonar 時代からそうである。Finder の力を借りるというのは、中の人の言葉で言うと Finder に AppleEvent を送っているということだ。
私は最近まで、ひどい勘違いをしていて……起動していないアプリケーションに AppleEvent を送ったら、勝手にそのアプリケーションが起ち上がってくれるんじゃないかと言う非常に甘く、ちょっと考えればアリエナイザーな挙動を何となく思い込んでいたのだ。たぶん、AppleEvent の後ろに AppleScript の幻影を見ていたのだろうと思う(もちろん、本当の位置関係は逆なのに!)。
もちろん、実際にはどうかと言うと、起動していないアプリケーションに AppleEvent を送っても、エラーが返ってくるだけなのであった。よってログファイルはゴミ箱に移動しないのである。


恐らく、このような場合に適切なのは、必要に応じて自動的に Finder を起ち上げさせてから AppleEvent を送信するように改良することであろう。よって、そのように修正する予定である。


ちなみに、NSWorkspace の -performFileOperation:source:destination:files:tag: で NSWorkspaceRecycleOperation を指定するというラクそうな方法については、未だになんとなく不安が拭えないので、考えていない。

追記:修正作業かんさつにっき

試しに Finder を終了した状態で Finder に AESendMessage() してみたら、エラー -600 (procNotFound) が返ってきた。最初 -609 (connectionInValid) が返ってくるのかと思っていたが、ハズレだったぜ*2


つまり、-600 が返ってきたら Finder に「起きろ!仕事だぞ!」とやらねばならない。そして、もう一度「ファイルをゴミ箱に入れてくれ!」と命じる訳だ。ここで二つの方法が考えられる:

  1. 「さっさと起きなさい!起きがけにゴミ箱に捨ててくるのよ!」と一度に命ずる。
  2. まず起こす。そして起きてきたら「おはよう Finder 君。ところでゴミ箱に捨ててきてくれ」と改めて頼む。

前者の方法を模索してみたのだが、やはり AppleEvent 周りは…いや、AppleEvent 周り以外の部分もだが、よく分からない。何やら Process Manager に LaunchApplication() というのがあったが、なんだか古くさそう*3なのであまり使いたくない(気分の問題だが)。一方、Cocoa に上がって -[NSWorkspace launchAppWithBundleIdentifier:options:additionalEventParamDescriptor:launchIdentifier:] の「additionalEventParamDescriptor」に何か上手い値を与えてやれば行けそうな感じがしたが、そもそも http://www.cocoabuilder.com/archive/message/cocoa/2007/4/9/181591 という情報を見つけてボツ。また Carbon に降りて LSOpenFromRefSpec() の方でやってみようか?…と思いつつも、このへんで疲れてきた。素直に後者の方法を採ることにした。


最後に細かい問題が一つ。Finder を -[NSWorkspace launchAppWithBundleIdentifier:options:additionalEventParamDescriptor:launchIdentifier:] なり LSOpenFromURLSpec() なりで「アクティブにしないで」起動させようと NSWorkspaceLaunchWithoutActivation (= kLSLaunchDontSwitch) を指定しても、どういうわけか Finder はアクティブになってしまうのだった。NSWorkspaceLaunchAndHide (= kLSLaunchAndHide) は有効だったけど…隠したい訳じゃないからな。出しゃばってほしくないだけで。まぁここは我慢してもらうか。

*1:正確には、BathyScaphe が内包している SGAppKit フレームワーク

*2:Technote tn1002: http://developer.apple.com/jp/technotes/tn1002.html を読んで推測していたのだが…この technote も 10 年前の情報だな、よく見れば

*3:Launch Services Reference を見ると、Tiger 以降で LSOpenApplication() というのが加わっていて、これが「This function is an updated alternative to the Process Manager's LaunchApplication function.」だそうである。しかし我々は Panther も相手にしなければならない。