PowerShell'i .NET 4 çalışma zamanı ile nasıl çalıştırabilirim?


234

Bazı .NET derlemelerini yöneten bir PowerShell betiğini güncelleştiriyorum. Komut dosyası, .NET 2'ye (PowerShell'in çalıştığı çerçevenin aynı sürümü) karşı oluşturulan derlemeler için yazılmıştır, ancak şimdi .NET 4 derlemelerinin yanı sıra .NET 2 derlemeleriyle de çalışması gerekir.

.NET 4, çerçevenin eski sürümlerine göre çalışan uygulamaları çalıştırmayı desteklediğinden, en basit çözüm, .NET 4 derlemelerine karşı çalıştırmam gerektiğinde PowerShell'i .NET 4 çalışma zamanı ile başlatmak gibi görünüyor.

PowerShell'i .NET 4 çalışma zamanı ile nasıl çalıştırabilirim?



8
Günümüzde CLRVersion: 4.0.30319.1 kullanan Powershell 3.0 CTP'yi kurmak en kolay çözüm olacaktır.
jon Z

2
Hala PowerShell 2 ile takılı kalan herkes, Tim Lewis'in makine çapında herhangi bir yapılandırmayı düzenlemeyi gerektirmeyen yerelleştirilmiş bir çözüm için cevabına bakın.
Eric Eskildsen

1
Sistem çapında olmayan ve gereksiz bir çözüm için bu cevaba
vkrzv

Yanıtlar:


147

PowerShell (motor) .NET 4.0 altında sorunsuz çalışır. PowerShell (konsol ana bilgisayarı ve ISE ), eski .NET sürümlerine karşı derlendikleri için bunu yapmaz. Sistem genelinde yüklenen .NET çerçevesini değiştirecek ve bu da PowerShell'in .NET 4.0 sınıflarını kullanmasına izin verecek bir kayıt defteri ayarı vardır :

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

Yalnızca ISE'yi .NET 4.0 kullanacak biçimde güncelleştirmek için yapılandırma ($ psHome \ powershell_ise.exe.config) dosyasını aşağıdaki gibi bir parçaya sahip olacak şekilde değiştirebilirsiniz:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup>
      <supportedRuntime version="v4.0.30319" />
    </startup>
</configuration>

PowerShell API'sini (System.Management.Automation.PowerShell) kullanarak PowerShell'i çağıran .NET 4.0 uygulamaları oluşturabilirsiniz, ancak bu adımlar kutudaki PowerShell ana bilgisayarlarının .NET 4.0 altında çalışmasına yardımcı olur.


Artık ihtiyacınız olmadığında kayıt defteri anahtarlarını kaldırın. Bunlar makine genelindeki anahtarlardır ve TÜM uygulamaları .net 2 ve .net 3.5 kullanan uygulamalar için bile zorla .NET 4.0'a geçirir.



9
Açık olmak gerekirse, powershell.exe'nin (konsol ana bilgisayar uygulaması) kendisi yerel bir uygulamadır - yönetilmez.
Keith Hill

4
Sorunumu yukarıdan anladım. 64 bit işletim sisteminde çalışırken yapılandırma dosyasını 64 bit dizine koymanız gerekir. 32-bit powershell çalıştırılabilir değişikliği oradan gayet iyi görünüyor.
Chris McKenzie

11
Sadece küçük bir tavsiye. Artık ihtiyacınız olmadığında kayıt defteri anahtarlarını kaldırın. Üzerinde çalıştığım bazı .NET 3.5 projelerini neden inşa edemediğimi öğrenmeye çalışırken çok fazla zaman kaybettim.
Klark

