Bagikan melalui


Memilih paket PowerShell NuGet yang tepat untuk proyek .NET Anda

Bersama dengan paket pwsh yang dapat dieksekusi yang diterbitkan dengan setiap rilis PowerShell, tim PowerShell juga mempertahankan beberapa paket yang tersedia di NuGet. Paket ini memungkinkan penargetan PowerShell sebagai platform API di .NET.

Sebagai aplikasi .NET yang menyediakan API dan mengharapkan untuk memuat pustaka .NET yang mengimplementasikan sendiri (modul biner), sangat penting bahwa PowerShell tersedia dalam bentuk paket NuGet.

Saat ini ada beberapa paket NuGet yang menyediakan beberapa representasi area permukaan API PowerShell. Paket mana yang akan digunakan dengan proyek tertentu belum selalu diperjelas. Artikel ini menjelaskan beberapa skenario umum untuk proyek .NET yang menargetkan PowerShell dan cara memilih paket NuGet yang tepat untuk ditargetkan untuk proyek .NET berorientasi PowerShell Anda.

Hosting vs referensi

Beberapa proyek .NET berusaha menulis kode untuk dimuat ke dalam runtime PowerShell yang sudah ada sebelumnya (seperti pwsh, powershell.exe, Konsol Terintegrasi PowerShell atau ISE), sementara yang lain ingin menjalankan PowerShell di aplikasi mereka sendiri.

  • Referensi digunakan saat proyek, biasanya modul, dirancang untuk dimuat ke dalam PowerShell. Ini harus dikompilasikan dengan API yang disediakan PowerShell untuk berinteraksi dengannya, tetapi implementasi PowerShell disediakan oleh proses PowerShell yang memuatnya. Untuk referensi, proyek dapat menggunakan rakitan referensi atau rakitan runtime aktual sebagai target kompilasi, tetapi harus memastikan bahwa proyek tersebut tidak menerbitkan rakitan-rakitan ini bersama hasil build-nya.
  • Hosting adalah ketika proyek membutuhkan implementasi PowerShell sendiri, biasanya karena ini adalah aplikasi mandiri yang perlu menjalankan PowerShell. Dalam hal ini, rakitan referensi murni tidak dapat digunakan. Sebaliknya, implementasi PowerShell konkret harus diandalkan. Karena implementasi PowerShell konkret harus digunakan, versi PowerShell tertentu harus dipilih untuk menjadi host; satu aplikasi host tidak dapat menargetkan berbagai versi PowerShell.

Menerbitkan proyek yang menargetkan PowerShell sebagai referensi

Nota

Kami menggunakan istilah menerbitkan dalam artikel ini untuk merujuk pada menjalankan dotnet publish, yang menempatkan pustaka .NET ke dalam direktori dengan semua dependensinya, siap untuk implementasi ke runtime tertentu.

Untuk mencegah dependensi proyek penerbitan yang hanya digunakan sebagai target referensi kompilasi, disarankan untuk mengatur atribut PrivateAssets:

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

Jika Anda lupa melakukan ini dan menggunakan assembly referensi sebagai target Anda, Anda mungkin akan melihat masalah yang terkait dengan penggunaan implementasi bawaan dari assembly referensi alih-alih dari implementasi aktual. Ini mungkin berbentuk NullReferenceException, karena rakitan referensi sering meniru API implementasi hanya dengan mengembalikan null.

Jenis utama proyek .NET yang menargetkan PowerShell

