如何使用 .NET 4 运行时运行 PowerShell?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2094694/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I run PowerShell with the .NET 4 runtime?
提问by Emperor XLII
I am updating a PowerShell script that manages some .NET assemblies. The script was written for assemblies built against .NET 2 (the same version of the framework that PowerShell runs with), but now needs to work with .NET 4 assemblies as well as .NET 2 assemblies.
我正在更新管理一些 .NET 程序集的 PowerShell 脚本。该脚本是为针对 .NET 2(与 PowerShell 运行的框架的相同版本)构建的程序集编写的,但现在需要使用 .NET 4 程序集以及 .NET 2 程序集。
Since .NET 4 supports running applications built against older versions of the framework, it seems like the simplest solution is to launch PowerShell with the .NET 4 runtime when I need to run it against .NET 4 assemblies.
由于 .NET 4 支持运行针对旧版本框架构建的应用程序,因此当我需要针对 .NET 4 程序集运行 PowerShell 时,似乎最简单的解决方案是使用 .NET 4 运行时启动 PowerShell。
How can I run PowerShell with the .NET 4 runtime?
如何使用 .NET 4 运行时运行 PowerShell?
采纳答案by Start-Automating
PowerShell (the engine) runs fine under .NET 4.0. PowerShell (the console host and the ISE) do not, simply because they were compiled against older versions of .NET. There's a registry setting that will change the .NET framework loaded systemwide, which will in turn allow PowerShell to use .NET 4.0 classes:
PowerShell(引擎)在 .NET 4.0 下运行良好。PowerShell(控制台主机和ISE)没有,仅仅是因为它们是针对旧版本的 .NET 编译的。有一个注册表设置将更改在系统范围内加载的 .NET 框架,从而允许 PowerShell 使用 .NET 4.0 类:
reg add hklm\software\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1
reg add hklm\software\wow6432node\microsoft\.netframework /v OnlyUseLatestCLR /t REG_DWORD /d 1
To update just the ISE to use .NET 4.0, you can change the configuration ($psHome\powershell_ise.exe.config) file to have a chunk like this:
要仅更新 ISE 以使用 .NET 4.0,您可以将配置 ($psHome\powershell_ise.exe.config) 文件更改为具有如下块:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0.30319" />
</startup>
</configuration>
You can build .NET 4.0 applications that call PowerShell using the PowerShell API (System.Management.Automation.PowerShell) just fine, but these steps will help get the in-the-box PowerShell hosts to work under .NET 4.0.
您可以使用 PowerShell API (System.Management.Automation.PowerShell) 构建调用 PowerShell 的 .NET 4.0 应用程序就好了,但这些步骤将有助于让内置 PowerShell 主机在 .NET 4.0 下工作。
Remove the registry keys when you don't need them any more. These are machine-wide keys and forcibly migrate ALL applications to .NET 4.0, even applications using .net 2 and .net 3.5
当您不再需要这些注册表项时,请删除它们。这些是机器范围的密钥,强制将所有应用程序迁移到 .NET 4.0,甚至是使用 .net 2 和 .net 3.5 的应用程序
回答by cmo999
The best solution I have found is in the blog post Using Newer Version(s) of .NET with PowerShell. This allows powershell.exe to run with .NET 4 assemblies.
我发现的最佳解决方案是在博客文章Using Newer Version(s) of .NET with PowerShell 中。这允许 powershell.exe 与 .NET 4 程序集一起运行。
Simply modify (or create) $pshome\powershell.exe.configso that it contains the following:
只需修改(或创建)$pshome\powershell.exe.config使其包含以下内容:
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
Additional, quick setup notes:
附加的快速设置说明:
Locations and files are somewhat platform dependent; however will give you an inline gist of how to make the solution work for you.
位置和文件在某种程度上取决于平台;但是会给你一个关于如何使解决方案适合你的内联要点。
- You can find PowerShell's location on your computer by executing
cd $pshomein the Powershell window(doesn't work from DOS prompt).- Path will be something like (example)
C:\Windows\System32\WindowsPowerShell\v1.0\
- Path will be something like (example)
- The filename to put configuration in is:
powershell.exe.configif yourPowerShell.exeis being executed (create the config file if need be).- If
PowerShellISE.Exeis running then you need to create its companion config file asPowerShellISE.Exe.config
- If
- 您可以通过
cd $pshome在 Powershell 窗口中执行来找到 PowerShell 在计算机上的位置(不适用于 DOS 提示符)。- 路径将类似于(示例)
C:\Windows\System32\WindowsPowerShell\v1.0\
- 路径将类似于(示例)
- 放置配置的文件名是:
powershell.exe.config如果您PowerShell.exe正在执行(如果需要,创建配置文件)。- 如果
PowerShellISE.Exe正在运行,那么您需要将其配套配置文件创建为PowerShellISE.Exe.config
- 如果
回答by Madhu Talluri
Please be VERY careful with using the registry key approach. These are machine-wide keys and forcibily migrate ALL applications to .NET4.0.
使用注册表项方法时请非常小心。这些是机器范围的密钥,可强制将所有应用程序迁移到.NET4.0。
Many products do not work if forcibily migrated and this is a testing aid and not a production quality mechanism. Visual Studio 2008 and 2010, MSBuild, turbotax, and a host of websites, SharePointand so on should not be automigrated.
如果强行迁移,许多产品将无法工作,这是一种测试辅助手段,而不是一种生产质量机制。Visual Studio 2008 和 2010、MSBuild、turbotax 和许多网站、SharePoint等不应自动迁移。
If you need to use PowerShell with 4.0, this should be done on a per-application basis with a configuration file, you should check with the PowerShell team on the precise recommendation. This is likely to break some existing PowerShell commands.
如果您需要将 PowerShell 与 4.0 一起使用,这应该在每个应用程序的基础上使用配置文件完成,您应该向 PowerShell 团队咨询确切的建议。这可能会破坏一些现有的 PowerShell 命令。
回答by Jason Stangroome
If you only need to execute a single command, script block, or script file in .NET 4, try using Activation Configuration Files from .NET 4to start only a single instance of PowerShell using version 4 of the CLR.
如果您只需要在 .NET 4 中执行单个命令、脚本块或脚本文件,请尝试使用 .NET 4 中的激活配置文件来仅使用 CLR 版本 4 启动单个 PowerShell 实例。
Full details:
完整细节:
http://blog.codeassassin.com/2011/03/23/executing-individual-powershell-commands-using-net-4/
http://blog.codeassassin.com/2011/03/23/executing-individual-powershell-commands-using-net-4/
An example PowerShell module:
一个示例 PowerShell 模块:
回答by Tim Lewis
If you're still stuck on PowerShell v1.0 or v2.0, here is my variation on Jason Stangroome's excellent answer.
如果您仍然坚持使用 PowerShell v1.0 或 v2.0,这里是我对 Jason Stangroome 出色回答的变体。
Create a powershell4.cmdsomewhere on your path with the following contents:
powershell4.cmd使用以下内容在您的路径上创建一个位置:
@echo off
:: http://stackoverflow.com/questions/7308586/using-batch-echo-with-special-characters
if exist %~dp0powershell.exe.activation_config goto :run
echo.^<?xml version="1.0" encoding="utf-8" ?^> > %~dp0powershell.exe.activation_config
echo.^<configuration^> >> %~dp0powershell.exe.activation_config
echo. ^<startup useLegacyV2RuntimeActivationPolicy="true"^> >> %~dp0powershell.exe.activation_config
echo. ^<supportedRuntime version="v4.0"/^> >> %~dp0powershell.exe.activation_config
echo. ^</startup^> >> %~dp0powershell.exe.activation_config
echo.^</configuration^> >> %~dp0powershell.exe.activation_config
:run
:: point COMPLUS_ApplicationMigrationRuntimeActivationConfigPath to the directory that this cmd file lives in
:: and the directory contains a powershell.exe.activation_config file which matches the executable name powershell.exe
set COMPLUS_ApplicationMigrationRuntimeActivationConfigPath=%~dp0
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe %*
set COMPLUS_ApplicationMigrationRuntimeActivationConfigPath=
This will allow you to launch an instance of the powershell console running under .NET 4.0.
这将允许您启动在 .NET 4.0 下运行的 powershell 控制台实例。
You can see the difference on my system where I have PowerShell 2.0 by examining the output of the following two commands run from cmd.
通过检查从 cmd 运行的以下两个命令的输出,您可以看到我的系统上有 PowerShell 2.0 的差异。
C:\>powershell -ExecutionPolicy ByPass -Command $PSVersionTable
Name Value
---- -----
CLRVersion 2.0.50727.5485
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
C:\>powershell4.cmd -ExecutionPolicy ByPass -Command $PSVersionTable
Name Value
---- -----
PSVersion 2.0
PSCompatibleVersions {1.0, 2.0}
BuildVersion 6.1.7601.17514
CLRVersion 4.0.30319.18408
WSManStackVersion 2.0
PSRemotingProtocolVersion 2.1
SerializationVersion 1.1.0.1
回答by Emperor XLII
Here is the contents of the configuration file I used to support both .NET 2.0 and .NET 4 assemblies:
这是我用来支持 .NET 2.0 和 .NET 4 程序集的配置文件的内容:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!-- http://msdn.microsoft.com/en-us/library/w4atty68.aspx -->
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" />
<supportedRuntime version="v2.0.50727" />
</startup>
</configuration>
Also, here's a simplified version of the PowerShell 1.0 compatible code I used to execute our scripts from the passed in command line arguments:
此外,这是我用来从传入的命令行参数执行脚本的 PowerShell 1.0 兼容代码的简化版本:
class Program {
static void Main( string[] args ) {
Console.WriteLine( ".NET " + Environment.Version );
string script = "& " + string.Join( " ", args );
Console.WriteLine( script );
Console.WriteLine( );
// Simple host that sends output to System.Console
PSHost host = new ConsoleHost( this );
Runspace runspace = RunspaceFactory.CreateRunspace( host );
Pipeline pipeline = runspace.CreatePipeline( );
pipeline.Commands.AddScript( script );
try {
runspace.Open( );
IEnumerable<PSObject> output = pipeline.Invoke( );
runspace.Close( );
// ...
}
catch( RuntimeException ex ) {
string psLine = ex.ErrorRecord.InvocationInfo.PositionMessage;
Console.WriteLine( "error : {0}: {1}{2}", ex.GetType( ), ex.Message, psLine );
ExitCode = -1;
}
}
}
In addition to the basic error handling shown above, we also inject a trapstatement into the script to display additional diagnostic information (similar to Jeffrey Snover's Resolve-Errorfunction).
除了上面显示的基本错误处理之外,我们还在trap脚本中注入了一条语句来显示额外的诊断信息(类似于 Jeffrey Snover 的Resolve-Error函数)。
回答by Jeppe Stig Nielsen
The other answers are from before 2012, and they focus on "hacking" PowerShell 1.0 or PowerShell 2.0 into targeting newer versions of the .NET Framework and Common Language Runtime (CLR).
其他答案来自 2012 年之前,他们专注于“入侵”PowerShell 1.0 或 PowerShell 2.0 以针对较新版本的 .NET Framework 和公共语言运行时 (CLR)。
However, as has been written in many comments, since 2012 (when PowerShell 3.0 came) a much better solution is to install the newest version of PowerShell. It will automatically target CLR v4.0.30319. This means .NET 4.0, 4.5, 4.5.1, 4.5.2, or 4.6 (expected in 2015) since all of these versions are in-place replacements of each other. Use $PSVersionTableor see the Determine installed PowerShell versionthreadif you are unsure of your PowerShell version.
但是,正如许多评论中所写的那样,自 2012 年(PowerShell 3.0 出现时)以来,更好的解决方案是安装最新版本的 PowerShell。它将自动以 CLR 为目标v4.0.30319。这意味着 .NET 4.0、4.5、4.5.1、4.5.2 或 4.6(预计在 2015 年推出),因为所有这些版本都是彼此的就地替换。如果您不确定您的 PowerShell 版本,请使用$PSVersionTable或查看确定已安装的 PowerShell 版本线程。
At the time of writing, the newest version of PowerShell is 4.0, and it can be downloaded with the Windows Management Framework (Google search link).
在撰写本文时,PowerShell 的最新版本是 4.0,可以通过Windows 管理框架(谷歌搜索链接)下载。
回答by Justin Yancey
Actually, you can get PowerShell to run using .NET 4 withoutaffecting other .NET applications. I needed to do so to use the new HttpWebRequest "Host" property, however changing the "OnlyUseLatestCLR" broke Fiddler as that could not be used under .NET 4.
实际上,您可以使用 .NET 4 运行 PowerShell,而不会影响其他 .NET 应用程序。我需要这样做才能使用新的 HttpWebRequest "Host" 属性,但是更改 "OnlyUseLatestCLR" 破坏了 Fiddler,因为它无法在 .NET 4 下使用。
The developers of PowerShell obviously foresaw this happening, and they added a registry key to specify what version of the Framework it should use. One slight issue is that you need to take ownership of the registry key before changing it, as even administrators do not have access.
PowerShell 的开发人员显然预见到了这种情况,他们添加了一个注册表项来指定它应该使用哪个版本的框架。一个小问题是您需要在更改注册表项之前取得其所有权,因为即使是管理员也无权访问。
- HKLM:\Software\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion (64 bit and 32 bit)
- HKLM:\Software\Wow6432Node\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion (32 bit on 64 bit machine)
- HKLM:\Software\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion(64 位和 32 位)
- HKLM:\Software\Wow6432Node\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion(64 位机器上的 32 位)
Change the value of that key to the required version. Keep in mind though that some snapins may no longer load unless they are .NET 4 compatible (WASP is the only one I have had trouble with, but I don't really use it anyway). VMWare, SQL Server 2008, PSCX, Active Directory(Microsoft and Quest Software) and SCOM all work fine.
将该键的值更改为所需的版本。请记住,某些管理单元可能不再加载,除非它们与 .NET 4 兼容(WASP 是我遇到的唯一问题,但我并没有真正使用它)。VMWare、SQL Server 2008、PSCX、Active Directory(Microsoft 和Quest Software)和 SCOM 都可以正常工作。
回答by Grant Holliday
If you don't want to modify the registry or app.config files, an alternate way is to create a simple .NET 4 console app that mimicks what PowerShell.exe does and hosts the PowerShell ConsoleShell.
如果您不想修改注册表或 app.config 文件,另一种方法是创建一个简单的 .NET 4 控制台应用程序,它模仿 PowerShell.exe 的功能并托管 PowerShell ConsoleShell。
See Option 2 – Hosting Windows PowerShell yourself
请参阅选项 2 – 自己托管 Windows PowerShell
First, add a reference to the System.Management.Automationand Microsoft.PowerShell.ConsoleHostassemblies which can be found under %programfiles%\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0
首先,添加对System.Management.Automation和Microsoft.PowerShell.ConsoleHost程序集的引用,它们可以在%programfiles%\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0 下找到
Then use the following code:
然后使用以下代码:
using System;
using System.Management.Automation.Runspaces;
using Microsoft.PowerShell;
namespace PSHostCLRv4
{
class Program
{
static int Main(string[] args)
{
var config = RunspaceConfiguration.Create();
return ConsoleShell.Start(
config,
"Windows PowerShell - Hosted on CLR v4\nCopyright (C) 2010 Microsoft Corporation. All rights reserved.",
"",
args
);
}
}
}
回答by Jaykul
Just as another option, the latest PoshConsolerelease includes binaries targeted to .NET4 RC (which work fine against the RTM release) without any configuration.
作为另一种选择,最新的PoshConsole版本包括针对.NET4 RC(在 RTM 版本中运行良好)的二进制文件,无需任何配置。