7
Çoklu hedefleme yapıyorsanız önerilen kayıt defteri değişiklik çözümü kötü yan etkilere sahiptir (örn. VS2010'da .NET 2.0 uygulamaları yazmak). Dikkat.
Todd Sprang

9
Microsoft'un bunu yapmamaya karşı büyük bir uyarıda bulunduğunu unutmayın: "PowerShell 2.0'ı PowerShell için bir yapılandırma dosyası oluşturma veya kayıt defterini düzenleme gibi çeşitli mekanizmalar kullanarak .NET Framework 4.0 ile çalışmaya zorlamak mümkün olsa da, bu mekanizmalar desteklenmez ve PowerShell uzaktan kumandası ve karışık mod montajlı cmdlet'ler gibi diğer PowerShell işlevleri üzerinde olumsuz yan etkiler. " connect.microsoft.com/PowerShell/feedback/details/525435/… Powershell 3.0'ın .NET 4.0 için yerel desteği vardır.
Timbo

238

Bulduğum en iyi çözüm , .NET'in PowerShell ile Daha Yeni Sürümlerini Kullanma blog yayınında . Bu, powershell.exe'nin .NET 4 derlemeleriyle çalışmasına izin verir.

$pshome\powershell.exe.configAşağıdakileri içerecek şekilde değiştirin (veya oluşturun) :

<?xml version="1.0"?> 
<configuration> 
    <startup useLegacyV2RuntimeActivationPolicy="true"> 
        <supportedRuntime version="v4.0.30319"/> 
        <supportedRuntime version="v2.0.50727"/> 
    </startup> 
</configuration> 

Ek, hızlı kurulum notları:

Konumlar ve dosyalar bir şekilde platforma bağlıdır; bununla birlikte, çözümün sizin için nasıl işe yarayacağına dair satır içi bir özeti size verecektir.

  • PowerShell'in konumunu cd $pshome , Powershell penceresinde çalıştırarak bilgisayarınızda bulabilirsiniz (DOS komut isteminden çalışmaz).
    • Yol böyle bir şey olacaktır (örnek) C:\Windows\System32\WindowsPowerShell\v1.0\
  • Yapılandırmayı koymak için dosya adı: powershell.exe.configsenin eğer PowerShell.exe(gerekirse yapılandırma dosyası oluşturmak) yürütülmektedir.
    • Eğer PowerShellISE.Exeo zaman çalıştığı siz onun arkadaşı yapılandırma dosyası oluşturmanız gerekirPowerShellISE.Exe.config

23
Bunu yapmanın kesinlikle doğru yolu. Bu, makinenizdeki diğer tüm .NET uygulamalarını değil, sadece Powershell'in davranışını değiştirir ...
Erik A. Brandstadmoen

4
Bu iyi çalışır ancak tüm PowerShell'inizi etkiler. Sadece bazı işlevsellik istiyorsanız powershell klasörünün bir kopyasını yapın ve sonra dosyayı orada düzenleyin.
Matt

8
Yukarıda belirtildiği gibi bir dosya ekledim. Ancak, PowerShell'i artık bu dosyayla birlikte çalıştıramıyorum - "Açılan dosyanın artık geçerli olmaması için bir dosyanın birimi harici olarak değiştirildi" hatasını alıyorum. Herhangi bir fikir?
JoshL

13
@JoshL - 64 bit sistemde, 64 bit powershell'i çalıştırmaya çalışsanız bile .exe.config dosyasının SysWOW64 \ WindowsPowershell'e (32 bit klasör) girmesi gerektiğini buldum. Aksi takdirde 'harici olarak değiştirildi' hatasını alırsınız.
Sam


28

Lütfen kayıt defteri anahtarı yaklaşımını kullanırken ÇOK dikkatli olun. Bunlar makine genelindeki anahtarlardır ve TÜM uygulamaları .NET 4.0'a zorla geçirir .

Zorla taşınması durumunda birçok ürün çalışmaz ve bu bir üretim kalitesi mekanizması değil, bir test yardımcısıdır. Visual Studio 2008 ve 2010, MSBuild , turbotax ve bir dizi web sitesi, SharePoint vb. Otomatikleştirilmemelidir.

PowerShell'i 4.0 ile kullanmanız gerekiyorsa, bu her uygulama için bir yapılandırma dosyasıyla yapılmalıdır, kesin öneri konusunda PowerShell ekibine danışmalısınız. Bu, varolan bazı PowerShell komutlarını kırabilir.


Kayıt defteri anahtarını kullanma konusunda çok iyi bir nokta. Ne mutlu ki, yapılandırma dosyası ile başlatıcısı uygulaması gayet iyi çalışıyor. Komut dosyalarımız öncelikle dosya sistemi komutlarını ve doğrudan .NET çağrılarını kullanır ve bozuk komutlarla ilgili herhangi bir sorun fark etmedik. .NET 4, .NET 2.0 ile büyük ölçüde geriye dönük uyumlu olduğundan, pek çok kırık komut olacağını düşünmüyorum (ancak dikkatli olmak için asla acıyor :).
İmparator XLII


21

Hala PowerShell v1.0 veya v2.0'a takılı kalıyorsanız, Jason Stangroome'un mükemmel cevabındaki varyasyonum.

Bir oluşturma powershell4.cmdAşağıdaki içerikleri ile yolu üzerinde bir yerlerde:

@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=

Bu, .NET 4.0 altında çalışan powershell konsolunun bir örneğini başlatmanızı sağlar.

Aşağıdaki iki komutun çıktısını cmd'den inceleyerek PowerShell 2.0'a sahip olduğum sistemimdeki farkı görebilirsiniz.

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

3
Bu, yerel bir değişiklik olduğundan ve sistemde kalıcı bir değişiklik yapmadığından, en iyi cevaptır. İyi şeyler!
Sebastian

fantastik! Buraya yardım edebilir misin? stackoverflow.com/questions/39801315/…
johny neden

@TimLewis, aynı ps4.cmd örneğine birden çok ifade göndermek mümkün müdür?
johny neden

@johnywhy, .cmd dosyasına birden çok ifade göndermek, .exe'e birden çok ifade göndermekle aynıdır. Ancak, cmd.exe'nin başlattığı yürütülebilir dosyaya parametreleri iletirken komut satırını nasıl ayrıştırdığına dikkat etmeniz gerektiğinden, bir fark yaratmaz. Buradaki diğer yığın taşması sorunuza ve adres özelliklerine bir göz atacağım.
Tim Lewis

Bu tekniği -Version komut satırı parametresiyle birlikte kullanmaya çalıştım docs.microsoft.com/en-us/powershell/scripting/core-powershell/… Ne yazık ki çalışmıyor; $ PSVersionTable.PSVersion'dan belirlenen en son PowerShell sürümüm (5.1.17134.407) piyasaya sürüldü.
eisenpony

17

Hem .NET 2.0 hem de .NET 4 derlemelerini desteklemek için kullandığım yapılandırma dosyasının içeriği:

<?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>

Ayrıca, komut satırlarımızı iletilen komut satırı argümanlarından yürütmek için kullandığım PowerShell 1.0 uyumlu kodun basitleştirilmiş bir sürümü:

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;
    }
  }
}

