Udostępnij za pomocą


Wybieranie odpowiedniego pakietu NuGet programu PowerShell dla projektu platformy .NET

Oprócz pakietów wykonywalnych pwsh publikowanych w każdej wersji PowerShell, zespół PowerShell obsługuje również kilka pakietów dostępnych w NuGet. Te pakiety umożliwiają celowanie w PowerShell jako platformę API w .NET.

Jako aplikacja .NET, która udostępnia interfejsy API i oczekuje załadowania bibliotek platformy .NET implementujących własne (moduły binarne), ważne jest, aby program PowerShell był dostępny w postaci pakietu NuGet.

Obecnie istnieje kilka pakietów NuGet, które zapewniają pewną reprezentację obszaru powierzchni interfejsu API programu PowerShell. Który pakiet użyć przy konkretnym projekcie, nie zawsze było jasno określone. W tym artykule omówiono kilka typowych scenariuszy dotyczących projektów platformy .NET przeznaczonych dla programu PowerShell oraz sposób wybierania odpowiedniego pakietu NuGet przeznaczonego dla projektu platformy .NET zorientowanego na program PowerShell.

Hosting vs referencje

Niektóre projekty platformy .NET starają się napisać kod, który ma zostać załadowany do istniejącego środowiska uruchomieniowego programu PowerShell (na przykład pwsh, powershell.exe, zintegrowanej konsoli programu PowerShell lub środowiska ISE), podczas gdy inne chcą uruchomić program PowerShell we własnych aplikacjach.

  • odwołanie do jest używane, gdy projekt, zazwyczaj moduł, jest przeznaczony do załadowania do programu PowerShell. Należy go skompilować przy użyciu interfejsów API udostępnianych przez program PowerShell, aby umożliwić interakcję z nim, ale implementacja programu PowerShell jest zapewniana przez proces, który ładuje go w ramach programu PowerShell. Przy odwoływaniu się do projektu można użyć zestawów odwołań lub rzeczywistych zestawów środowiska uruchomieniowego jako celu kompilacji, ale należy upewnić się, że żaden z nich nie zostanie opublikowany podczas tworzenia.
  • Hosting ma miejsce wtedy, gdy projekt potrzebuje własnej implementacji programu PowerShell, zwykle dlatego, że jest to niezależna aplikacja, która potrzebuje uruchamiania programu PowerShell. W tym przypadku nie można używać czystych zestawów odwołań. Zamiast tego należy zależeć od konkretnej implementacji programu PowerShell. Ponieważ należy użyć konkretnej implementacji programu PowerShell, należy wybrać określoną wersję programu PowerShell do hostowania; pojedyncza aplikacja hosta nie może obsługiwać wielu docelowych wersji programu PowerShell.

Publikowanie projektów, które traktują PowerShell jako wzorzec

Notatka

Używamy terminu publikować w tym artykule, aby odnosić się do uruchamiania dotnet publish, które umieszcza bibliotekę platformy .NET w katalogu ze wszystkimi jej zależnościami. Jest gotowa do wdrożenia w określonym środowisku uruchomieniowym.

Aby zapobiec publikowaniu zależności projektu, które są używane tylko jako obiekty docelowe odwołania kompilacji, zaleca się ustawienie atrybutu PrivateAssets:

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

Jeśli zapomnisz to zrobić i użyjesz zestawu referencyjnego jako docelowego, mogą wystąpić problemy związane z używaniem domyślnej implementacji zestawu referencyjnego zamiast rzeczywistej implementacji. Może to mieć formę NullReferenceException, ponieważ zestawy referencyjne często wyśmiewają interfejs API implementacji, po prostu zwracając null.

Kluczowe rodzaje projektów platformy .NET przeznaczonych dla programu PowerShell

