AxShockwaveFlashを使ってFlashを貼ってる.NETアプリを64bitのWindowsで動かす

ちょっとハマった話。

AxShockwaveFlash x .NET x Windows 7(64bit)

.NETのアプリで、フォームにAxShockwaveFlashを使ってFlashを貼っている。自分で作ったもの。これをあるPCで動かしたら、

System.Runtime.InteropServices.COMException : クラスが登録されていません

の実行時例外になった。このアプリは他のPCでは普通に動いているので、非常にショックだった。

.NETで作った他のアプリ(Flashを貼っていないやつ)は動くし、IEなどからFlashが使われてるサイトを見れば普通に再生される。

というわけで、最初はなんで例外になるのかわからなくてかなり悩んだけど、いろいろ情報を整理したらわかった。64bit版のWindowsだからダメだったっぽい。

  1. Flash Playerは32bit版しかない。
  2. だから64bitのWindows上では、WOW64を経由して動く。
  3. .NETのアプリは、通常は32bit版も64bit版もなく、どっちのWindows上でも普通に動く。
  4. だから64bitのWindows上では.NETのアプリは64bitで動く。
  5. でも64bitで動作している.NETアプリから32bitのCOM(この場合はFlash Player)を貼り付けることはできない(64bitのFlash Playerを探してしまい、でも見つからなくて、COMExceptionになる)。
  6. もうダメぽ。

こんな感じ。

x86でビルドすれば解決

これを解決するには、.NETアプリをビルドするときに、ターゲットCPUを「x86」にする。そうすると32bit専用の.NETアプリとしてコンパイルされるわけだ。デフォルトは「AnyCPU」で、これは32bitも64bitもどっちでも動くコンパイル方法。

64bitのWindowsにはちゃんと32bit版の.NET Frameworkも搭載されていて、32bit専用の.NETアプリは32bitの.NET Frameworkを使って動く。そうすると、32bitのCOMも扱えるので、AxShockwaveFlashでFlashを貼り付けることもできるようになる。

とりあえずこれで解決。でも悩みが発生。

ホントにビルドしなおすしかないの?

最初の疑問は、ホントにビルドをやり直す必要があるのか、っていう点。だって元のアプリだって「x64」じゃなく「AnyCPU」でビルドされてるんだから、そのままでも32bitでも動くと思うわけよ。64bitのWindowsで、AnyCPUでビルドされた.NETアプリを強制的に32bitとして動かす方法は無いの?

ビルドをやり直すなんてソースコード持ってないと不可能な芸当であるわけで、今回はたまたま良かったけど今後はソースコードがない局面だってあり得る。そのときに困っちゃう(ていうかそのときはもう詰み)。

パフォーマンスが落ちる

x86でビルドした.NETアプリを32bit版の.NET Frameworkで動かすこともWOW64と呼んでいいのかどうか知らないけど(WOW64上で動く32bit版.NET Framework上でアプリが動いてるってこと?)、やはりこういうのは動作速度に影響するっぽい。

通常、WOW64を経由してもほぼパフォーマンス低下は感じられないとのこと。実際に今回のアプリでも、普通の機能では特に問題は無かった。ただ、Flashが動画をRED5に送信しているところがあって、 そこはかなり処理性能が落ちたのがわかった。性能が低下したせいで、動画の品質が落ちた(画質優先にするとコマ落ちして、帯域優先にすると画質が落ちた)。別なもっとスペックの低い32bit環境で同じアプリを動かすと、動画の品質は全然良かったので、つまりスペック的に上でもWOW64経由なので動画の品質が落ちてるという説明がつく。

しかもその品質の落ち方が、どう見ても使い物にならないレベルにまで落ちていて、ごまかすのにかなり苦労させられた。

Flash Player 64bit版はいつでるの?

これが出てくれれば解決なんだけどなあ。iPhone版のFlashなんかあとでいいから、こっちを頼むよー。