2011年9月15日木曜日

64bit環境で動かない.NETアプリ

一部の特殊なアプリを除けば、64bit環境でも従来のアプリはWow64上で普通に動作するものが多いが、たまに.NETアプリは動かないものがある。フックやシェル拡張など他のプロセスに寄生するアプリやドライバならともかく.NETでそんなの書かないのに何故? と不思議に思うだろう。

どういう訳かというと.NETアプリの実行ファイルはコンパイルした段階では純粋なマシン語ではない中間言語で、実行時にCPUのビット数に合ったマシン語に変換される仕組みになっており、同じ実行ファイルでも64bit OS上では64bit, 32bit OS上では32bitで動作する。

ここに一つの罠があって、.NETアプリにはたまにネイティブのDLLを利用しているものがあり、このDLLは始めからマシン語でありコンパイル時に指定したビット数のCPUでしか動作しない。そのため、64bit環境で動作させると.NETアプリのプロセスは64bitで起動して、32bitのDLLを読み込もうとしてエラーとなってしまう。

32bitのネイティブアプリのように始めからWow64上で32bitアプリとして起動させることができれば32bitのDLLでも読み込める。実は.NETアプリのコンパイル時にTarget CPUにx86を選んでいれば、64bit環境でも32bit CPUのマシン語に変換されるため、Wow64が発動してちゃんと動いてくれる。上に書いた罠が発動するのはコンパイル時にTarget CPUにAny CPUを選んでいる場合なのだ。

最近はこのノウハウも広まってきたので、アプリ作者の人もちゃんとコンパイルオプションを選んでくれるし、今動かなくても将来のバージョンアップで動くようになるだろうけど、もう作者の人が更新を止めちゃっている場合はどうしたら良いのか。

実はコンパイルオプションを変えても実行ファイルの大部分である中間言語の部分は全く同じで、ヘッダにあるフラグがちょっと違うだけなので、バイナリエディタで書き換えてやれば良い、というのは大変なのでちゃんとツールがある。

CorFlags.exe "対象の.exe" /32BIT+

問題はこのコマンドは単体では配っていなくて、.NET FrameworkのSDKを入手してインストールしないと使えるようにならないこと。自分はVisual Studio C#のExpress Editionを使っているので始めから入っていたけど、そうじゃない人はちょっと面倒かもしれない。

0 件のコメント:

コメントを投稿