Chociaż dowolna biblioteka lub aplikacja platformy .NET może osadzić program PowerShell, istnieje kilka typowych scenariuszy korzystających z interfejsów API programu PowerShell:

  • implementowanie modułu binarnego programu PowerShell

    Moduły binarne programu PowerShell to biblioteki platformy .NET ładowane przez program PowerShell, które muszą implementować API PowerShell, takie jak typy PSCmdlet lub CmdletProvider, aby odpowiednio udostępnić cmdlety lub dostawców. Ponieważ są ładowane, moduły próbują kompilować względem odniesień do programu PowerShell bez publikowania ich w swojej kompilacji. Często zdarza się również, że moduły chcą obsługiwać wiele wersji i platform programu PowerShell, najlepiej z minimalnym obciążeniem miejsca na dysku, złożonością lub powtarzaną implementacją. Aby uzyskać więcej informacji na temat modułów, zobacz about_Modules.

  • wdrażanie hosta programu PowerShell

    Host programu PowerShell udostępnia warstwę interakcji dla środowiska uruchomieniowego programu PowerShell. Jest to konkretna forma hostowania , w której PSHost jest implementowany jako nowy interfejs użytkownika do PowerShell. Na przykład konsola programu PowerShell ConsoleHost udostępnia interfejs użytkownika terminalu dla plików wykonywalnych programu PowerShell, a host usług Edytora programu PowerShell i host ISE zapewniają częściowo graficzny interfejs użytkownika zintegrowany z edytorem wokół programu PowerShell. Chociaż istnieje możliwość załadowania hosta do istniejącego procesu programu PowerShell, implementacja hosta najczęściej działa jako samodzielna wersja programu PowerShell, która redystrybuuje mechanizm PowerShell.

  • Wywoływanie PowerShell z innej aplikacji .NET

    Podobnie jak w przypadku dowolnej aplikacji, program PowerShell może być wywoływany jako podproces do uruchamiania obciążeń. Jednak jako aplikacja .NET można również wywołać PowerShell w procesie, aby uzyskać pełne obiekty .NET do użycia w aplikacji wywołującej. To bardziej ogólna forma hostowania , gdzie aplikacja posiada własną implementację PowerShell na potrzeby wewnętrzne. Przykładem może być usługa lub demon z uruchomionym programem PowerShell do zarządzania stanem komputera lub aplikacją internetową, która uruchamia program PowerShell na żądanie, aby wykonać operacje zarządzania wdrożeniami w chmurze.

  • Jednostkowe testowanie modułów PowerShell w .NET

    Moduły i inne biblioteki przeznaczone do uwidaczniania funkcji programu PowerShell powinny być testowane głównie z poziomu programu PowerShell (zalecamy Pester), ale czasami konieczne jest przetestowanie interfejsów API testów jednostkowych napisanych dla modułu programu PowerShell z platformy .NET. Taka sytuacja dotyczy kodu modułu, który stara się obsługiwać różne wersje PowerShell, podczas gdy testy powinny być wykonywane na określonych, konkretnych implementacjach.

Pakiety NuGet programu PowerShell w skrócie

W tym artykule omówimy następujące pakiety NuGet, które uwidaczniają interfejsy API programu PowerShell:

  • powerShellStandard.Library, zestaw referencyjny, który umożliwia tworzenie pojedynczego zestawu, który może zostać załadowany przez wiele środowisk uruchomieniowych programu PowerShell.
  • Microsoft.PowerShell.SDK, sposób na kierowanie i ponowne hostowanie całego PowerShell SDK
  • Pakiet System.Management.Automation, podstawowy runtime i implementacja silnika PowerShell, które mogą być przydatne w minimalnych implementacjach hostowanych oraz w scenariuszach ukierunkowanych na konkretne wersje.
  • Zestawy referencyjne programu Windows PowerShell , metoda ukierunkowania i wydajnego przehostowania programu Windows PowerShell (wersje PowerShell 5.1 i starsze).

Notatka

Pakiet NuGet programu PowerShell nie jest wcale pakietem biblioteki .NET, lecz zapewnia implementację globalnego narzędzia dotnet dla PowerShell. Nie powinno być ono używane przez żadne projekty, ponieważ udostępnia tylko plik wykonywalny.