Yukarıda gösterilen temel hata işlemeye ek olarak, trapkomut dosyasına ek tanı bilgileri görüntülemek için bir ifade ekliyoruz (Jeffrey Snover'ın Çözümleme Hatası işlevine benzer).


10

Diğer yanıtlar 2012 öncesindendir ve PowerShell 1.0 veya PowerShell 2.0'ı .NET Framework ve Common Language Runtime'ın (CLR) daha yeni sürümlerini hedeflemeye "odaklamaya" odaklanmıştır.

Bununla birlikte, birçok yorumda yazıldığı gibi, 2012'den beri (PowerShell 3.0 geldiğinde) PowerShell'in en yeni sürümünü yüklemek daha iyi bir çözümdür . CLR'yi otomatik olarak hedefleyecektir v4.0.30319. Bu, .NET 4.0, 4.5, 4.5.1, 4.5.2 veya 4.6 (2015'te beklenen) anlamına gelir, çünkü bu sürümlerin tümü birbirinin yerinde değiştirilmesidir. kullanım$PSVersionTablePowerShell sürümünüzden emin değilseniz Yüklü PowerShell sürümünü belirleme iş parçacığını veya bakın .

Yazma sırasında, PowerShell'in en yeni sürümü 4.0'dır ve Windows Yönetim Çerçevesi (Google arama bağlantısı) ile indirilebilir .


