Volba 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, které implementují vlastní (binární moduly), je nezbytné, aby PowerShell byl 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 popisuje několik běžných scénářů pro projekty .NET zaměřené na PowerShell a způsob výběru správného balíčku NuGet 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 pwsh, powershell.exeintegrované konzoly PowerShellu nebo isE), zatímco jiní chtějí spustit PowerShell ve svých vlastních aplikacích.

  • Odkazování je určené, když se projekt, obvykle modul, má načíst 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 závislá konkrétní implementace PowerShellu. Vzhledem k tomu, že je potřeba použít konkrétní implementaci PowerShellu, je nutné zvolit konkrétní verzi PowerShellu pro hostování; Jedna hostitelská aplikace nemůže více cílových verzí PowerShellu.

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

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.

Aby se zabránilo 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 referenční sestavení jako cíl, mohou 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 NullReferenceException, protože referenční sestavení často napodobení rozhraní API implementace jednoduše vrací null.

Klíčové typy projektů powershellového cílení na .NET

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 RutinProvider , aby bylo možné vystavit rutiny nebo zprostředkovatele. Vzhledem k tomu, že jsou načtené, moduly se snaží zkompilovat odkazy 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 tématu about_Modules .

  • Implementace hostitele PowerShellu

    Hostitel PowerShellu poskytuje vrstvu interakce pro modul runtime PowerShellu. Jedná se o konkrétní formu hostování, kdy se psHost implementuje jako nové uživatelské rozhraní pro PowerShell. Konzola PowerShellu například poskytuje uživatelské rozhraní terminálu pro spustitelné soubory PowerShellu, zatímco hostitel služby Editor PowerShellu a hostitel ISE poskytují částečně grafické uživatelské rozhraní integrované v editoru 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 je možné PowerShell volat jako podproces ke spouštění úloh. Jako aplikace .NET je ale také možné vyvolat in-process PowerShellu, abyste získali úplné objekty .NET pro použití v rámci volající aplikace. Toto je obecnější forma hostování, kde aplikace obsahuje vlastní implementaci PowerShellu pro interní použití. Příkladem může být služba nebo démon, na kterém běží PowerShell pro správu stavu počítače nebo webové aplikace, která na vyžádání spouští PowerShell, aby mohla něco jako spravovat cloudová nasazení.

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

    Moduly a další knihovny navržené tak, aby zpřístupnily funkce PowerShellu, 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 pokouší cílit na řadu verzí PowerShellu, zatímco testování by mělo běžet na konkrétních konkrétních implementacích.

Balíčky NuGet PowerShellu na první pohled

V tomto článku se podíváme na následující 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, jak cílit a znovu hostovat celou sadu PowerShell SDK
  • Balíček System.Management.Automation , základní implementace modulu runtime a modulu PowerShellu, 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.
  • Windows PowerShell referenční sestavení, způsob, jak cílit a efektivně hostovat Windows PowerShell (PowerShell verze 5.1 a níže).

Poznámka

Balíček NuGet PowerShellu není vůbec balíček knihovny .NET, ale poskytuje globální implementaci nástroje PowerShell dotnet. Tento soubor by neměl 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 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í, PowerShell 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 modul runtime fasády navržený tak, aby poskytoval společnou povrchovou oblast 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:

  • PowerShell, který načítá modul nebo knihovnu, musí běžet minimálně na .NET 4.6.1; .NET 4.6 a .NET 4.5.2 nepodporuje .NET Standard. Všimněte si, že novější verze Windows PowerShell 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 prostředím PowerShell s rozhraním .NET Framework 4.7.1 nebo nižším, je potřeba implementovat .NET 4.6.1 NETStandard.Library , aby bylo možné poskytovat netstandard.dll a další sestavení shim ve starších verzích rozhraní .NET Framework.

PowerShell 6+ poskytuje vlastní sestavení pro přeposílá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+ načíst a spustit, když je vytvořený pro .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 pro net461 cílový modul runtime To zahrnuje:

    • Publikování projektu pro net461 modul runtime
    • Také kompiluje modul netstandard2.0 runtime (bez použití výstupu sestavení), aby se zajistilo, že se všechna použitá rozhraní API 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 Nebo knihovny PowerShellu, 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í se bude muset načíst v době načítání 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 v testovacích běžcích .NET, jako je xUnit, nezapomeňte, že kontroly času 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 powershellovém standardu v .NET, měli byste přidat Microsoft.Powershell.SDK jako testovací závislost s .NET Core (s verzí nastavenou tak, aby odpovídala požadované verzi PowerShellu) a odpovídající Windows PowerShell referenční sestavení s rozhraním .NET Framework.

