Я обновляю PowerShell script, который управляет некоторыми сборками .NET. script был написан для сборок, встроенных в .NET 2 (та же самая версия фреймворка, с которой работает PowerShell), но теперь ему необходимо работать с сборками .NET 4, а также с сборками .NET 2.
Так как .NET 4 поддерживает запуск приложений, созданных на основе старых версий фреймворка, кажется, что самое простое решение - запустить PowerShell со средой .NET 4, когда мне нужно запустить его с сборками .NET 4.
Как запустить PowerShell со средой .NET 4?
Ответ 1
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
Чтобы обновить только 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>
Вы можете создавать приложения .NET 4.0, которые вызывают PowerShell с помощью PowerShell API (System.Management.Automation.PowerShell), просто отлично, но эти шаги помогут получить доступ к встроенным в PowerShell хостам для работы в .NET 4.0.
Удалите ключи реестра, когда они вам больше не понадобятся. Это машинные ключи и принудительно переносят ВСЕ приложения в .NET 4.0, даже приложения с использованием .net 2 и .net 3.5
Ответ 2
Лучшее решение, которое я нашел, - в блоге Использование более новых версий .NET с PowerShell. Это позволяет powershell.exe работать со сборками .NET 4.
Просто измените (или создайте) $pshome\powershell.exe.config
, чтобы он содержал следующее:
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0.30319"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
Дополнительные примечания по быстрой установке:
Расположение и файлы в некоторой степени зависят от платформы; Тем не менее, вы узнаете, как заставить решение работать на вас.
- Вы можете найти расположение PowerShell на вашем компьютере, выполнив
cd $pshome
в окне Powershell (не работает из командной строки DOS).
- Путь будет примерно таким (пример)
C:\Windows\System32\WindowsPowerShell\v1.0\
- Имя файла для конфигурации:
powershell.exe.config
, если выполняется ваш PowerShell.exe
(создайте файл конфигурации, если это необходимо).
- Если
PowerShellISE.Exe
запущен, вам нужно создать его конфигурационный файл как PowerShellISE.Exe.config
Ответ 3
Пожалуйста, будьте ОЧЕНЬ осторожны с использованием подхода к разделу реестра. Это ключи машинного интерфейса и автоматически переносят ВСЕ приложения в .NET 4.0.
Многие продукты не работают, если они переносятся автоматически, и это средство тестирования, а не механизм качества продукции. Visual Studio 2008 и 2010, MSBuild, turbotax и множество веб-сайтов, SharePoint и т.д. не должны быть автоматизированы.
Если вам нужно использовать PowerShell с 4.0, это должно быть сделано для каждого приложения с конфигурационным файлом, вы должны проверить с командой PowerShell точную рекомендацию. Вероятно, это приведет к поломке некоторых существующих команд PowerShell.
Ответ 4
Если вам нужна только одна команда, блок script или script в .NET 4, попробуйте использовать Файлы конфигурации активации .NET 4, чтобы запустить только один экземпляр PowerShell, используя версию 4 CLR.
Полная информация:
http://blog.codeassassin.com/2011/03/23/executing-individual-powershell-commands-using-net-4/
Пример модуля PowerShell:
https://gist.github.com/882528
Ответ 5
Если вы все еще застряли в PowerShell v1.0 или v2.0, вот мой вариант на Jason Stangroome отличный ответ.
Создайте 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=
Это позволит вам запустить экземпляр консоли powershell, работающей под .NET 4.0.
Вы можете увидеть разницу в моей системе, где у меня есть PowerShell 2.0, рассмотрев вывод следующих двух команд, запущенных из cmd.
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
Ответ 6
Вот содержимое файла конфигурации, который я использовал для поддержки сборок .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>
Кроме того, это упрощенная версия совместимого с 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;
}
}
}
В дополнение к основной обработке ошибок, показанной выше, мы также вводим инструкцию trap
в script, чтобы отобразить дополнительную диагностическую информацию (похожую на Jeffrey Snover Resolve-Error).
Ответ 7
Другие ответы датируются до 2012 года, и они сосредоточены на "взломе" PowerShell 1.0 или PowerShell 2.0 в таргетинге на более новые версии .NET Framework и Common Language Runtime (CLR).
Однако, как было написано во многих комментариях, с 2012 года (когда пришел PowerShell 3.0) гораздо лучшее решение - это установить новейшую версию PowerShell. Он автоматически настроится на CLR v4.0.30319
. Это означает, что .NET 4.0, 4.5, 4.5.1, 4.5.2 или 4.6 (ожидается в 2015 году), поскольку все эти версии заменяют друг друга на месте. Используйте $PSVersionTable
или посмотрите Определить установленный поток версии PowerShell, если вы не уверены в своей версии PowerShell.
На момент написания последней версии PowerShell 4.0, и она может быть загружена с помощью системы управления Windows (ссылка для поиска Google).
Ответ 8
На самом деле вы можете запустить PowerShell с помощью .NET 4, не затрагивая другие .NET-приложения. Мне нужно было сделать это, чтобы использовать новое свойство хоста HttpWebRequest, однако изменение "OnlyUseLatestCLR" сломало Fiddler, поскольку это невозможно было использовать в .NET 4.
Разработчики PowerShell явно предвидели это, и они добавили раздел реестра, чтобы указать, какую версию Framework он должен использовать. Одна из незначительных проблем заключается в том, что перед тем, как изменить его, вам необходимо взять на себя управление ключом реестра, так как даже администраторы не имеют доступа.
- HKLM:\Software\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion (64-разрядная и 32-разрядная версия)
- HKLM:\Software\Wow6432Node\Microsoft\Powershell\1\PowerShellEngine\RuntimeVersion (32-разрядная версия на 64-битной машине)
Измените значение этого ключа на нужную версию. Имейте в виду, что некоторые snapins больше не могут загружаться, если они не совместимы с .NET 4 (WASP - это единственное, с чем я столкнулся, но на самом деле я его не использую). VMWare, SQL Server 2008, PSCX, Active Directory (Microsoft и Quest Software), и SCOM все работает нормально.
Ответ 9
Если вы не хотите изменять файлы реестра или app.config, альтернативный способ - создать простое консольное приложение .NET 4, которое имитирует то, что делает PowerShell.exe, и размещает PowerShell ConsoleShell.
См. Вариант 2 - Хостинг Windows PowerShell самостоятельно
Сначала добавьте ссылку на сборки System.Management.Automation и Microsoft.PowerShell.ConsoleHost, которые можно найти в разделе % programfiles%\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0
Затем используйте следующий код:
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
);
}
}
}
Ответ 10
Как еще один вариант, последний выпуск PoshConsole включает в себя двоичные файлы, предназначенные для .NET 4 RC (которые отлично работают с релизом RTM) без какой-либо конфигурации.
Ответ 11
Просто запустите powershell.exe с переменной среды COMPLUS_version
, для которой установлено значение v4.0.30319
.
Например, из cmd.exe или .bat файла:
set COMPLUS_version=v4.0.30319
powershell -file c:\scripts\test.ps1