PowerShellStandard.Library

Biblioteka PowerShell Standard to zestaw referencyjny, który określa wspólne elementy interfejsów API wersji 7, 6 i 5.1 programu PowerShell. Zapewnia to weryfikowaną podczas kompilacji powierzchnię API, aby kompilować kod .NET, pozwalając projektom .NET na celowanie w wersje PowerShell 7, 6 i 5.1 bez ryzyka wywołania API, które nie istnieje.

Program PowerShell Standard jest przeznaczony do pisania modułów programu PowerShell lub innego kodu przeznaczonego tylko do uruchomienia po załadowaniu go do procesu programu PowerShell. Ponieważ jest to zestaw referencyjny, program PowerShell Standard nie zawiera samej implementacji, dlatego nie zapewnia funkcji dla aplikacji autonomicznych.

Używanie PowerShell Standard z różnymi środowiskami uruchomieniowymi platformy .NET

PowerShell Standard jest przeznaczony dla docelowego środowiska uruchomieniowego .NET Standard 2.0, które jest środowiskiem uruchomieniowym typu fasada, zaprojektowanym w celu zapewnienia wspólnego interfejsu dla platform .NET Framework oraz .NET Core. Pozwala to na utworzenie pojedynczego środowiska uruchomieniowego w celu utworzenia pojedynczego zestawu, który będzie działać z wieloma wersjami programu PowerShell, ale ma następujące konsekwencje:

  • Program PowerShell ładujący moduł lub bibliotekę musi działać co najmniej na platformie .NET 4.6.1; .NET 4.6 i .NET 4.5.2 nie obsługują platformy .NET Standard. Należy pamiętać, że nowsza wersja programu Windows PowerShell nie oznacza nowszej wersji programu .NET Framework; Program Windows PowerShell 5.1 może działać na platformie .NET 4.5.2.
  • Aby można było pracować z programem PowerShell z uruchomionym programem .NET Framework 4.7.1 lub starszym, implementacja platformy .NET 4.6.1 NETStandard. Library jest wymagana do zapewnienia netstandard.dll i innych zestawów podkładek dla starszych wersji programu .NET Framework.

Program PowerShell 6+ udostępnia własne zestawy warstw pośrednich do przekierowywania typów z .NET Framework 4.6.1 (i nowszych) do platformy .NET Core. Oznacza to, że tak długo, jak moduł używa tylko interfejsów API, które istnieją na platformie .NET Core, program PowerShell 6+ może załadować i uruchomić go, gdy został utworzony dla programu .NET Framework 4.6.1 (obiekt docelowy środowiska uruchomieniowego net461).

Oznacza to, że moduły binarne używające standardu PowerShell do obsługi wielu wersji tego programu za pomocą jednej opublikowanej biblioteki DLL mają dwie opcje:

  1. Publikowanie zestawu utworzonego dla docelowego środowiska uruchomieniowego net461. Obejmuje to:

    • Publikowanie projektu dla środowiska uruchomieniowego net461
    • Ponadto kompilowanie dla środowiska uruchomieniowego netstandard2.0 (bez używania wyników kompilacji), aby upewnić się, że wszystkie używane interfejsy API są również obecne na platformie .NET Core.
  2. Publikowanie kompilacji zestawu dla docelowego środowiska uruchomieniowego netstandard2.0. Wymaga to:

    • Publikowanie projektu dla środowiska uruchomieniowego netstandard2.0
    • Pobranie net461 zależności z biblioteki NETStandard.Library i skopiowanie ich do lokalizacji publikowania zestawu projektu, aby przekierowanie typów w programie .NET Framework było wykonane poprawnie.

Aby utworzyć moduły lub biblioteki programu PowerShell przeznaczone dla starszych wersji programu .NET Framework, preferowane może być kierowanie wielu środowisk uruchomieniowych platformy .NET. Spowoduje to opublikowanie zestawu dla każdego docelowego środowiska uruchomieniowego, a prawidłowy zestaw będzie musiał zostać załadowany w czasie ładowania modułu (na przykład z małym psm1 jako modułem głównym).

