2009-10-02 6 views
57

W .NET opcja kompilatora "Cel platformy: dowolny procesor" pozwala na uruchomienie zestawu .NET w postaci 64  bit na maszynie x64 i 32   bit na maszyna x86. Można również zmusić zespół do uruchomienia jako x86 na maszynie x64 za pomocą opcji kompilatora "Platform Target: x86".Wymuś CLR x86 na zespole "Any CPU" .NET

Czy można uruchomić zespół z flagą "Any CPU", ale określić, czy powinien on działać w CLR x86 lub x64? Zwykle ta decyzja jest podejmowana przez program ładujący CLR/OS (jak to rozumiem) w oparciu o zgodność systemu bazowego.

Próbuję napisać aplikację C# .NET, która może wchodzić w interakcje z (czytaj: kod wtrysku) do innych działających procesów. Procesy x64 mogą wstrzykiwać tylko do innych procesów x64, a to samo z x86. Najlepiej byłoby skorzystać z kompilacji JIT i opcji Any CPU, aby umożliwić użycie pojedynczej aplikacji do wstrzykiwania do procesów x64 lub x86 (na maszynie x64).

Chodzi o to, że aplikacja zostanie skompilowana jako Dowolny procesor. Na komputerze z procesorem x64 byłby uruchamiany jako x64. Jeśli proces docelowy to x86, powinien się uruchomić ponownie, zmuszając CLR do uruchomienia go jako x86. czy to możliwe?

Odpowiedz

9

Minęło trochę czasu, odkąd próbowałem tego, ale wierzę, że bitness procesu, który wywołuje zestaw decyduje o tym, czy będzie JITed jako x86 lub x64.

Więc jeśli napiszesz małą aplikację konsolową i zbudujesz ją jako x86, a drugą jako x64, uruchomienie jednego lub drugiego spowoduje, że inne zespoły załadowane do procesu będą działać jako 32 lub 64-bitowe. Zakłada to oczywiście, że używasz maszyny 64-bitowej.

+3

Tak, jestem świadom tego, że możesz go zmusić, owijając go w zespół uruchamiający x86, ale zastanawiałem się, czy możesz dynamicznie wymusić go na zestawach skompilowanych dla "dowolnego procesora". Mimo to dzięki, prawdopodobnie powrócę do tego, jeśli nie znajdę niczego innego. Obdarowałby, ale za mało rep. – jeffora

+1

Procesy są albo 64-bitowe, albo 32-bitowe. Jeśli zestaw jest ładowany w procesie 32-bitowym i jest zbudowany jako Dowolny procesor, będzie JITed jako 32-bitowy, w procesie 64-bitowym będzie to JITed jako 64. W jaki sposób planujesz utworzyć zespół, który hostuje twoje złożenia? – jnoss

6

Nie jestem pewien, czy mogę ci w tym pomóc. Ale to jest moje doświadczenie.

Mam aplikację hosta, A.exe (skompilowana jako x86) i mam aplikację klienta, B.exe (skompilowaną jako ANY CPU) z aplikacji hosta. I uruchamiam B.exe z A.exe, używając klasy System.Diagnostic.Process.

Problem jest teraz, gdy kładę dwa na maszynie x64, a następnie A.exe będzie działał jak x86, natomiast B.exe będzie działał jak x64.

Ale jeśli A.exe rozmowy montaż C (c.dll, który jest kompilowany jako Any CPU) oraz B.exe wzywa również c.dll, wtedy C.dll śledzić aplikację, która wywołuje go. Innymi słowy, w maszynie 64-bitowej, gdy wywoła ją A.exe, zachowa się ona jak x86 dll, natomiast gdy wywoła ją B.exe, będzie zachowywać się jak x64.

61

Możesz dowiedzieć się, jak aplikacja będzie działać i zmieniać ją statycznie, używając aplikacji CorFlags. Aby dowiedzieć się, w jaki sposób aplikacja będzie działać, przeznaczenie:

corflags <PathToExe> 

Aby zmienić sposób aplikacja będzie działać, zastosowanie:

corflags /32bit+ <PathToExe> 

To spowoduje, że plik EXE uruchamiane jako proces 32-bitowym. Informacje o tym, jak powinien działać zestaw, są przechowywane w nagłówku PE.Zobacz pytanie przepełnienie stosu: How to find if a native DLL file is compiled as x64 or x86?.

Jeśli chcesz wprowadzić kod w czasie wykonywania, musisz napisać profiler .NET w C++/COM. Aby uzyskać więcej informacji, zobacz .NET Internals: The Profiling API i Profiling (Unmanaged API Reference).

Musisz zaimplementować wywołanie zwrotne JitCompilationStarted i tam wykonać pracę. Jeśli jesteś w tym kierunku, będziesz musiał zbudować wstrzyknięty plik DLL zarówno jako x86, jak i x64. Natywne pliki DLL zostanie załadowany przez CLR raz zostaną ustawione następujące zmienne środowiskowe:

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

Jeśli masz to ustawione prawidłowo wtedy 64-bitowa wersja będzie „widzieć” procesy 64-bitowe i 32- wersja bitowa "zobaczy" procesy 32-bitowe.

+0

Dzięki za informację :) Byłem świadomy aplikacji corflags, ale zastanawiałem się, czy był jakiś sposób, aby osiągnąć podobny wynik programowo w czasie wykonywania. – jeffora

+1

Po uruchomieniu procesu nie ma możliwości zmiany jego kontekstu! –

+0

Zmiana kontekstu w czasie wykonywania nie oznacza po prostu ustawienia bitu w nagłówku PE, proces 32-bitowy działa pod warstwą emulacji WOW. Nie widzę, w jaki sposób proces może zapisać swój stan w środowisku wykonawczym, zmienić kontekst i kontynuować działanie. Zobacz ten link: http://blogs.msdn.com/oldnewthing/archive/2008/12/22/9244582.aspx –

6

Zrobiłem coś podobnego, tworząc dwa (naprawdę trzy) pliki binarne. Miałem jeden wykryć, czy proces, który próbowałem wprowadzić, był 32 lub 64-bit. Ten proces następnie uruchomi 32-bitową lub 64-bitową wersję twojego binarnego wtrysku (w przeciwieństwie do ponownego uruchomienia, jak wspomniałeś).

To brzmi niechlujnie, ale można to łatwo osiągnąć w czasie kompilacji z post-buildowym zdarzeniem, które tworzy kopię pliku wyjściowego binarnego i używa narzędzia CorFlags, aby wymusić uruchomienie kopii jako 32-bitowej. W ten sposób nie musisz instalować narzędzia CorFlags w swojej aplikacji, co prawdopodobnie i tak nie jest legalne.

Myślę, że jest to bardzo podobne do twojego pierwotnego pomysłu i naprawdę nie wymaga więcej pracy z wyjątkiem dwuliniowego wydarzenia budowania.

Powiązane problemy