8

32 ビット プロセッサと 64 ビット プロセッサの両方で実行するように構築された C# アプリケーションがあります。特定のシステムですべてのプロセスのモジュールを列挙しようとしていますが、64 ビット アプリケーションから 32 ビット プロセス モジュールを列挙しようとすると問題が発生します。Windows または .NET では禁止されています。

アプリケーションを内部から再起動できればかなりクールだと思いましたが、強制的に 32 ビットで実行すると、前回の実行で見逃したプロセス モジュールが正しく列挙されます。

実行可能ファイルをプログラムで実行し、構成を使用してビルドされているにもかかわらずANY CPU、32 ビット プロセスとして実行する必要があることを示すにはどうすればよいですか?

System.ComponentModel.Win32Exception以下のコードは、「32 ビット プロセスは 64 ビット プロセスのモジュールにアクセスできません」というテキストをスローします。

[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);
                      }
                  //}
              }
          }
      }
  }
}
4

2 に答える 2

3

一見すると、問題は、IsWow64Process呼び出しが利用できない/適切でないときに呼び出しを発行することです....次のコードで検出を試してください。

それを乗り越えたら、プラットフォームに依存しない方法で 32 ビットおよび 64 ビット プロセスのモジュールをリストできるようにする方法を探ることができます。

UseWMIToGetProcessesWMI (Windows Management Instrumentation) を使用して、必要な情報を照会します... ()について言及している 3 番目の投稿を参照してください。

EnumProcessModulesEx32ビットおよび64ビットのプロセスリストを列挙できるため、(Vista以降でサポートされています... 64ビットモードであることを検出した場合)使用します(このリンクの最後を参照):

プロセスを列挙するために使用CreateToolhelp32Snapshotします (構造体の定義には注意が必要です)。

于 2013-07-27T02:22:23.233 に答える