Testowanie projektów PowerShell Standard na platformie .NET

Gdy chodzi o testowanie modułu w narzędziach do uruchamiania testów platformy .NET, takich jak xUnit, pamiętaj, że sprawdzenia czasu kompilacji mogą zapewnić tylko ograniczoną ochronę. Moduł należy przetestować na odpowiednich platformach programu PowerShell.

Aby przetestować interfejsy API utworzone przy użyciu programu PowerShell Standard na platformie .NET, należy dodać Microsoft.PowerShell.SDK jako zależność testowania z platformą .NET Core (z wersją ustawioną tak, aby odpowiadała żądanej wersji programu PowerShell) oraz odpowiednie zestawy odwołań środowiska Windows PowerShell za pomocą programu .NET Framework.

Aby uzyskać więcej informacji na temat PowerShell Standard i używania go do pisania modułu binarnego działającego w wielu wersjach PowerShell, zobacz ten wpis na blogu. Zobacz także repozytorium PowerShell Standard na GitHubie.

Microsoft.PowerShell.SDK

Microsoft.PowerShell.SDK to metapakiet, który łączy wszystkie składniki zestawu SDK programu PowerShell w jeden pakiet NuGet. Samodzielna aplikacja .NET może używać zestawu Microsoft.PowerShell.SDK do uruchamiania dowolnych funkcji programu PowerShell bez względu na zewnętrzne instalacje lub biblioteki programu PowerShell.

Notatka

Zestaw SDK programu PowerShell odnosi się tylko do wszystkich pakietów składników tworzących program PowerShell i które mogą być używane do programowania na platformie .NET za pomocą programu PowerShell.

Dana wersja Microsoft.PowerShell.SDK zawiera konkretną implementację tej samej wersji aplikacji programu PowerShell; Wersja 7.0 zawiera implementację programu PowerShell 7.0 i uruchamianie poleceń lub skryptów z nim będzie w dużej mierze zachowywać się tak, jakby działały w programie PowerShell 7.0.

Uruchamianie poleceń programu PowerShell z zestawu SDK jest w dużej mierze takie samo, ale nie całkowicie, jak uruchamianie ich z pwsh. Na przykład Start-Job jest obecnie zależny od dostępności pliku wykonywalnego pwsh, dlatego nie będzie działać z Microsoft.PowerShell.SDK domyślnie.

Określanie wartości docelowej Microsoft.PowerShell.SDK z poziomu aplikacji .NET umożliwia integrację ze wszystkimi zestawami implementacji programu PowerShell, takimi jak System.Management.Automation, Microsoft.PowerShell.Managementi inne zestawy modułów.

Publikowanie aplikacji przeznaczonej dla Microsoft.PowerShell.SDK uwzględnia wszystkie te biblioteki oraz wszelkie zależności wymagane przez PowerShell. Będzie również zawierać inne zasoby wymagane przez program PowerShell podczas budowy, takie jak manifesty modułów dla modułów Microsoft.PowerShell.* i katalog ref wymagany przez Add-Type.

Ze względu na kompletność Microsoft.PowerShell.SDK, najlepiej nadaje się do:

  • Implementacja hostów programu PowerShell.
  • Testowanie bibliotek xUnit dla zestawów referencyjnych programu PowerShell.
  • Wywoływanie programu PowerShell w procesie z poziomu aplikacji .NET.

Microsoft.PowerShell.SDK może być również używany jako cel odwołania, gdy projekt .NET ma być używany jako moduł lub w inny sposób ładowany przez PowerShell, ale zależy od API obecnego tylko w konkretnej wersji PowerShell. Należy pamiętać, że zestaw opublikowany dla określonej wersji Microsoft.PowerShell.SDK będzie bezpieczny tylko do załadowania i użycia w tej wersji programu PowerShell. Aby uwzględnić wiele wersji programu PowerShell z określonymi interfejsami API, wymagane są różne kompilacje, z których każda jest dostosowana do swojej wersji Microsoft.PowerShell.SDK.

