Výběr správného balíčku NuGet PowerShellu pro váš projekt .NET

pwsh Kromě spustitelných balíčků publikovaných s každou verzí PowerShellu udržuje tým PowerShellu také několik balíčků dostupných na NuGetu. Tyto balíčky umožňují cílení na PowerShell jako platformu ROZHRANÍ API v .NET.

Jako aplikace .NET, která poskytuje rozhraní API a očekává načtení knihoven .NET implementovaných vlastními (binárními moduly), je nezbytné, aby byl PowerShell k dispozici ve formě balíčku NuGet.

V současné době existuje několik balíčků NuGet, které poskytují určitou reprezentaci oblasti rozhraní API PowerShellu. Který balíček pro použití s konkrétním projektem nebyl vždy jasný. Tento článek vysvětluje několik běžných scénářů, které se zaměřují na projekty .NET v PowerShellu a jak zvolit správný balíček NuGet určený pro váš projekt .NET orientovaný na PowerShell.

Hostování vs. odkazování

Některé projekty .NET se snaží napsat kód, který se má načíst do existujícího modulu runtime PowerShellu (například pwshpowershell.exe, integrované konzoly PowerShellu nebo integrovaného skriptovacího prostředí (ISE), zatímco jiní chtějí spustit PowerShell ve svých vlastních aplikacích.

  • Odkazování je, když je projekt, obvykle modul, určený k načtení do PowerShellu. Musí být zkompilován proti rozhraním API, která PowerShell poskytuje, aby s ním mohl pracovat, ale implementace PowerShellu je poskytována procesem PowerShellu, který ho načítá. Pro odkazování může projekt používat referenční sestavení nebo skutečná sestavení runtime jako cíl kompilace, ale musí zajistit, aby nepublikovala žádnou z těchto sestavení s jeho sestavením.
  • Hostování je, když projekt potřebuje vlastní implementaci PowerShellu, obvykle proto, že se jedná o samostatnou aplikaci, která potřebuje spustit PowerShell. V tomto případě nelze použít čistě referenční sestavení. Místo toho musí být konkrétní implementace PowerShellu závislá. Vzhledem k tomu, že je nutné použít konkrétní implementaci PowerShellu, musí být pro hostování zvolena konkrétní verze PowerShellu; Jedna hostitelská aplikace nemůže více cílových verzí PowerShellu.

Publikování projektů, které cílí na PowerShell jako referenci

Poznámka:

Termín publikování v tomto článku používáme k odkazování na spuštění dotnet publish, který umístí knihovnu .NET do adresáře se všemi jeho závislostmi připravenými k nasazení do určitého modulu runtime.

Pokud chcete zabránit publikování závislostí projektu, které se právě používají jako referenční cíle kompilace, doporučujeme nastavit atribut PrivateAssets :

<PackageReference Include="PowerShellStandard.Library" Version="5.1.0.0" PrivateAssets="all" />

Pokud to zapomenete a použijete jako cíl referenční sestavení, můžou se místo skutečné implementace zobrazit problémy související s použitím výchozí implementace referenčního sestavení. To může mít formu , NullReferenceExceptionprotože referenční sestavení často napodobení rozhraní API implementace jednoduše vrací null.

Klíčové typy projektů .NET, které cílí na PowerShell

I když každá knihovna nebo aplikace .NET může vkládat PowerShell, existují některé běžné scénáře, které používají rozhraní API PowerShellu:

  • Implementace binárního modulu PowerShellu

    Binární moduly PowerShellu jsou knihovny .NET načtené prostředím PowerShell, které musí implementovat rozhraní API PowerShellu, jako jsou typy PSCmdlet nebo CmdletProvider , aby bylo možné zpřístupnit rutiny nebo zprostředkovatele. Vzhledem k tomu, že jsou načteny, moduly se snaží zkompilovat proti odkazům na PowerShell bez publikování v sestavení. Je také běžné, že moduly chtějí podporovat více verzí a platforem PowerShellu, ideálně s minimální režií na místo na disku, složitostí nebo opakovanou implementací. Další informace o modulech najdete v about_Modules .

  • Implementace hostitele PowerShellu

    Hostitel PowerShellu poskytuje vrstvu interakce pro modul runtime PowerShellu. Jedná se o konkrétní formu hostování, kde se psHost implementuje jako nové uživatelské rozhraní pro PowerShell. Například Konzola PowerShellu poskytuje uživatelské rozhraní terminálu pro spustitelné soubory PowerShellu, zatímco hostitel služby Editor Services PowerShellu a hostitel ISE poskytují částečně grafické uživatelské rozhraní integrované editorem kolem PowerShellu. I když je možné načíst hostitele do existujícího procesu PowerShellu, je mnohem častější, aby implementace hostitele fungovala jako samostatná implementace PowerShellu, která redistribuuje modul PowerShellu.

  • Volání do PowerShellu z jiné aplikace .NET

    Stejně jako u jakékoli aplikace lze PowerShell volat jako podproces pro spouštění úloh. Jako aplikace .NET je ale také možné vyvolat in-proces PowerShellu, aby se vrátily úplné objekty .NET pro použití v rámci volající aplikace. Toto je obecnější forma hostování, kde aplikace vlastní implementaci PowerShellu pro interní použití. Příkladem může být služba nebo démon, na kterém běží PowerShell ke správě stavu počítače nebo webové aplikace, která na vyžádání spouští PowerShell, aby bylo možné spravovat cloudová nasazení.

  • Testování jednotek modulů PowerShellu z .NET

    Moduly a další knihovny navržené tak, aby zpřístupnily funkce prostředí PowerShell, by měly být primárně testovány z PowerShellu (doporučujeme Pester), někdy je potřeba rozhraní API pro testování jednotek napsaná pro modul PowerShellu z .NET. Tato situace zahrnuje kód modulu, který se snaží cílit na řadu verzí PowerShellu, zatímco testování by mělo běžet na konkrétních konkrétních konkrétních implementacích.

Balíčky NuGet PowerShellu na první pohled

V tomto článku se budeme zabývat následujícími balíčky NuGet, které zpřístupňují rozhraní API PowerShellu:

  • PowerShellStandard.Library, referenční sestavení, které umožňuje sestavení jednoho sestavení, které lze načíst několika moduly runtime PowerShellu.
  • Microsoft.PowerShell.SDK, způsob cílení a změna hostitele celé sady PowerShell SDK
  • Balíček System.Management.Automation , základní modul runtime PowerShellu a implementace modulu, který může být užitečný v minimálních hostovaných implementacích a pro scénáře cílení specifické pro verze.
  • Referenční sestavení Prostředí Windows PowerShell, způsob cílení a efektivního hostování prostředí Windows PowerShell (powershell verze 5.1 a novější).

Poznámka:

Balíček NuGet PowerShellu není vůbec balíček knihovny .NET, ale poskytuje globální implementaci nástroje PowerShell dotnet. Neměly by ho používat žádné projekty, protože poskytuje pouze spustitelný soubor.

PowerShellStandard.Library

Standardní knihovna PowerShellu je referenční sestavení, které zachycuje průnik rozhraní API PowerShellu verze 7, 6 a 5.1. To poskytuje plochu rozhraní API s kontrolou času kompilace pro kompilaci kódu .NET, což umožňuje projektům .NET cílit na PowerShell verze 7, 6 a 5.1 bez rizika volání rozhraní API, které tam nebude.

PowerShell Standard je určený pro psaní modulů PowerShellu nebo jiného kódu, který se má spustit jenom po jeho načtení do procesu PowerShellu. Vzhledem k tomu, že se jedná o referenční sestavení, powershellový standard neobsahuje samotnou implementaci, takže neposkytuje žádné funkce pro samostatné aplikace.

Použití PowerShellu Standard s různými moduly runtime .NET

PowerShell Standard cílí na cílový modul runtime .NET Standard 2.0 , což je fasádní modul runtime navržený tak, aby poskytoval společnou plochu sdílenou rozhraním .NET Framework a .NET Core. To umožňuje cílení na jeden modul runtime, aby vytvořilo jedno sestavení, které bude fungovat s více verzemi PowerShellu, ale má následující důsledky:

  • Načtení modulu nebo knihovny powershellu musí spouštět minimálně .NET 4.6.1, .NET 4.6 a .NET 4.5.2 nepodporují .NET Standard. Všimněte si, že novější verze Windows PowerShellu neznamená novější verzi rozhraní .NET Framework; Windows PowerShell 5.1 může běžet na .NET 4.5.2.
  • Aby bylo možné pracovat s powershellem se spuštěným rozhraním .NET Framework 4.7.1 nebo nižším, je potřeba implementace rozhraní .NET 4.6.1 NETStandard.Library , která poskytují netstandard.dll a další sestavení shim ve starších verzích rozhraní .NET Framework.

PowerShell 6 nebo novější poskytuje vlastní sestavení shim pro předávání typů z rozhraní .NET Framework 4.6.1 (a vyšší) do .NET Core. To znamená, že pokud modul používá pouze rozhraní API, která existují v .NET Core, může PowerShell 6 nebo novější načíst a spustit, když je vytvořený pro rozhraní .NET Framework 4.6.1 ( net461 cíl modulu runtime).

To znamená, že binární moduly používající PowerShell Standard k cílení na více verzí PowerShellu s jednou publikovanou knihovnou DLL mají dvě možnosti:

  1. Publikování sestavení vytvořeného net461 pro cílový modul runtime Ta zahrnuje tyto kroky:

    • Publikování projektu pro net461 modul runtime
    • Také kompilace proti netstandard2.0 modulu runtime (bez použití výstupu sestavení), aby se zajistilo, že všechna použitá rozhraní API se nacházejí také v .NET Core.
  2. Publikování sestavení sestavení pro netstandard2.0 cílový modul runtime To vyžaduje:

    • Publikování projektu pro netstandard2.0 modul runtime
    • net461 Přebírá závislosti netStandard.Library a kopíruje je do umístění publikování sestavení projektu, aby bylo sestavení přeposílané typem opraveno v rozhraní .NET Framework.

Pokud chcete vytvářet moduly PowerShellu nebo knihovny, které cílí na starší verze rozhraní .NET Framework, může být vhodnější cílit na více modulů runtime .NET. Tím se publikuje sestavení pro každý cílový modul runtime a správné sestavení bude potřeba načíst v době načtení modulu (například s malým psm1 jako kořenovým modulem).

Testování projektů PowerShellu Standard v .NET

Pokud jde o testování modulu ve spouštěčích testů .NET, jako je xUnit, nezapomeňte, že kontroly doby kompilace můžou jít až doposud. Modul musíte otestovat na příslušných platformách PowerShellu.

Pokud chcete testovat rozhraní API vytvořená v prostředí PowerShell Standard v .NET, měli byste přidat Microsoft.Powershell.SDK jako testovací závislost pomocí .NET Core (verze nastavená tak, aby odpovídala požadované verzi PowerShellu) a odpovídající referenční sestavení Prostředí Windows PowerShell s rozhraním .NET Framework.

Další informace o PowerShellu Standard a jeho použití k napsání binárního modulu, který funguje v několika verzích PowerShellu, najdete v tomto blogovém příspěvku. Podívejte se také na úložiště PowerShell Standard na GitHubu.

Microsoft.PowerShell.SDK

Microsoft.PowerShell.SDK je metabalíč, který spojuje všechny komponenty sady PowerShell SDK do jednoho balíčku NuGet. Samostatná aplikace .NET může pomocí sady Microsoft.PowerShell.SDK spouštět libovolné funkce PowerShellu bez nutnosti v závislosti na externích instalacích nebo knihovnách PowerShellu.

Poznámka:

Sada PowerShell SDK jenom odkazuje na všechny balíčky komponent, které tvoří PowerShell, a které je možné použít pro vývoj v .NET pomocí PowerShellu.

Daná Microsoft.Powershell.SDK verze obsahuje konkrétní implementaci stejné verze aplikace PowerShellu. Verze 7.0 obsahuje implementaci PowerShellu 7.0 a spouštění příkazů nebo skriptů s ní se bude do značné míry chovat jako spuštění v PowerShellu 7.0.

Spouštění příkazů PowerShellu ze sady SDK je většinou, ale ne zcela stejné jako spouštění z pwsh. Například spuštění úlohy aktuálně závisí na dostupném pwsh spustitelném souboru, takže ve výchozím nastavení nebude fungovat Microsoft.Powershell.SDK .

Cílení Microsoft.Powershell.SDK z aplikace .NET umožňuje integraci se všemi sestaveními implementace PowerShellu, jako System.Management.Automationjsou , Microsoft.PowerShell.Managementa dalšími sestaveními modulů.

Publikování cílení Microsoft.Powershell.SDK na aplikaci bude obsahovat všechna tato sestavení a všechny závislosti vyžaduje PowerShell. Bude obsahovat také další prostředky, které PowerShell vyžaduje ve svém sestavení, například manifesty modulů pro moduly a ref adresář vyžadovaný doplňkem.Microsoft.PowerShell.*

Vzhledem k úplnosti Microsoft.Powershell.SDKje nejvhodnější pro:

  • Implementace hostitelů PowerShellu
  • Testování knihoven xUnit, které cílí na referenční sestavení PowerShellu
  • Vyvolání procesu v PowerShellu z aplikace .NET

Microsoft.PowerShell.SDK lze také použít jako cíl odkazu, pokud je projekt .NET určený k použití jako modulu nebo jinak načtený prostředím PowerShell, ale závisí na rozhraních API, která jsou k dispozici pouze v konkrétní verzi PowerShellu. Všimněte si, že sestavení publikované pro konkrétní verzi Microsoft.PowerShell.SDK bude bezpečné načíst a používat pouze v této verzi PowerShellu. Pokud chcete cílit na více verzí PowerShellu s konkrétními rozhraními API, vyžaduje se více sestavení, přičemž každá cílí na vlastní verzi Microsoft.Powershell.SDK.

Poznámka:

Sada PowerShell SDK je dostupná jenom pro PowerShell verze 6 a novější. Pokud chcete poskytovat ekvivalentní funkce prostředí Windows PowerShell, použijte referenční sestavení windows PowerShellu popsaná níže.

System.Management.Automation

Balíček System.Management.Automation je jádrem sady PowerShell SDK. Existuje v NuGetu, především jako prostředek, který Microsoft.Powershell.SDK má načíst. Dá se ale také použít přímo jako balíček pro menší scénáře hostování a moduly cílení na verze.

Konkrétně může být balíček vhodnějším poskytovatelem funkcí PowerShellu, System.Management.Automation když:

  • Hledáte jenom funkce jazyka PowerShellu (v System.Management.Automation.Language oboru názvů), jako je analyzátor PowerShellu, AST a rozhraní API pro návštěvníky AST (například pro statickou analýzu PowerShellu).
  • Chcete z modulu spouštět pouze konkrétní příkazy Microsoft.PowerShell.Core a můžete je spustit ve stavu relace vytvořeném pomocí metody CreateDefault2 factory.

Kromě toho je užitečné referenční sestavení v System.Management.Automation následujících případech:

  • Chcete cílit na rozhraní API, která jsou k dispozici pouze v konkrétní verzi PowerShellu.
  • Nebudete v závislosti na typech, ke kterým dochází mimo System.Management.Automation sestavení (například typy exportované rutinami v Microsoft.PowerShell.* modulech).

Referenční sestavení prostředí Windows PowerShell

Pro PowerShell verze 5.1 a starší (Windows PowerShell) není k dispozici žádná sada SDK pro implementaci PowerShellu, protože implementace Prostředí Windows PowerShell je součástí Windows.

Místo toho referenční sestavení prostředí Windows PowerShell poskytují referenční cíle i způsob, jak změnit hostitele Prostředí Windows PowerShell, který funguje stejně jako sada PowerShell SDK pro verze 6 a vyšší.

Referenční sestavení Prostředí Windows PowerShell mají místo rozlišení podle verze jiný balíček pro každou verzi Windows PowerShellu:

Informace o tom, jak používat referenční sestavení prostředí Windows PowerShell, najdete v sadě Windows PowerShell SDK.

Příklady z reálného světa využívající tyto balíčky NuGet

Různé projekty nástrojů PowerShellu cílí na různé balíčky NuGet PowerShellu v závislosti na jejich potřebách. Tady jsou některé z nádůsných příkladů.

PSReadLine

PSReadLine, modul PowerShellu, který poskytuje většinu bohatého prostředí konzoly PowerShellu, cílí na PowerShell Standard jako na závislost místo konkrétní verze PowerShellu a cílí na net461 modul runtime .NET v jeho souboru csproj.

PowerShell 6 nebo novější dodává vlastní sestavení shim, která umožňují knihovně DLL, která cílí na net461 modul runtime, při načítání "jen pracovat" (přesměrováním vazby na příslušné sestavení . mscorlib.dll NET Core).

To zjednodušuje rozložení a doručování modulů PSReadLine výrazně, protože PowerShell Standard zajišťuje, že v PowerShellu 5.1 a PowerShellu 6+ budou k dispozici pouze používaná rozhraní API, a zároveň umožňuje dodávat modul pouze s jedním sestavením.

Cíl .NET 4.6.1 znamená, že Windows PowerShell spuštěný v .NET 4.5.2 a .NET 4.6 se ale nepodporuje.

PowerShell Editor Services

PowerShell Editor Services (PSES) je back-end pro rozšíření PowerShellu pro Visual Studio Code a ve skutečnosti je to forma modulu PowerShellu, který se načte spustitelným souborem PowerShellu a pak tento proces převezme, aby se powerShell přehostil uvnitř sebe, a zároveň poskytuje funkce protokolu jazykové služby a adaptéru ladění.

PsES poskytuje konkrétní cíle implementace pro netcoreapp2.1 cílení na PowerShell 6 nebo novější (protože modul runtime PowerShellu 7 netcoreapp3.1 je zpětně kompatibilní) a net461 cílí na Prostředí Windows PowerShell 5.1, ale obsahuje většinu logiky v druhém sestavení, které cílí netstandard2.0 a PowerShell Standard. To umožňuje načíst závislosti vyžadované pro platformy .NET Core a .NET Framework a zároveň zjednodušit většinu základu kódu za jednotným abstrakcí.

Vzhledem k tomu, že je sestavená s powershellovým standardem, psES vyžaduje, aby se správně otestovala implementace PowerShellu za běhu. K tomu psES xUnit testuje přijetí změn Microsoft.PowerShell.SDK a Microsoft.PowerShell.5.ReferenceAssemblies k zajištění implementace PowerShellu v testovacím prostředí.

Stejně jako u PSReadLine nemůže PSES podporovat .NET 4.6 a novější, ale provádí kontrolu za běhu před voláním některého z rozhraní API, která by mohla způsobit chybové ukončení v nižších modulech runtime rozhraní .NET Framework.

PSScriptAnalyzer

PSScriptAnalyzer, linter pro PowerShell, musí cílit na syntaktické prvky, které byly zavedeny pouze v určitých verzích PowerShellu. Vzhledem k tomu, že rozpoznávání těchto syntaktických elementů se provádí implementací astVisitor2, není možné použít PowerShellStandard a také implementovat metody návštěvníků AST pro novější syntaxe PowerShellu.

Místo toho PSScriptAnalyzer cílí na každou verzi PowerShellu jako konfiguraci sestavení a vytvoří samostatnou knihovnu DLL pro každou z nich. Tím se zvyšuje velikost sestavení a složitost, ale umožňuje:

  • Cílení na rozhraní API specifické pro konkrétní verze
  • Funkce specifické pro konkrétní verze, které se mají implementovat bez nákladů na modul runtime
  • Celková podpora prostředí Windows PowerShell až do rozhraní .NET Framework 4.5.2

Shrnutí

V tomto článku jsme uvedli a probrali balíčky NuGet, které jsou k dispozici pro cílení při implementaci projektu .NET, který používá PowerShell, a důvody pro použití mezi sebou.

Pokud jste se přeskočili na souhrn, jsou některá obecná doporučení:

  • Moduly PowerShellu by se měly zkompilovat proti PowerShellu Standard, pokud vyžadují pouze rozhraní API společná pro různé verze PowerShellu.
  • Hostitelé a aplikace PowerShellu, které potřebují spustit PowerShell interně, by měly cílit na sadu PowerShell SDK pro PowerShell 6 nebo odpovídající referenční sestavení prostředí Windows PowerShell pro Windows PowerShell.
  • Moduly PowerShellu, které potřebují rozhraní API specifické pro konkrétní verzi, by měly cílit na referenční sestavení sady PowerShell SDK nebo Prostředí Windows PowerShell pro požadované verze PowerShellu, které je používají jako referenční sestavení (to znamená, že nepublikují závislosti PowerShellu).