2009-10-02 10 views
57

.NETで 'プラットフォームターゲット:任意のCPU'コンパイラオプションを使用すると、.NETアセンブリがx64マシンで64  ビットとして実行され、32  ビットがオンx86マシン。 'Platform Target:x86'コンパイラオプションを使用して、x64マシン上でx86としてアセンブリを実行するよう強制することもできます。'任意のCPU' .NETアセンブリでのx86 CLRの強制

「任意のCPU」フラグを使用してアセンブリを実行できますが、それをx86またはx64 CLRで実行する必要があるかどうかを判断できますか?通常、この決定は、基礎となるシステムのビット数に基づいてCLR/OSローダーによって行われます(これは私の理解です)。

他の実行中のプロセスとやり取り(読み込み:コードを挿入)できるC#.NETアプリケーションを作成しようとしています。 x64プロセスは、他のx64プロセスにのみインジェクトすることができます。理想的には、JITコンパイルと任意のCPUオプションを利用して、単一のアプリケーションをx64またはx86プロセス(x64マシン上)に注入できるようにしたいと考えています。

考えられるのは、アプリケーションがのいずれかのCPUとしてコンパイルされるということです。 x64マシンでは、x64として実行されます。ターゲットプロセスがx86の場合は、それ自体を再起動して、CLRで強制的にx86として実行する必要があります。これは可能ですか?

答えて

9

私はこれを試して以来、しばらくしていますが、アセンブリを呼び出すプロセスのビット数によって、JITされるかどうかがx86またはx64で決まると思います。

したがって、小さなコンソールアプリケーションを作成してx86としてビルドし、もう1つをx64としてビルドすると、プロセスにロードされる他のアセンブリが32または64ビットとして実行されます。これはもちろん、あなたが64ビットマシンで動作していることを前提としています。

+3

私はあなたがx86ランチャーアセンブリでそれをラップすることによって強制することができると知っていますが、あなたは動的に 'Any CPU'コンパイルされたアセンブリに対して強制することができますか?とにかくありがとう、私は他の何かを見つけることができない場合おそらくこれに戻ります。 upvoteしかし、十分な担当者はありません。 – jeffora

+1

プロセスは64ビットまたは32ビットです。アセンブリが32ビットプロセスでロードされ、任意のCPUとして構築されている場合、64ビットプロセスでは64ビットとしてJITされます。アセンブリをホストするアセンブリをどのように作成する予定ですか? – jnoss

6

私はあなたにこれを手伝ってくれるかどうかはわかりません。しかし、これは私の経験です。

私はホストアプリケーションA.exe(x86としてコンパイルされています)があり、ホストアプリケーションからクライアントアプリケーションB.exeANY CPUとしてコンパイルされています)を持っています。そしてSystem.Diagnostic.Processクラスを使用してをA.exeから開始します。

問題は、今私はx64のマシン上の2を置く場合、A.exeは、x86のように実行されますB.exeに対しはx64のとして実行されますです。

しかしA.exeコール(Any CPUとしてコンパイルされc.dll)組立C、及びB.exec.dllを呼び出す場合、次いでC.DLLがそれを呼び出すアプリケーションに続く

。つまり、 A.exeを呼び出すと64ビットマシンでは x86 dllのように動作し、 B.exeと呼び出すと x64のように動作します。

61

CorFlagsアプリケーションを使用すると、アプリケーションの実行方法と静的な変更方法を確認できます。アプリケーションを実行する方法を見つけるには、使用:

corflags <PathToExe> 

アプリケーションを実行する方法を変更するには、使用:

corflags /32bit+ <PathToExe> 

これは、32ビットプロセスとして、EXEファイルの実行を行います。アセンブリの実行方法に関する情報は、PEヘッダーに格納されます。Stack Overflowの質問How to find if a native DLL file is compiled as x64 or x86?を参照してください。

実行時にコードを注入する場合は、.NETプロファイラをC++/COMに記述する必要があります。 詳細については、.NET Internals: The Profiling APIおよびProfiling (Unmanaged API Reference)を参照してください。

JitCompilationStartedコールバックを実装し、そこで作業する必要があります。あなたがこの方向にいるなら、x86とx64として注入DLLファイルをビルドする必要があります。

Cor_Enable_Profiling=0x1 
COR_PROFILER={CLSID-of-your-native-DLL-file} 

あなたはそれが正しく設定されている場合は、64ビット版は、64ビットプロセスと「見る」だろう32:以下の環境変数が設定されたら、ネイティブのDLLファイルがCLRによってロードされます32ビットプロセスは「見る」でしょう。

+0

情報をありがとう:)私はcorflagsアプリケーションを認識していましたが、実行時にプログラムで同様の結果を達成する方法があるかどうか疑問に思っていました。 – jeffora

+1

プロセスが実行されると、そのコンテキストを変更することはできません! –

+0

実行時にコンテキストを変更しても、PEヘッダーにビットを設定するだけではなく、32ビットプロセスがWOWエミュレーションレイヤーで実行されていることを意味します。どのようにプロセスが実行時に状態を保存し、コンテキストを切り替えて実行を継続できるかはわかりません。 このリンクを参照してください: http://blogs.msdn.com/oldnewthing/archive/2008/12/22/9244582.aspx –

6

2つの(実際には3つの)バイナリを作成することで同様のことをしました。私が注入しようとしていたプロセスが32ビットか64ビットかを検出しました。このプロセスでは、32ビット版または64ビット版の注入バイナリを起動します(前述のように再起動するのではなく)。

これは面倒ですが、出力バイナリのコピーを作成し、CorFlagsユーティリティを使用してコピーを32ビットとして強制的に実行するポストビルドイベントで、ビルド時にこれを簡単に達成できます。この方法では、アプリケーションにCorFlagsユーティリティをデプロイする必要はありません。何らかの理由でおそらく合法ではないでしょう。

私はこれがあなたの最初のアイデアと非常に似ていると思うし、実際には2行のビルドイベント以外の多くの作業は必要ありません。

関連する問題