IEのmime typeの判定

IEに限らずブラウザを使っていると、ダウンロードしたいものなのに、ブラウザで開いてしまうことが起こる。ここではmp3を開いたときに、quicktimeのアドオンが起動する場合にこれをダウンロードするように直す方法を調べてみる。

一般的にはファイルの種類を知りたいとき、拡張子というのがあるが、Mine Typeはこの拡張子をもっと一般的にしたものだと思う。サーバーはブラウザからの要求に対して、Content-typeヘッダを返す。たとえばhtmlデータを返す場合は以下のようなヘッダを返す。

Content-type: text/html

サーバがどのようなContent-typeを返すかは、通常拡張子によって決まると思われる。apacheなどの場合はmod-mimeのAddTypeなどを使っていろいろカスタマイズできるのだろう。またPerlなどのCGIの場合には自分でContent-typeを指定することもできる。

IEがこのContent-typeを受け取ったときどう処理されるかはここなどに書いてあり、ここにも要約があるが、複雑みたいなので、ここでは勝手に解釈して作業を続行する。

問題のmp3の時、サーバはContent-typeとして、audio/mpegを返していた。これを調べるにはレスポンスヘッダを見れるダウンロードマネージャを使ったり、プロキシで見てみたりいろいろやり方はあるが、ここではスルー。

このaudio/mpegの時、IEがどう動くかだが多分レジストリーの
HKEY_CLASSES_ROOT\MIME\Database\Content Type\audio/mpeg
を見ているのだろう。で、このキーの中のCLSIDで指定されているGUIDのコンポーネントを起動しているものと思われる。ここでは
{4063BE15-3B08-470D-A0D5-B37161CFFD69}
になっていた。これ以上はCOMの話になると思うので詳しくは書かないが、ここからレジストリキー

HKEY_CLASSES_ROOT\CLSID\{4063BE15-3B08-470D-A0D5-B37161CFFD69}
をみて動作しているものと思われる。

そこでレジストリーから
HKEY_CLASSES_ROOT\CLSID\{4063BE15-3B08-470D-A0D5-B37161CFFD69}
を削除してみたら、mp3がquicktimeによるアドオン再生から、ダウンロードに変わって希望の動作ができたので終了。

ちなみにfirefoxの場合は、オプションのプログラムで設定できるものと思われる。
firefox-contenttype

javascriptでURLを解析

ここにあるparseUriを使ってみる。ソースは以下。

http://user:pass@www.example.com/dir1/dir2/file.php?aaa=111&bbb=222&ccc=333#anchor を解析してクエリーのaaaを取得する。

bashのリダイレクション 覚え書

コマンドラインプログラムは何らかのメッセージを出力する際、標準出力標準エラー出力の2から選ぶことができる。普通のメッセージは標準出力で、エラーを出力する場合は標準エラー出力を使う。

練習用に以下のファイル “redtest”を作成する。chmod 755して実行可能にしておく。

このスクリプトは標準出力に”standard”を出力し、標準エラー出力に”error”を出力する。

普通に起動すると、両方画面上に出力される。

$ ./redtest
standard
error
$

以下のように実行すると、標準出力はファイル s に保存されて、標準エラー出力は画面に表示される。

$ ./redtest > s
error
$

以下のように実行すると、標準出力は画面に、標準エラー出力はファイル e に保存される。

$ ./redtest 2> e
standard
$

2は標準エラー出力を表し、1は標準出力を表す。最初の例は 1> と書いても動く。

以下のように書くと、両方の出力をファイル a に保存する。

$ ./redtest > a 2>&1
$

2>&1 は「2を1と同じところに出力する」と読む。ここで以下の例を考える。

$ ./redtest 2>&1 > t
error
$ cat t
standard
$

これだとtには標準出力しか保存されていない。これは最初の 2>&1 で「2を1と同じところに出力する」がここではまだ1は画面なので、「標準エラー出力を画面に出力する」と解釈される。つまりその時さしている最終地点に直接結びつくと言うことだと思う。

さらに1個上の例で作ったファイルを見てみると、”error”の出力の方が先に来ているかもしれない。これはバッファリングに関係しているのだと思うがよく分からなかった。

.NETのFormClosingとFormClosed

フォームが閉じられるときの動作の覚書。

ユーザが閉じたとき

ユーザがフォームの右上のXをクリックした場合、WM_CLOSEが送られ、FormClosingが呼ばれる。引数のFormClosingEventArgのCloseReasonにはUserClosingが設定される。Cancelプロパティをtrueに設定すると閉じるのをやめることができる。
Cancelをtrueにしなければ続いてFormClosedが呼ばれる。この時点ではフォームはまだ生きているが閉じるのをやめることはできない。FormClosedの後にDisposeが呼ばれる。

タスクマネージャから閉じられたとき(タスクマネージャのアプリケーションタグからのときで、プロセスタブのときは違うと思われる)はCloseResonにTaskManagerClosingが設定される。

タスクマネージャはWM_CLOSEを送るだけだと思うが、アプリから終了した場合はSC_CLOSEが先に来るのでそこで分けられると思われる。

システムがシャットダウンするとき

Win32の整理。システムがシャットダウンするときまずアプリにWM_QUERYENDSESSIONが送れられる。誰かが0を返すと送るのをやめる(途中で0が来たら残りのアプリには送らないと思われる)。次にWM_ENDSESSIONを送る。これを送るアプリはWM_QUERYENDSESSIONを送ったアプリと思われる。つまりWM_QUERYENDSESSIONを送ったときすべてのアプリが非ゼロを返せばすべてのアプリということになる。このときこの2つのメッセージは一気に送るのか、1つのアプリに対して毎に2つ送るのかはよくわからない。WM_ENDSESSIONのWParamはWM_QUERYENDSESSIONの戻り値が返るのでアプリはシャットダウンするのかしないのか判断できると思われる。これら2つのメッセージにはLparamもあるがここでは0(シャットダウンORリスタート)を考える。

WM_QUERYENDSESSIONが送られるとFormClosingが呼ばれる。CloseReasonはWindowsShutDown。Cancelをtrueにすると。メッセージの戻り値が0に設定される(つまりシャットダウンがキャンセルされる)。この時点では当然FormClosedは呼ばれない。

次にWM_ENDSESSIONが送られる。WParamが非ゼロの時(シャットダウン実行)はFormClosedが呼ばれる。

フローチャート

[OSがシャットダウン開始]
       ↓
[WM_QUERYENDSESSION送られてFormClosing呼ばれる]
       ↓
[Cancel=falseのまま?]→NO[WM_ENDSESSION送られる]→[なにもなし]
       ↓ YES
[WM_ENDSESSION送られる]
       ↓
[FormClosed呼ばれる]
       ↓
[シャットダウン]

なので注意すべき点はFormClosingでCancel=trueするときは、最初にCancelすべきかどうかを済ませて、内部の変更を行うコードはそれ以降に書く、ということかな。