Sebagian besar orang tahu saat System.Reflection.Assembly.LoadWithPartialName
ini sudah usang, tetapi ternyata Add-Type -AssemblyName Microsoft.VisualBasic
tidak berperilaku jauh lebih baik daripadaLoadWithPartialName
:
Daripada melakukan upaya untuk menguraikan permintaan Anda dalam konteks sistem Anda, [Add-Type] melihat tabel internal yang statis untuk menerjemahkan "sebagian nama" menjadi "nama lengkap".
Jika "sebagian nama" Anda tidak muncul di tabel mereka, skrip Anda akan gagal.
Jika Anda memiliki beberapa versi rakitan yang diinstal pada komputer Anda, tidak ada algoritma cerdas untuk memilih di antara mereka. Anda akan mendapatkan mana yang muncul di meja mereka, mungkin yang lebih tua, yang sudah ketinggalan zaman.
Jika versi yang Anda instal semuanya lebih baru daripada versi usang di skrip, skrip Anda akan gagal.
Add-Type tidak memiliki parser cerdas "sebagian nama" seperti
.LoadWithPartialNames
.
Apa yang Microsoft mengatakan Anda benar-benar harus lakukan adalah sesuatu seperti ini:
Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Atau, jika Anda tahu jalannya, sesuatu seperti ini:
Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'
Nama panjang yang diberikan untuk majelis dikenal sebagai nama kuat , yang unik untuk versi dan majelis, dan kadang-kadang juga dikenal sebagai nama lengkap.
Tapi ini menyisakan beberapa pertanyaan:
Bagaimana cara menentukan nama kuat dari apa yang sebenarnya dimuat di sistem saya dengan nama parsial yang diberikan?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Ini juga harus bekerja:
Add-Type -AssemblyName $TypeName -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
Jika saya ingin skrip saya selalu menggunakan versi tertentu dari .dll tapi saya tidak bisa memastikan di mana itu diinstal, bagaimana cara menentukan apa nama yang kuat dari.
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
Atau:
Add-Type $Path -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
Jika saya tahu nama yang kuat, bagaimana cara menentukan jalur .dll?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
Dan, dengan nada yang sama, jika saya tahu nama tipe dari apa yang saya gunakan, bagaimana saya tahu dari mana asalnya?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
Bagaimana cara melihat majelis apa yang tersedia?
Saya menyarankan modul GAC PowerShell . Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
bekerja dengan cukup baik.
- Bagaimana saya bisa melihat daftar yang
Add-Type
menggunakan?
Ini sedikit lebih rumit. Saya dapat menjelaskan cara mengaksesnya untuk versi PowerShell dengan reflektor .Net (lihat pembaruan di bawah ini untuk PowerShell Core 6.0).
Pertama, cari tahu dari perpustakaan mana Add-Type
:
Get-Command -Name Add-Type | Select-Object -Property DLL
Buka DLL yang dihasilkan dengan reflektor Anda. Saya telah menggunakan ILSpy untuk ini karena FLOSS, tetapi reflektor C # apa pun harus berfungsi. Buka perpustakaan itu, dan lihat Microsoft.Powershell.Commands.Utility
. Di bawah Microsoft.Powershell.Commands
, seharusnya ada AddTypeCommand
.
Dalam daftar kode untuk itu, ada kelas privat InitializeStrongNameDictionary()
,. Itu mencantumkan kamus yang memetakan nama pendek ke nama kuat. Ada hampir 750 entri di perpustakaan yang pernah saya lihat.
Pembaruan: Sekarang PowerShell Core 6.0 adalah open source. Untuk versi itu, Anda dapat melewati langkah-langkah di atas dan melihat kode secara online di repositori GitHub mereka . Saya tidak dapat menjamin bahwa kode tersebut cocok dengan versi PowerShell lainnya.