C# 如何以32位或64位配置以编程方式运行任何CPU.NET可执行文件?

C# 如何以32位或64位配置以编程方式运行任何CPU.NET可执行文件?,c#,.net,C#,.net,我有一个C#应用程序,可以在32位和64位处理器上运行。我试图枚举给定系统上所有进程的模块,当试图枚举64位应用程序中的32位进程模块时,这会产生问题;Windows或.NET禁止它 我认为如果我可以从应用程序内部重新启动它,但强制它以32位运行,然后它将正确地枚举上次运行时错过的流程模块,那将是非常酷的 如何以编程方式运行可执行文件,并指出即使它是使用任何CPU配置构建的,它也应该作为32位进程运行 下面的代码抛出一个带有文本“32位进程无法访问64位进程的模块”的System.Compone

我有一个C#应用程序,可以在32位和64位处理器上运行。我试图枚举给定系统上所有进程的模块,当试图枚举64位应用程序中的32位进程模块时,这会产生问题;Windows或.NET禁止它

我认为如果我可以从应用程序内部重新启动它,但强制它以32位运行,然后它将正确地枚举上次运行时错过的流程模块,那将是非常酷的

如何以编程方式运行可执行文件,并指出即使它是使用
任何CPU
配置构建的,它也应该作为32位进程运行

下面的代码抛出一个带有文本“32位进程无法访问64位进程的模块”的
System.ComponentModel.Win32Exception


根据Rick Byer的文章,关于用于启动任何CPU应用程序的“比特数”的决定是由OS加载器决定的,您在这件事上没有任何发言权

具体而言:

由于操作系统加载程序需要 决定如何初始化流程。在64位操作系统上,它们作为 64位进程(除非“ldr64”主操作系统交换机另有说明), 在32位操作系统上,它们作为32位进程运行


因此,您的最佳选择似乎是创建并启动第二个32位exe并启动它。

从外观上看,您的问题在于在调用不可用/不合适时发出
iswow64进程
调用……尝试使用此代码进行检测:

当您了解了这一点后,您就可以探索以平台无关的方式列出32位和64位进程的模块的方法:

使用WMI(Windows Management Instrumentation)查询所需信息…请参阅第三篇文章,其中提到
usewmitogetprocesss
()

使用
EnumProcessModulesEx
(在Vista以后的版本中受支持…当您检测到自己处于64位模式时),因为它可以枚举32位和64位进程列表(请参阅此链接的最后部分):

使用
CreateToolhelp32Snapshot
枚举进程(定义结构时必须小心):


向我们展示您用于枚举进程的代码,并告诉我们您收到的错误消息的确切措辞。您能否通过启动一个32位帮助程序可执行文件来解决此问题,该文件可以像库一样加载和运行您真正的可执行文件?@hvd确实可以。我希望避免有两个可执行文件,并认为如果在启动进程时可以在进程上设置某种选项,以指示它应强制以32位运行,这将是一件好事。@RobertHarvey我添加了捕获进程并转储模块的代码。我还注释掉了允许进程以32位和64位的形式运行并且仍然正常工作的代码,以显示在这种情况下代码中断。我还添加了异常类型和消息。有一种更好的方法可以检测您是否以64位运行…这是安全的,无论您是在32位还是64位版本的Windows上运行…这里。。我的答案(因为已删除)基本上是您的第一点,WMI只对进程有用,而对它们的模块不有用。一种方法是将代码移动到一个单独的类库程序集中(保留为AnyCPU),然后创建两个应用程序(一个x86,一个x64),并让它们都调用类库来完成这项工作。.exe会使您的进程以所需的“位”运行,类库在运行时会进行JIT编译,以适应.exe所需的风格。
[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);
                      }
                  //}
              }
          }
      }
  }
}