Další informace o PowerShellu Standard a jeho použití k zápisu binárního modulu, který funguje ve více 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 metabalek, 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 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é se dají 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ím 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 start-job aktuálně závisí na dostupném spustitelném pwsh souboru, takže ve výchozím nastavení nebude fungovat Microsoft.Powershell.SDK .

Cílení Microsoft.Powershell.SDK z aplikace .NET umožňuje integrovat se všemi sestaveními implementace PowerShellu, jako jsou System.Management.Automation, a Microsoft.PowerShell.Managementdalší sestavení modulů.

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

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

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

Microsoft.PowerShell.SDK Může se také použít jako cíl odkazu, pokud je projekt .NET určený k použití jako modulu nebo jinak načtený PowerShellem, ale závisí na rozhraních API, která jsou k dispozici pouze v konkrétní verzi PowerShellu. Mějte na paměti, že sestavení publikované pro konkrétní verzi Microsoft.PowerShell.SDK bude bezpečné pouze pro načtení a použití v této verzi PowerShellu. Pokud chcete cílit na více verzí PowerShellu s konkrétními rozhraními API, vyžaduje se několik 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 zajistit ekvivalentní funkce s Windows PowerShell, použijte referenční sestavení Windows PowerShell popsaná níže.

System.Management.Automation

Balíček System.Management.Automation je jádrem sady PowerShell SDK. V NuGetu existuje především jako prostředek, který Microsoft.Powershell.SDK se má načíst. Dá se ale použít také 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ž:

  • Chcete používat 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 spustit pouze konkrétní příkazy Microsoft.PowerShell.Core a můžete je spustit ve stavu relace vytvořeném pomocí metody CreateDefault2 factory.

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

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

referenční sestavení Windows PowerShell

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

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

Místo rozlišení podle verze mají referenční sestavení Windows PowerShell jiný balíček pro každou verzi Windows PowerShell:

Informace o použití referenčních sestavení Windows PowerShell najdete v sadě Windows PowerShell SDK.

Příklady z reálného světa s využitím těchto balíčků 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ákladných příkladů.

PSReadLine

PSReadLine, modul PowerShellu, který poskytuje velkou část prostředí konzoly PowerShellu, cílí na PowerShell Standard jako na závislost, nikoli na konkrétní verzi PowerShellu, a cílí na net461 modul runtime .NET v jeho souboru csproj.

PowerShell 6 nebo novější poskytuje vlastní sestavení shim, která umožňují knihovně DLL, která při net461 načtení modulu runtime umožňují "pracovat" (přesměrováním vazby na rozhraní .NET Framework mscorlib.dll na příslušné sestavení .NET Core).

Tím se výrazně zjednodušuje rozložení a doručování modulů PSReadLine, 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é na .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 forma modulu PowerShellu, který se načte spustitelným souborem PowerShellu a pak převezme tento proces tak, aby znovu hostoval PowerShell 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+ (protože modul runtime PowerShellu 7 netcoreapp3.1 je zpětně kompatibilní) a net461 cíl Windows PowerShell 5.1, ale obsahuje většinu jeho logiky v druhém sestavení, které cílí netstandard2.0 a PowerShell Standard. To umožňuje načíst závislosti potřebné pro platformy .NET Core a .NET Framework, zatímco stále zjednodušuje většinu základu kódu za jednotným abstrakcí.

Vzhledem k tomu, že je sestavená pro PowerShell Standard, vyžaduje psES k otestování správné testování implementace modulu runtime PowerShellu. Provedete to tak, že testy xUnit psES načítá Microsoft.PowerShell.SDK a Microsoft.PowerShell.5.ReferenceAssemblies zajistí implementaci PowerShellu v testovacím prostředí.

Stejně jako u PSReadLine psES nepodporuje .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 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íka AST pro novější syntaxe PowerShellu.

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 a složitost sestavení, ale umožňuje:

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

Souhrn

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č je možné, že je potřeba použít jeden po druhém.

Pokud jste přeskočili do souhrnu, jsou některá obecná doporučení:

  • Moduly PowerShellu by se měly zkompilovat proti PowerShellu Standard, pokud vyžadují jenom rozhraní API běžná pro různé verze PowerShellu.
  • Hostitelé a aplikace PowerShellu, které potřebují používat PowerShell interně, by měly cílit na sadu PowerShell SDK pro PowerShell 6 nebo relevantní referenční sestavení Windows PowerShell pro Windows PowerShell.
  • Moduly PowerShellu, které potřebují rozhraní API specifické pro verzi, by měly cílit na sadu PowerShell SDK nebo Windows PowerShell referenční sestavení pro požadované verze PowerShellu, které je používají jako referenční sestavení (to znamená, že nepublikuje závislosti PowerShellu).