Meskipun pustaka atau aplikasi .NET apa pun dapat menyematkan PowerShell, ada beberapa skenario umum yang menggunakan API PowerShell:

  • Menerapkan modul biner PowerShell

    Modul biner PowerShell adalah pustaka .NET yang dimuat oleh PowerShell yang harus menerapkan API PowerShell seperti tipe PSCmdlet atau CmdletProvider untuk memaparkan cmdlet atau penyedia masing-masing. Karena dimuat, modul berusaha mengkompilasi terhadap referensi ke PowerShell tanpa menerbitkannya dalam build mereka. Adalah umum bagi modul untuk mendukung beberapa versi dan platform PowerShell, idealnya dengan overhead seminimal mungkin pada ruang disk, kompleksitas, atau implementasi berulang. Lihat about_Modules untuk informasi selengkapnya tentang modul.

  • Menerapkan Host PowerShell

    Host PowerShell menyediakan lapisan interaksi untuk runtime PowerShell. Ini adalah bentuk spesifik dari hosting, di mana PSHost diimplementasikan sebagai antarmuka pengguna baru ke PowerShell. Misalnya, PowerShell ConsoleHost menyediakan antarmuka pengguna terminal untuk program PowerShell, sementara Host Layanan Editor PowerShell dan Host ISE menyediakan antarmuka pengguna grafis parsial yang terintegrasi dengan editor untuk PowerShell. Meskipun dimungkinkan untuk memuat host ke proses PowerShell yang ada, jauh lebih umum bagi implementasi host untuk bertindak sebagai implementasi PowerShell mandiri yang mendistribusikan ulang mesin PowerShell.

  • Memanggil PowerShell dari aplikasi .NET lain

    Seperti halnya aplikasi apa pun, PowerShell dapat dipanggil sebagai sub-proses untuk menjalankan beban kerja. Namun, sebagai aplikasi .NET, dimungkinkan juga untuk memanggil PowerShell dalam proses untuk mendapatkan kembali objek .NET penuh untuk digunakan dalam aplikasi panggilan. Ini adalah bentuk yang lebih umum dari hosting, di mana aplikasi memegang implementasi PowerShell sendiri untuk penggunaan internal. Contohnya mungkin layanan atau daemon yang menjalankan PowerShell untuk mengelola status mesin atau aplikasi web yang menjalankan PowerShell berdasarkan permintaan untuk melakukan sesuatu seperti mengelola penyebaran cloud.

  • Unit yang menguji modul PowerShell dari .NET

    Meskipun modul dan pustaka lain yang dirancang untuk mengekspos fungsionalitas ke PowerShell sebaiknya diuji terutama dari PowerShell (kami merekomendasikan Pester), terkadang perlu untuk melakukan pengujian unit terhadap API yang ditulis untuk modul PowerShell melalui .NET. Situasi ini melibatkan kode modul yang mencoba menargetkan sejumlah versi PowerShell, sementara pengujian harus menjalankannya pada implementasi konkret tertentu.

Paket PowerShell NuGet Sekilas Pandang

Dalam artikel ini, kita akan membahas paket NuGet berikut yang mengekspos API PowerShell:

  • PowerShellStandard.Library, rakitan referensi yang memungkinkan pembuatan satu rakitan yang dapat dimuat oleh beberapa runtime PowerShell.
  • Microsoft.PowerShell.SDK, cara untuk menargetkan dan menghosting ulang seluruh PowerShell SDK
  • Paket System.Management.Automation, runtime dan implementasi mesin PowerShell inti, yang dapat berguna dalam implementasi yang dihosting minimal dan untuk skenario penargetan khusus versi.
  • Rakitan referensi Windows PowerShell , cara untuk menargetkan dan secara efektif menghosting ulang Windows PowerShell (PowerShell versi 5.1 ke bawah).

Nota

Paket PowerShell NuGet sama sekali bukan paket pustaka .NET, tetapi sebaliknya menyediakan implementasi alat global PowerShell dotnet. Ini tidak boleh digunakan oleh proyek apa pun, karena hanya menyediakan executable.

PowerShellStandard.Library

Pustaka PowerShell Standard adalah rakitan referensi yang menangkap persimpangan API PowerShell versi 7, 6, dan 5.1. Ini menyediakan lapisan API yang diperiksa saat waktu kompilasi untuk mengkompilasi kode .NET, memungkinkan proyek .NET menargetkan PowerShell versi 7, 6, dan 5.1 tanpa berisiko memanggil API yang tidak tersedia.

PowerShell Standard ditujukan untuk menulis modul PowerShell, atau kode lain hanya dimaksudkan untuk dijalankan setelah memuatnya ke dalam proses PowerShell. Karena ini adalah rakitan referensi, PowerShell Standard tidak berisi implementasi itu sendiri, jadi tidak menyediakan fungsionalitas untuk aplikasi mandiri.

Menggunakan PowerShell Standard dengan runtime .NET yang berbeda

PowerShell Standard menargetkan runtime target .NET Standard 2.0, yang merupakan runtime fasad yang dirancang untuk menyediakan area permukaan bersama untuk .NET Framework dan .NET Core. Hal ini memungkinkan penargetan satu runtime untuk menghasilkan satu rakitan yang akan berfungsi dengan beberapa versi PowerShell, tetapi memiliki konsekuensi berikut:

  • PowerShell yang memuat modul atau pustaka harus menjalankan minimal .NET 4.6.1; .NET 4.6 dan .NET 4.5.2 tidak mendukung .NET Standard. Perhatikan bahwa versi Windows PowerShell yang lebih baru tidak berarti versi .NET Framework yang lebih baru; Windows PowerShell 5.1 dapat berjalan pada .NET 4.5.2.
  • Untuk bekerja dengan PowerShell yang menjalankan .NET Framework 4.7.1 atau di bawahnya, implementasi .NET 4.6.1 NETStandard.Library diperlukan untuk menyediakan netstandard.dll dan rakitan shim lainnya dalam versi .NET Framework yang lebih lama.

