Top 上へ 目次
Ver.8.0以降で予定している機能の話の続きの続き
Ver.8.0.3をリリースしてから一週間ほど経過しましたが、なんと障害レポートが1件もありません。
(Ver.7系の報告をチラホラ頂いてますが改修済みの内容と考えてます、またOSの再起動に巻き込まれた強制終了も未カウントです)
窓の杜さんで、メジャーアップデートを紹介されたりして、ダウンロード数が多めに振れてる状況も加味すると、かなり改善されたんじゃないかと判断できます。
せっかくなので何が一番の原因だったかということを語っておこうと思います。
プログラム屋さん向けのネタです。
パス文字列「c:\windows」などのテキストのパス表記は、Windowsの中の人であるシェルインターフェイスでは扱えません。
必ずシェルインターフェイスで扱えるITEMIDLISTというバイナリ型に変換する必要があるんですね。
多分、この中にキャッシュ情報のタイムスタンプとかファイルサイズまでも埋まってると推測しています。
まぁ、この手のAPIは複数用意されていて
ILCreateFromPath()
SHILCreateFromPath()
SHSimpleIDListFromPath()
IShellFolder::ParseDisplayName()
などなど、複数の手段が用意されてます。
結果から語っちゃいますが、これらのAPIを呼び出し、別のスレッドなりプロセスで返ってくる前に、そのファイルを削除/更新/追加を2回以上行うとAPI内部で落ちることがあります。
発生するのはごくまれになので、厳密な法則は分かりませんが、ディスクの性能限界に近い速度でファイル操作を連続発生させると現象が多めに出るような気がします。
また現象が発生するのは、RAMディスク、HDD、ネットワーク上のフォルダ、外部ストレージ、仮想フォルダを問いません。
NASだと発生しやすいとか、RAMディスクでも現象が出にくいドライブもあるようなので、ドライバ関係の問題の可能性も否定できません。
そして落ちてるアドレスを見る限り、削除/更新/追加ごとに色んなパターンがあるようです。
もちろんAPI仕様にない動作ですし、イベントログに掲載されるような落ち方をするAPIなんぞ、どう考えてもWindowsのバグなわけで、OSによって発生頻度や発生パターンが異なるというオマケ付きです。
(COMインターフェイスに絡んだ寿命管理か、ディスクキャッシュか、排他制御が怪しいと考えてます)
で、ナニをしたかというと
LPITEMIDLIST ILCreateFromPathSafe(LPCTSTR szBuff)
{
try
{
return ILCreateFromPath(szBuff);
}
catch (...)
{
return NULL;
}
}
こんな感じで、例外を捕まえるようにしました。
凄まじくバカバカしい対処方法ですが1年ぐらい悩みまくったトラブルの多くが、これで解消したと結果が出たのが余計に始末が悪いです
ちょっと暴投を投げますが、As/Rでは一切の例外処理を使っておらず、リリースビルドのコンパイラオプションで例外のキャッチを無効にしてました。
例外処理って結構なオーバーヘッドがあるので、速度面でもメモリ面でも不利になる場合が多々あるからなんですね。
要するに、発生したエラー処理を全て完全に網羅することで、一切の例外処理を不要な状態にしていたわけです。
一般的な感覚だと例外処理を使わないって、ナニをバカな事を語ってるの?猿なの?暇人なの?と思われるでしょうが、一覧表示の性能を実現するためのネタの一つです。
実装の手間がスゲェかかる反面、性能が限界まで引き出せるというわけですが、どう考えても茨の道なので真似することはお薦めしません。
というわけで、30万ファイルの一覧表示が、801ms→838ms・・・約5%ほど悪化ですかねぇ。
体感できるような数字じゃないので気のせいかもしれませんが、全体的にモッサリするようになっちゃった気もします。
まぁ、性能ダウンしたとはいえ、エクスプローラーだと12〜14秒位かかってる処理であり、桁が2個違ってる時点で気にする方がおかしいのかもしれないですが・・・こういうネタの積み重ねで今の速度を実現していただけに、やはり気持ち悪いです。
アプリケーションが落ちるよりマシって事で妥協です。
さて、ここまで読んで鋭い人は気づくと思います。
Ver.7系のAs/Rが落ちるような操作を、Ver.8系やエクスプローラーなどで繰り返した場合はメモリリークが積み重なることになるんで、Windowsの安定稼働のためには定期的な再起動が必要なんですね・・・という、とんでもなく切ないオチがあります。
As/Rの再起動はともかく、エクスプローラーの再起動ってハードル高すぎる気がしますが・・・Windowsの内部の見えない位置にある不具合が解消されることを祈りましょう。
で、本題の未来の話です。
多分、Ver.8.2頃の機能だと思います。
As/Rにはとんでもない数のコマンドがありますし、連携が可能ですが、シェル系のコマンドを直接扱えるのは意外と少ないです。
具体的に存在しているものとしては「プロパティを開く」と「開く」が該当しますが、他にもシェル拡張されたコマンド類をキーボードに割り当てられないか?というのが話の出処です。
例えば、右クリックメニューを開いて選択アイテムに応じて色んなコマンドが表示されると思いますが、これらのコマンドですね。
いくつか他所様のソフトも写り込んでまして、現在のリストで選択しているファイルに対して「SVN 更新」とか「SVN コミット」とかTotoiseSVNというバージョン管理ツールのシェル拡張機能です。
まぁ、個人でこういったツールを使ってる人はあまり居ないでしょうが、開発現場とかだとわりと頻繁に使われてるツールの一つです。
具体的にはスクリプトコマンドの追加なんですが
ContextCommand=プロパティ
こんな感じのコマンドで、現在のリストで選択しているアイテムに対してプロパティコマンドを実行します。
今のところ前方一致で判定するようにしています。
ContextCommand=SVN 更新
とかにしておくと、選択したアイテムをTotoiseSVNで更新してくれるわけです。
下位階層にあるコマンドは対象外なのであまり凝ったことはできませんが、特定用途では便利な機能になるかもしれません。
(シェルの右クリックメニューは下位階層を表示しないとアイテムが取得できないというカラクリなんで対応不能)
ノートンがインストールされている環境だと、右クリックメニューに「検体提出」なんてコマンドがあるんでしたっけ・・・きっと誤検出報告が捗ると思います。(苦笑)