Notatka

Zestaw POWERShell SDK jest dostępny tylko dla programu PowerShell w wersji 6 i nowszej. Aby zapewnić równoważne funkcje programu Windows PowerShell, użyj zestawów referencyjnych programu Windows PowerShell opisanych poniżej.

System.Management.Automation

Pakiet System.Management.Automation jest sercem zestawu PowerShell SDK. Istnieje on przede wszystkim na NuGet, jako zasób do ściągnięcia dla Microsoft.PowerShell.SDK. Można go jednak również używać bezpośrednio jako pakiet dla mniej skomplikowanych scenariuszy hostowania i modułów dopasowanych do konkretnych wersji.

W szczególności pakiet System.Management.Automation może być preferowanym dostawcą funkcji programu PowerShell, gdy:

  • Chcesz używać tylko funkcji języka programu PowerShell (w przestrzeni nazw System.Management.Automation.Language), takiej jak analizator programu PowerShell, AST i interfejsy API odwiedzających AST (na przykład w przypadku statycznej analizy programu PowerShell).
  • Chcesz tylko wykonać określone polecenia z modułu Microsoft.PowerShell.Core i wykonać je w stanie sesji utworzonym za pomocą metody CreateDefault2 factory.

Ponadto System.Management.Automation jest przydatnym zestawem referencyjnym w następujących przypadkach:

  • Zamierzasz celować w interfejsy API, które są obecne tylko w określonej wersji programu PowerShell.
  • Nie będziesz zależeć od typów występujących poza zestawem System.Management.Automation (na przykład typów eksportowanych przez polecenia cmdlet w modułach Microsoft.PowerShell.*).

Zestawy referencyjne programu Windows PowerShell

W przypadku programu PowerShell w wersji 5.1 lub starszej (Windows PowerShell) nie ma zestawu SDK do zapewnienia implementacji programu PowerShell, ponieważ implementacja programu Windows PowerShell jest częścią systemu Windows.

Zamiast tego zestawy odwołań środowiska Windows PowerShell udostępniają obiekty docelowe odwołań i sposób ponownego hostowania programu Windows PowerShell, działając tak samo jak zestaw SDK programu PowerShell dla wersji 6 i nowszych.

Zamiast rozróżniać wersję, zestawy odwołań programu Windows PowerShell mają inny pakiet dla każdej wersji programu Windows PowerShell:

Informacje o sposobie korzystania z zestawów odniesienia Windows PowerShell można znaleźć w Windows PowerShell SDK.

Rzeczywiste przykłady użycia tych pakietów NuGet

Różne projekty narzędzi programu PowerShell są przeznaczone dla różnych pakietów NuGet programu PowerShell w zależności od ich potrzeb. Poniżej wymieniono kilka godnych uwagi przykładów.

PSReadLine (Linia PSReadLine)

PSReadLine, moduł programu PowerShell, który zapewnia bogate możliwości konsoli programu PowerShell, jest precyzowany jako zależność w standardzie PowerShell Standard, zamiast konkretnej wersji programu PowerShell, oraz celuje w środowisko uruchomieniowe .NET net461 w swoim pliku csproj.

Program PowerShell 6+ dostarcza własne zestawy pośredniczące, które umożliwiają bibliotekom DLL przeznaczonym dla środowiska net461 działać bezproblemowo podczas ładowania, przekierowując powiązania z mscorlib.dll programu .NET Framework do odpowiedniego zestawu platformy .NET Core.

Upraszcza to znacznie układ modułu i dostarczanie modułu PSReadLine, ponieważ program PowerShell Standard zapewnia, że jedyne używane interfejsy API będą obecne zarówno w programie PowerShell 5.1, jak i programie PowerShell 6 lub nowszym, a jednocześnie umożliwia dostarczanie modułu tylko z jednym zestawem.

Docelowa wersja .NET 4.6.1 oznacza, że program Windows PowerShell uruchomiony na platformie .NET 4.5.2 i .NET 4.6 nie jest obsługiwany.