PowerShell 6+ menyediakan rakitan shim sendiri untuk penerusan tipe dari .NET Framework 4.6.1 (dan yang lebih tinggi) ke .NET Core. Ini berarti bahwa selama modul hanya menggunakan API yang ada di .NET Core, PowerShell 6+ dapat memuat dan menjalankannya ketika telah dibangun untuk .NET Framework 4.6.1 (target runtime net461).

Ini berarti bahwa modul biner menggunakan PowerShell Standard untuk menargetkan beberapa versi PowerShell dengan satu DLL yang diterbitkan memiliki dua opsi:

  1. Menerbitkan rakitan yang dibuat untuk runtime target net461. Ini melibatkan:

    • Menerbitkan proyek untuk runtime net461
    • Juga melakukan kompilasi terhadap runtime netstandard2.0 (tanpa menggunakan hasil build) untuk memastikan bahwa semua API yang digunakan juga ada di .NET Core.
  2. Menerbitkan build assembly untuk netstandard2.0 target runtime. Ini memerlukan:

    • Menerbitkan proyek untuk runtime netstandard2.0
    • Mengambil dependensi net461 NETStandard.Library dan menyalinnya ke lokasi publikasi rakitan proyek sehingga rakitan tersebut diteruskan dengan tipe yang benar dalam .NET Framework.

Untuk membangun modul atau pustaka PowerShell yang menargetkan versi .NET Framework yang lebih lama, mungkin lebih baik menargetkan beberapa runtime .NET. Ini akan menerbitkan rakitan untuk setiap runtime target, dan rakitan yang benar perlu dimuat pada waktu pemuatan modul (misalnya dengan psm1 kecil sebagai modul akar).

Menguji proyek PowerShell Standard di .NET

Saat menguji modul Anda di runner pengujian .NET seperti xUnit, ingatlah bahwa pemeriksaan waktu kompilasi hanya dapat dilakukan sampai batas tertentu. Anda harus menguji modul Anda terhadap platform PowerShell yang relevan.

Untuk menguji API yang dibangun terhadap PowerShell Standard di .NET, Anda harus menambahkan Microsoft.Powershell.SDK sebagai dependensi pengujian dengan .NET Core (dengan versi yang diatur agar sesuai dengan versi PowerShell yang diinginkan), dan rakitan referensi Windows PowerShell yang sesuai dengan .NET Framework.

Untuk informasi selengkapnya tentang PowerShell Standard dan menggunakannya untuk menulis modul biner yang berfungsi di beberapa versi PowerShell, lihat posting blog ini. Lihat juga repositori PowerShell Standard di GitHub.

Microsoft.PowerShell.SDK

Microsoft.PowerShell.SDK adalah paket meta yang menggabungkan semua komponen PowerShell SDK ke dalam satu paket NuGet. Aplikasi .NET mandiri dapat menggunakan Microsoft.PowerShell.SDK untuk menjalankan fungsionalitas PowerShell arbitrer tanpa bergantung pada instalasi atau pustaka PowerShell eksternal apa pun.

Nota

PowerShell SDK hanya mengacu pada semua paket komponen yang membentuk PowerShell, dan yang dapat digunakan untuk pengembangan .NET dengan PowerShell.

Versi Microsoft.Powershell.SDK tertentu berisi implementasi konkret dari versi aplikasi PowerShell yang sama; versi 7.0 berisi implementasi PowerShell 7.0 dan menjalankan perintah atau skrip dengannya sebagian besar akan berulah seperti menjalankannya di PowerShell 7.0.

Menjalankan perintah PowerShell dari SDK sebagian besar, tetapi tidak sepenuhnya, sama dengan menjalankannya dari pwsh. Misalnya, Start-Job saat ini bergantung pada pwsh yang dapat dieksekusi yang tersedia, sehingga tidak akan berfungsi dengan Microsoft.Powershell.SDK secara default.

Menargetkan Microsoft.Powershell.SDK dari aplikasi .NET memungkinkan Anda untuk berintegrasi dengan semua rakitan implementasi PowerShell, seperti System.Management.Automation, Microsoft.PowerShell.Management, dan rakitan modul lainnya.

