如何将 C# 应用程序中的嵌入式 PowerShell 会话配置为 64 位

How to configure embedded PowerShell session in a C# application to be 64bit

在常规 PowerShell window 中,可以确定当前 shell 是 x64 还是 x86 by examining the boolean environment variable [Environment]::Is64BitProcess

现在我做了同样的事情,但是是从 .NET 应用程序中的嵌入式 PS 会话进行的。并且输出显示位数不是 64 位。

static void Main(string[] args)
{
    using (PowerShell ps = PowerShell.Create())
    {
        foreach (var res in ps
            .AddScript("$host.version.tostring()").AddStatement()
            .AddScript("[Environment]::Is64BitProcess").AddStatement()
            .Invoke())
        {
            Console.WriteLine(res.BaseObject);
        }

        // Outputs:
        // 4.0
        // False
    }
}

使用 corflagsildasm,我确保引用的 System.Management.Automation DLL 是 v4.0 和 ILONLY。即使我从 x64 shell(例如 PowerShell.exe x64)调用我的应用程序,结果仍然指示 Is64BitProcess == false。有什么提示吗?

这很重要,因为我想从嵌入式会话中 Add-PsSnapin。如果位数不正确,则无法加载 SnapIn。

这是一个猜测,但您可能在项目引用中使用了 32 位版本的 PowerShell 程序集。

确保引用 64 位版本的 System.Management.Automation.dll 程序集。

在 64 位 Windows 安装中,您可以在此处找到程序集:
32 位版本

C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\[PS version installed]\System.Management.Automation.dll

64 位版本

C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll

好的,刚刚弄明白了。在项目属性中,如果我 "force" 构建目标从 Any CPUX64,它解决了问题。嵌入式 PS 会话正确显示位数为 64 位,并且正确列出了所有已注册的管理单元。

我仍然不知道为什么 Any CPU 不起作用。可能是因为 Prefer 32-bit 复选框默认选中了 Any CPU 选项。

嵌入式 PowerShell 会话的位数遵循调用它的 .NET 进程的位数。

似乎没有办法(使用 System.Management.Automation)从 64 位父进程 运行 32 位嵌入式 PowerShell 进程,反之亦然(尽管我很好奇是否存在是一个)。

如果您不介意将父进程强制为 64 位,并且想知道为什么它 运行宁作为 32 位进程,可能的原因如下:

  • 平台设置为"x86"
  • 平台设置为"Any CPU",勾选"Prefer 32-bit"
  • 平台设置为 "Any CPU",当 运行ning 来自 Visual Studio 时,父进程是 IIS Express 中 运行ning 的 Web 应用程序。您可以在 Visual Studio 设置中更改此设置(工具 > 选项 > 项目和解决方案 > Web 项目 > 使用 64 位版本的 IIS Express...)。请注意,在生产环境中(常规 IIS、Azure 网站等),父进程可能 运行 默认为 64 位。