2013-07-26 11 views
8

Mam aplikację C#, która została zbudowana do pracy zarówno na procesorach 32-bitowych, jak i 64-bitowych. Próbuję wyliczyć moduły wszystkich procesów w danym systemie i staje się to problematyczne przy próbie wyliczenia 32-bitowych modułów procesowych z aplikacji 64-bitowej; Windows lub .NET zabrania tego.Jak można programowo uruchomić dowolny plik .NET .NET CPU w konfiguracji 32-bitowej lub 64-bitowej?

Pomyślałem, że byłoby całkiem fajnie, gdybym mógł ponownie uruchomić aplikację z poziomu samej siebie, ale zmusić ją do uruchomienia jako 32-bitowego, a następnie poprawnie wyliczy moduły procesowe, które przegapił podczas ostatniego uruchomienia.

Jak uruchomić programowo programowo i wskazać, że mimo że został on zbudowany z konfiguracją ANY CPU, powinien działać jako proces 32-bitowy?

Poniższy kod zgłasza System.ComponentModel.Win32Exception z tekstem "Procesy 32-bitowe nie mogą uzyskać dostępu do modułów procesu 64-bitowego."

[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] 
[return: MarshalAs(UnmanagedType.Bool)] 
private static extern bool IsWow64Process(
    [In] IntPtr hProcess, 
    [Out] out bool lpSystemInfo); 

private static void Main() 
{ 
    Process[] processes = Process.GetProcesses(); 

    using (FileStream fileStream = new FileStream("ProcessModulesDump.dat", FileMode.Create, FileAccess.Write, FileShare.None)) 
    { 
     using (GZipStream gzipStream = new GZipStream(fileStream, CompressionLevel.Optimal)) 
     { 
      using (TextWriter writer = new StreamWriter(gzipStream)) 
      { 
       foreach (Process process in processes) 
       { 
        writer.WriteLine("{0} - {1}", process.Id, process.ProcessName); 

        //bool lpSystemInfo; 
        //if ((Environment.Is64BitProcess && 
         IsWow64Process(process.Handle, out lpSystemInfo)) || 
         (!Environment.Is64BitProcess && 
          !IsWow64Process(process.Handle, out lpSystemInfo))) 
        //{ 
         foreach (ProcessModule module in process.Modules) 
         { 
          writer.WriteLine("\t{0} - {1} ({2})", 
           module.BaseAddress, 
           module.ModuleName, 
           module.FileName); 
         } 
        //} 
       } 
      } 
     } 
    } 
} 
+0

Pokaż nam kod, którego używasz do wyliczenia procesów, i podaj nam dokładną treść komunikatu o błędzie, który otrzymujesz. –

+0

Czy możesz obejść problem, uruchamiając 32-bitowy plik wykonywalny pomocnika, który ładuje i uruchamia twój prawdziwy plik wykonywalny, tak jakby był biblioteką? – hvd

+0

@hvd Rzeczywiście mogłem. Chciałem uniknąć dwóch plików wykonywalnych i pomyślałem, że byłoby zgrabnie, gdybyś mógł ustawić jakąś opcję w procesie, kiedy zaczynałby wskazywać, że powinien być zmuszony do uruchomienia jako 32-bitowy. –

Odpowiedz

3

przez wygląda to Twój problem jest z wydaniem połączenia IsWow64Process gdy nie jest dostępna/niewłaściwe .... spróbuj robi swoje wykrywanie z tym kodem:

Kiedy Przekroczysz to, możesz wtedy zbadać sposoby, aby móc wymieniać moduły 32-bitowych i 64-bitowych procesów w sposób niezależny od platformy:

Zastosowanie WMI (Windows Management Instrumentation) kwerendy wymagane informacje ... zobacz 3rd pocztowy dół który wspomina UseWMIToGetProcesses().

Zastosowanie EnumProcessModulesEx (obsługiwane w systemie Windows Vista r ...kiedy wykryje jesteś w trybie 64-bitowym), gdyż może to wyliczyć listę procesów 32bit i 64bit (patrz samym końcu tego linku):

Zastosowanie CreateToolhelp32Snapshot wyliczyć procesy (trzeba być ostrożnym w definiowaniu konstrukcjom):

+0

Moja odpowiedź (ponieważ usunięta) była w zasadzie twoją pierwszą kwestią, WMI jest przydatna tylko dla procesów, ale nie dla ich modułów. –

3

Zgodnie z artykułem Rick byer'S, AnyCPU Exes are usually more trouble than they're worth, decyzja na „bitness” używany do uruchamiania aplikacji AnyCPU jest określana przez program ładujący OS i nie masz nic do powiedzenia w tej sprawie.

Konkretnie:

AnyCPU EXE są trochę bardziej skomplikowane, ponieważ ładowarka OS musi zdecydować, jak initialze proces. W 64-bitowych systemach operacyjnych są one uruchamiane jako 64-bitowe procesy (chyba że główny przełącznik systemu operacyjnego ldr64 mówi inaczej), , a w 32-bitowych systemach operacyjnych są uruchamiane jako procesy 32-bitowe.

Wygląda na to, że najlepszym rozwiązaniem jest utworzenie i uruchomienie drugiego, 32-bitowego pliku exe i uruchomienie go.

+0

Jednym ze sposobów jest przeniesienie kodu do oddzielnego zestawu biblioteki klas (zachowaj AnyCPU) - następnie utwórz dwie aplikacje (jedna x86, jedna x64) i każ im obie wywołać bibliotekę klas, aby wykonać praca. Plik .exe powoduje, że proces jest uruchamiany w wymaganej "bitness", a biblioteka klas jest kompilowana JIT, ponieważ jest uruchamiana w celu dopasowania do smaku, który potrzebuje .exe. –

Powiązane problemy