Menerbitkan aplikasi yang menargetkan Microsoft.Powershell.SDK akan menyertakan semua assembly ini, serta dependensi yang diperlukan oleh PowerShell. Ini juga akan mencakup aset lain yang diperlukan PowerShell dalam buildnya, seperti manifes modul untuk modul Microsoft.PowerShell.* dan direktori ref yang diperlukan oleh Add-Type.

Mengingat kelengkapan Microsoft.Powershell.SDK, maka paling sesuai untuk:

  • Implementasi pada host PowerShell.
  • Pengujian xUnit untuk pustaka yang ditargetkan pada rakitan referensi PowerShell.
  • Memanggil PowerShell dalam proses dari aplikasi .NET.

Microsoft.PowerShell.SDK juga dapat digunakan sebagai target referensi ketika proyek .NET dimaksudkan untuk digunakan sebagai modul atau dimuat oleh PowerShell, tetapi tergantung pada API hanya ada di versi PowerShell tertentu. Perhatikan bahwa rakitan yang diterbitkan terhadap versi Microsoft.PowerShell.SDK tertentu hanya akan aman untuk dimuat dan digunakan dalam versi PowerShell tersebut. Untuk menargetkan beberapa versi PowerShell dengan API tertentu, diperlukan beberapa kompilasi, masing-masing menargetkan versi Microsoft.Powershell.SDKtersendiri.

Nota

PowerShell SDK hanya tersedia untuk PowerShell versi 6 ke atas. Untuk menyediakan fungsionalitas yang setara dengan Windows PowerShell, gunakan rakitan referensi Windows PowerShell yang dijelaskan di bawah ini.

System.Management.Automation

Paket System.Management.Automation adalah inti dari PowerShell SDK. Ini ada di NuGet, terutama, sebagai aset bagi Microsoft.Powershell.SDK untuk masuk. Namun, ini juga dapat digunakan langsung sebagai paket untuk skenario hosting yang lebih kecil dan modul yang menyasar versi tertentu.

Secara khusus, paket System.Management.Automation mungkin merupakan penyedia fungsionalitas PowerShell yang lebih disukai saat:

  • Anda hanya ingin menggunakan fungsionalitas bahasa PowerShell (di namespace System.Management.Automation.Language) seperti pengurai PowerShell, AST, dan API pengunjung AST (misalnya untuk analisis statis PowerShell).
  • Anda hanya ingin menjalankan perintah tertentu dari modul Microsoft.PowerShell.Core dan dapat menjalankannya dalam status sesi yang dibuat dengan metode CreateDefault2 factory.

Selain itu, System.Management.Automation merupakan rakitan referensi yang berguna ketika:

  • Anda ingin menargetkan API yang hanya ada dalam versi PowerShell tertentu
  • Anda tidak akan bergantung pada tipe yang berasal dari luar rakitan System.Management.Automation (misalnya, tipe yang diekspor oleh cmdlet dalam modul Microsoft.PowerShell.*).

Kumpulan referensi Windows PowerShell

Untuk PowerShell versi 5.1 dan yang lebih lama (Windows PowerShell), tidak ada SDK untuk menyediakan implementasi PowerShell, karena implementasi Windows PowerShell adalah bagian dari Windows.

Sebagai gantinya, rakitan referensi Windows PowerShell menyediakan target referensi dan cara untuk menghosting ulang Windows PowerShell, bertindak sama seperti yang dilakukan PowerShell SDK untuk versi 6 ke atas.

Daripada dibingkai berdasarkan versi, rakitan referensi Windows PowerShell memiliki paket yang berbeda untuk setiap versi Windows PowerShell:

  • PowerShell 5.1
  • PowerShell 4
  • PowerShell 3

Informasi tentang cara menggunakan rakitan referensi Windows PowerShell dapat ditemukan di Windows PowerShell SDK.

Contoh dunia nyata menggunakan paket NuGet ini

Proyek alat PowerShell yang berbeda menargetkan paket PowerShell NuGet yang berbeda tergantung pada kebutuhannya. Tercantum di sini adalah beberapa contoh penting.

PSReadLine

PSReadLine, modul PowerShell yang menyediakan banyak pengalaman konsol PowerShell yang kaya, menargetkan PowerShell Standard sebagai dependensi, bukan versi PowerShell tertentu, dan menargetkan runtime .NET net461 dalam csproj.