Usługi edytora programu PowerShell

Usługi edytora programu PowerShell (PSES) stanowią zaplecze rozszerzenia programu PowerShell dla programu Visual Studio Code. Jest to w rzeczywistości forma modułu programu PowerShell, który jest ładowany przez plik wykonywalny programu PowerShell i przejmuje ten proces, aby ponownie hostować PowerShell w jego środowisku, zapewniając jednocześnie funkcje protokołu usług językowych i adaptera debugowania.

Program PSES zapewnia konkretne cele implementacji dla netcoreapp2.1 przeznaczone dla programu PowerShell 6+ (ponieważ środowisko uruchomieniowe netcoreapp3.1 programu PowerShell 7 jest zgodne z poprzednimi wersjami) i net461 aby celować w Windows PowerShell 5.1, ale zawiera większość jej logiki w drugim zestawie przeznaczonym dla netstandard2.0 i programu PowerShell Standard. Dzięki temu możliwe jest włączanie zależności wymaganych dla platform .NET Core i .NET Framework, przy jednoczesnym upraszczaniu większości bazy kodu poprzez jednolitą abstrakcję.

Ponieważ jest zbudowana w oparciu o PowerShell Standard, PSES wymaga implementacji środowiska wykonawczego PowerShell, aby zostać poprawnie przetestowana. W tym celu testy xUnit PSES ściągają Microsoft.PowerShell.SDK i Microsoft.PowerShell.5.ReferenceAssemblies w celu zapewnienia implementacji programu PowerShell w środowisku testowym.

Podobnie jak w przypadku programu PSReadLine program PSES nie może obsługiwać platformy .NET 4.6 lub starszej, ale wykonuje sprawdzanie w czasie wykonywania przed wywołaniem dowolnego z interfejsów API, które mogą spowodować awarię w niższych środowiskach uruchomieniowych programu .NET Framework.

PSScriptAnalyzer

PSScriptAnalyzer, linter dla programu PowerShell, powinien obejmować elementy składniowe wprowadzone tylko w niektórych wersjach programu PowerShell. Ponieważ rozpoznawanie tych elementów składniowych jest realizowane przez zaimplementowanie AstVisitor2, nie można użyć PowerShellStandard ani zaimplementować metod odwiedzających AST dla nowszych składni PowerShell.

Zamiast tego PSScriptAnalyzer celuje w każdą wersję PowerShell jako osobną konfigurację kompilacji i tworzy oddzielną bibliotekę DLL dla każdej z nich. Zwiększa to rozmiar kompilacji i złożoność, ale umożliwia:

  • Ukierunkowanie interfejsu API na określoną wersję
  • Funkcje specyficzne dla wersji, które mają być implementowane przy praktycznie zerowych kosztach czasu wykonania
  • Łączna obsługa programu Windows PowerShell aż do programu .NET Framework 4.5.2

Streszczenie

W tym artykule wymieniliśmy i omówiliśmy pakiety NuGet dostępne do użycia przy implementacji projektu .NET, który korzysta z PowerShell, oraz powody, dla których można wybrać jeden z nich nad innymi.

Jeśli pominięto podsumowanie, niektóre szerokie zalecenia to:

  • Moduły programu PowerShell powinny być kompilowane zgodnie ze standardem PowerShell Standard, jeśli wymagają tylko interfejsów API wspólnych dla różnych wersji PowerShell.
  • Hosty i aplikacje programu PowerShell , które muszą wewnętrznie uruchamiać program PowerShell, powinny celować w SDK PowerShell dla PowerShell 6+ lub odpowiednie zestawy referencyjne Windows PowerShell dla Windows PowerShell.
  • Moduły programu PowerShell, które wymagają interfejsów API specyficznych dla wersji, powinny być przeznaczone dla zestawów odwołań programu PowerShell lub środowiska Windows PowerShell dla wymaganych wersji programu PowerShell, używając ich jako zestawów referencyjnych (czyli nie publikowania zależności programu PowerShell).