Как запустить PowerShell с помощью среды выполнения.NET 4?




.net-4.0 (7)

Я обновляю сценарий PowerShell, который управляет некоторыми сборками .NET. Сценарий был написан для сборок, построенных против .NET 2 (той же версии среды, с которой работает PowerShell), но теперь ей необходимо работать с сборками .NET 4, а также с сборками .NET 2.

Поскольку .NET 4 поддерживает запуск приложений, созданных на основе старых версий фреймворка, кажется, что самым простым решением является запуск PowerShell с использованием среды .NET 4, когда мне нужно запустить его с сборками .NET 4.

Как запустить PowerShell с помощью среды выполнения .NET 4?


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


Вот содержимое файла конфигурации, который я использовал для поддержки сборок .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 для отображения дополнительной диагностической информации (аналогично функции Resolve-Error Джеффри Сновера).


Если вам нужно выполнить только одну команду, блок сценариев или файл сценария в .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


Если вы все еще придерживаетесь PowerShell v1.0 или v2.0, вот моя вариация на отличный ответ Джейсона Стенгроума.

Создайте файл powershell4.cmd где-то на вашем пути со следующим содержимым:

@echo off
:: http://.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

Как и еще один вариант, последний выпуск PoshConsole включает в себя двоичные файлы, предназначенные для .NET 4 RC (которые отлично работают с релизом RTM) без какой-либо конфигурации.


Лучшее решение, которое я нашел, находится в блоге с использованием более новой версии .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 в PowerShellISE.Exe.config

Фактически, вы можете запустить 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 работают нормально.







.net-4.0