2009-10-02 42 views
57

在.NET中,「平臺目標:任何CPU」編譯選項允許.NET組件64  位X64的機器上運行,和32位 上一臺x86機器。使用'Platform Target:x86'編譯器選項,還可以強制程序集在x64機器上以x86形式運行。力86 CLR上的「任何CPU」 .NET組件

是否有可能運行與「任何CPU」標誌的組件,但是確定它是否應該在x86或x64 CLR上運行?通常,這個決定是由CLR/OS Loader(根據我的理解)根據底層系統的位數作出的。

我想寫一個C#.NET應用程序,可以用(讀:代碼注入)相互作用的其它正在運行的進程。 x64進程只能注入到其他x64進程中,並且與x86一樣。理想情況下,我想利用JIT編譯的和任何CPU選項,以允許單個應用程序被用來注入任一的x64或x86過程(在x64機器上)。

的想法是,應用程序將被編譯爲任何CPU。在x64機器上,它將以x64運行。如果目標進程是x86,則它應該自行重新啓動,強制CLR將其作爲x86運行。這可能嗎?

回答

9

以來,它一直我想這一段時間,但我相信,調用組件的過程中位數確定它是否會被JIT編譯爲x86或x64。

所以,如果你寫一個小控制檯應用程序並構建它爲X86,並作爲另64位,運行一個或其他會導致加載到進程爲32或64位運行其他組件。當然,這是假定您在64位機器上運行。

+3

我知道你可以強制它通過包裝它在x86啓動程序集,但我想知道如果你可以動態強制它'任何CPU'編譯程序集。無論如何,如果我找不到其他東西,可能會回到這個位置。會upvote,但沒有足夠的代表。 – jeffora 2009-10-02 01:49:22

+1

進程是64位或32位。如果程序集是在32位進程中加載​​的,並且它構建爲任何CPU,則它將被作爲32位進行JIT處理,在64位進程中它將被打成64.你打算如何創建承載程序集的程序集? – jnoss 2009-10-02 02:38:35

6

我不知道我是否能幫助你與此有關。但這是我的經驗。

我有一個主機應用程序,A.exe(編譯爲x86),我有一個客戶端應用程序B.exe(編譯爲ANY CPU),從主機應用程序。我從A.exe啓動B.exe,使用System.Diagnostic.Process類。

現在的問題是,如果我把兩個64位的機器上,然後A.exe會運行的x86,B.exe將運行64位

但如果A.exe調用組件C(c.dll,其編譯爲Any CPU)和B.exe還呼籲c.dll,然後c.dll將遵循調用它的應用程序。換句話說,在64位機的時候A.exe調用它,它會像x86 DLL,而B.exe調用的時候,它會像x64

61

你可以找到應用程序將如何運行,靜態使用CorFlags應用更改。要了解應用程序將如何運行,使用:

corflags <PathToExe> 

要更改應用程序將如何運行,使用:

corflags /32bit+ <PathToExe> 

這將使作爲運行32位程序的EXE文件。有關組件應如何運行的信息存儲在PE標頭中。請參閱堆棧溢出問題How to find if a native DLL file is compiled as x64 or x86?

如果您想在運行時注入代碼,則必須在C++/COM中編寫.NET探查器。 見.NET Internals: The Profiling APIProfiling (Unmanaged API Reference)瞭解更多詳情。

您需要實現JitCompilationStarted回調並在那裏完成您的工作。如果你在這個方向上,你將不得不建立注入DLL文件爲x86和x64。本機的DLL文件將被CLR加載一次以下環境變量將被設置:

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

如果您有它設置正確,則64位版本會「看到」的64個程序和32位bit版本將'看到'32位進程。

+0

感謝您的信息:)我知道corflags應用程序,但想知道是否有任何方式在運行時以編程方式實現類似的結果。 – jeffora 2009-10-04 01:18:31

+1

一旦進程運行,無法更改其上下文! – 2009-10-04 04:08:04

+0

在運行時更改上下文並不意味着只需在PE頭上設置一點,32位進程在WOW仿真層下運行。我看不到進程如何在運行時保存其狀態,執行上下文切換並繼續運行。 看到這個鏈接: http://blogs.msdn.com/oldnewthing/archive/2008/12/22/9244582.aspx – 2009-10-04 04:38:43

6

我已經做了類似的創建兩個(真的三個)二進制文件。我曾經檢測過我嘗試注入的進程是32位還是64位。然後這個過程會啓動你的注入二進制文件的32位或64位版本(而不是象你提到的那樣重新啓動它)。

這聽起來很亂,但您可以在構建時使用生成輸出二進制文件的副本並使用CorFlags實用程序強制副本以32位運行的構建後事件輕鬆實現此目的。這樣您就不必在應用程序中部署CorFlags實用程序,無論如何,這可能不合法。

我認爲這與您最初的想法非常相似,除了兩行構建事件外,實際上並不需要更多工作。