PowerShell 6+ menyediakan assembly shim sendiri yang memungkinkan DLL yang menargetkan runtime net461 untuk dapat "berfungsi dengan baik" ketika dimuat dalam lingkungan (dengan mengalihkan pengikatan ke assembly .NET Framework mscorlib.dll yang relevan ke assembly .NET Core).

Ini menyederhanakan tata letak dan pengiriman modul PSReadLine secara signifikan, karena PowerShell Standard memastikan satu-satunya API yang digunakan akan ada di PowerShell 5.1 dan PowerShell 6+, sekaligus memungkinkan modul untuk dikirim hanya dengan satu rakitan.

Target .NET 4.6.1 berarti bahwa Windows PowerShell yang berjalan pada .NET 4.5.2 dan .NET 4.6 tidak didukung.

Layanan Editor PowerShell

PowerShell Editor Services (PSES) adalah backend untuk ekstensi PowerShell tersebut untuk Visual Studio Code, dan sebenarnya merupakan jenis modul PowerShell yang dimuat oleh eksekutabel PowerShell dan kemudian memproses ulang PowerShell tersebut dalam dirinya sendiri sambil juga menyediakan fitur Protokol Layanan Bahasa dan Adaptor Debugging.

PSES menyediakan target implementasi konkret untuk netcoreapp2.1 guna memfokuskan pada PowerShell 6+ (karena runtime netcoreapp3.1 pada PowerShell 7 kompatibel secara mundur) dan net461 untuk menargetkan Windows PowerShell 5.1, tetapi sebagian besar logiknya terdapat dalam rakitan kedua yang menargetkan netstandard2.0 dan PowerShell Standard. Ini memungkinkannya untuk menarik dependensi yang diperlukan untuk platform .NET Core dan .NET Framework, sambil tetap menyederhanakan sebagian besar basis kode di balik abstraksi seragam.

Karena dibangun terhadap PowerShell Standard, PSES memerlukan implementasi runtime PowerShell agar dapat diuji dengan benar. Untuk melakukan ini, pengujian xUnit PSES menarik Microsoft.PowerShell.SDK dan Microsoft.PowerShell.5.ReferenceAssemblies untuk menyediakan implementasi PowerShell di lingkungan pengujian.

Seperti halnya PSReadLine, PSES tidak dapat mendukung .NET 4.6 ke bawah, tetapi melakukan pemeriksaan pada runtime sebelum memanggil SALAH SATU API yang dapat menyebabkan crash pada runtime .NET Framework yang lebih rendah.

PSScriptAnalyzer

PSScriptAnalyzer, linter untuk PowerShell, harus menargetkan elemen sintaksis yang hanya diperkenalkan dalam versi PowerShell tertentu. Karena pengenalan elemen-elemen sintaksis ini dicapai dengan menerapkan AstVisitor2, tidak mungkin untuk menggunakan PowerShellStandard serta menerapkan metode pengunjung AST untuk sintaks PowerShell yang lebih baru.

Sebagai gantinya, PSScriptAnalyzer menargetkan setiap versi PowerShell sebagai konfigurasi build, dan menghasilkan DLL terpisah untuk masing-masing versi tersebut. Ini menambah ukuran dan kompleksitas build, tetapi memungkinkan:

  • Penargetan API khusus versi
  • Fungsi khusus versi yang akan diimplementasikan tanpa biaya runtime yang signifikan
  • Dukungan penuh terdapat untuk Windows PowerShell hingga ke .NET Framework 4.5.2

Ringkasan

Dalam artikel ini, kami telah mencantumkan dan membahas paket NuGet yang tersedia untuk digunakan dalam menerapkan proyek .NET yang menggunakan PowerShell, serta alasan memilih salah satunya dibandingkan yang lain.

Jika Anda telah melompat ke ringkasan, beberapa rekomendasi luas adalah:

  • Modul PowerShell harus dikompilasi terhadap PowerShell Standard jika hanya memerlukan API-API yang sering digunakan dalam berbagai versi PowerShell.
  • PowerShell host dan aplikasi yang perlu menjalankan PowerShell secara internal harus menargetkan PowerShell SDK untuk PowerShell 6+ atau rakitan referensi Windows PowerShell yang relevan untuk Windows PowerShell.
  • Modul PowerShell yang memerlukan API khusus versi harus menargetkan rakitan referensi PowerShell SDK atau Windows PowerShell untuk versi PowerShell yang diperlukan, menggunakannya sebagai rakitan referensi (yaitu, tidak menerbitkan dependensi PowerShell).