2
Windows Management Framework 4.0 için sistem gereksinimleri (3.0 için benzerdir): Windows 7, Windows Embedded Standard 7, Windows Server 2008 R2, Windows Server 2012.
Peter Mortensen

9

Aslında, .NET 4 kullanarak çalıştırmak için PowerShell alabilirsiniz olmadan diğer .NET uygulamalarını etkileyen. Yeni HttpWebRequest "Host" özelliğini kullanmak için bunu yapmak gerekiyordu, ancak "OnlyUseLatestCLR" değiştirerek .NET 4 altında kullanılamaz gibi Fiddler kırdı.

PowerShell geliştiricileri açıkça bunun olmasını öngördü ve Çerçeve'nin hangi sürümünü kullanması gerektiğini belirtmek için bir kayıt defteri anahtarı eklediler. Küçük bir sorun, yöneticilerin bile erişimi olmadığı için kayıt defteri anahtarını değiştirmeden önce sahip olmanız gerekir.

  • HKLM: \ Yazılım \ Microsoft \ Powershell \ 1 \ PowerShellEngine \ RuntimeVersion (64 bit ve 32 bit)
  • HKLM: \ Software \ Wow6432Node \ Microsoft \ Powershell \ 1 \ PowerShellEngine \ RuntimeVersion (64 bit makinede 32 bit)

Bu anahtarın değerini gereken sürüme değiştirin. .NET 4 uyumlu olmadıkça bazı snapinlerin artık yüklenmeyebileceğini unutmayın (WASP, sorun yaşadığım tek şeydir, ancak yine de kullanmıyorum). VMWare , SQL Server 2008 , PSCX, Active Directory (Microsoft ve Quest Yazılımı ) ve SCOM sorunsuz çalışır.


+1 Bu, tüm .net uygulamalarını etkileyecek diğer reg girdilerinden çok önemli bir alternatiftir (ve daha iyi), ancak bu çözüm yalnızca powershell'i etkiler.
Christian Mikkelsen

"OnlyUseLatestCLR" 'yi uyguladıktan sonra Fiddler'im ve bazı sunucularla bağlantı kuramadığı için artık çalıştırılmayan bazı powershell betikleri bozuldu. Regedt32'deki değerleri manuel olarak 0 olarak değiştirdim ve şimdi her şey tekrar çalışıyor. Teşekkürler!
Neville

WASP, PSCX ve SCOM (bu bağlamda) nedir?
Peter Mortensen

7

Kayıt defteri veya app.config dosyalarını değiştirmek istemiyorsanız, alternatif bir yol, PowerShell.exe'nin yaptıklarını taklit eden ve PowerShell ConsoleShell'i barındıran basit bir .NET 4 konsol uygulaması oluşturmaktır.

Bkz. Seçenek 2 - Windows PowerShell'i kendiniz barındırma

İlk olarak, % programfiles% \ Reference Assemblies \ Microsoft \ WindowsPowerShell \ v1.0 altında bulunan System.Management.Automation ve Microsoft.PowerShell.ConsoleHost derlemelerine başvuru ekleyin.

Ardından aşağıdaki kodu kullanın:

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
            );
        }
    }
}

6

Başka bir seçenek olarak, en son PoshConsole sürümü, herhangi bir yapılandırma olmadan .NET 4 RC'yi (RTM sürümüne karşı iyi çalışır) hedefleyen ikili dosyaları içerir .


1

COMPLUS_versionOrtam değişkeni olarak ayarlanmış powershell.exe dosyasını çalıştırın v4.0.30319. Örneğin, cmd.exe veya .bat dosyasından:

set COMPLUS_version=v4.0.30319
powershell -file c:\scripts\test.ps1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.