Şimdiye kadar çoğu insan bunun System.Reflection.Assembly.LoadWithPartialName
kullanımdan kaldırıldığını biliyor , ancak bunun Add-Type -AssemblyName Microsoft.VisualBasic
şunlardan daha iyi davranmadığıLoadWithPartialName
ortaya çıktı :
[Add-Type], isteğinizi sisteminizin bağlamında ayrıştırmak yerine, "kısmi adı" "tam ada" çevirmek için statik, dahili bir tabloya bakar.
"Kısmi adınız" onların tablosunda görünmüyorsa, komut dosyanız başarısız olacaktır.
Bilgisayarınızda montajın birden çok sürümü kuruluysa, aralarında seçim yapabileceğiniz akıllı bir algoritma yoktur. Masalarında hangisi görünüyorsa, muhtemelen daha eski, modası geçmiş olanı alacaksınız.
Yüklediğiniz sürümlerin tümü tablodaki eski sürümden daha yeniyse, betiğiniz başarısız olacaktır.
Add-Type, "kısmi adlar" gibi akıllı ayrıştırıcıya sahip değildir
.LoadWithPartialNames
.
Microsoft'un .Net ekiplerinin aslında yapmanız gerektiğini söylediği şey şuna benzer:
Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
Veya yolu biliyorsanız, bunun gibi bir şey:
Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'
Meclis için verilen bu uzun isim, güçlü isim olarak bilinir. , hem sürüme hem de derlemeye özgü olan olarak bilinir ve bazen tam ad olarak da bilinir.
Ancak bu, birkaç soruyu cevapsız bırakıyor:
Belirli bir kısmi adla sistemime gerçekte yüklenen şeyin güçlü adını nasıl belirleyebilirim?
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
Bunlar da çalışmalıdır:
Add-Type -AssemblyName $TypeName -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
Komut dosyamın her zaman bir .dll'nin belirli bir sürümünü kullanmasını istiyorsam, ancak nereye yüklendiğinden emin olamıyorsam, güçlü adın .dll'den ne olduğunu nasıl belirleyebilirim?
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
Veya:
Add-Type $Path -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
Güçlü adı biliyorsanız, .dll yolunu nasıl belirleyebilirim?
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
Ve benzer bir şekilde, kullandığım şeyin tip adını bilirsem, hangi montajdan geldiğini nasıl bilebilirim?
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
Hangi montajların mevcut olduğunu nasıl görebilirim?
GAC PowerShell modülünü öneririm . Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
oldukça iyi çalışıyor.
- Kullanılan listeyi nasıl görebilirim
Add-Type
?
Bu biraz daha karmaşık. Net reflektörlü herhangi bir PowerShell sürümü için buna nasıl erişileceğini açıklayabilirim (PowerShell Core 6.0 için aşağıdaki güncellemeye bakın).
İlk olarak, hangi kitaplığın Add-Type
geldiğini bulun:
Get-Command -Name Add-Type | Select-Object -Property DLL
Ortaya çıkan DLL dosyasını reflektörünüzle açın. Bunun için ILSpy'ı kullandım çünkü FLOSS, ancak herhangi bir C # reflektörü çalışmalı. O kitaplığı açın ve içeri bakın Microsoft.Powershell.Commands.Utility
. Altında Microsoft.Powershell.Commands
olmalı AddTypeCommand
.
Bunun için kod listesinde özel bir sınıf var InitializeStrongNameDictionary()
. Bu, kısa adları güçlü adlarla eşleyen sözlüğü listeler. Baktığım kütüphanede neredeyse 750 kayıt var.
Güncelleme: PowerShell Core 6.0 artık açık kaynak. Bu sürüm için, yukarıdaki adımları atlayabilir ve kodu doğrudan GitHub deposunda çevrimiçi olarak görebilirsiniz . Bununla birlikte, bu kodun başka herhangi bir PowerShell sürümüyle eşleşeceğini garanti edemem.
Güncelleme 2: Powershell 7+ artık hash tablosu aramasına sahip görünmüyor. Bunun yerine , yorumların LoadWithPartialName'e "mümkün olan en yakın yaklaşım" adını verdiği bir LoadAssemblyHelper()
yöntem kullanırlar. Temel olarak, bunu yaparlar:
loadedAssembly = Assembly.Load(new AssemblyName(assemblyName));
Şimdi, yorumlar ayrıca "kullanıcılar Add-Type -AssemblyName Forms
(System.Windows.Forms yerine) diyebilir" diyor . Ancak, Windows 10 2004'te Powershell v7.0.3'te gördüğüm bu değil.
Add-Type -AssemblyName Forms
[System.Reflection.Assembly]::Load([System.Reflection.AssemblyName]::new('Forms'))
Add-Type -AssemblyName System.Windows.Forms
[System.Reflection.Assembly]::Load([System.Reflection.AssemblyName]::new('System.Windows.Forms'))
Yani yorumlar biraz gizemli görünüyor.
Assembly.Load(AssemblyName)
Belirtilen sürüm veya genel anahtar belirteci olmadığında mantığın tam olarak ne olduğunu bilmiyorum . Birden çok yüklediyseniz, bu, LoadWithPartialName'in potansiyel olarak derlemenin yanlış sürümünü yüklemeyi sevdiği sorunların çoğuna sahip olmasını beklerim.