ตอนนี้คนส่วนใหญ่รู้แล้วว่าSystem.Reflection.Assembly.LoadWithPartialName
เลิกใช้แล้ว แต่กลับกลายเป็นAdd-Type -AssemblyName Microsoft.VisualBasic
ว่าไม่ได้ประพฤติดีกว่าLoadWithPartialName
:
แทนที่จะพยายามแยกวิเคราะห์คำขอของคุณในบริบทของระบบของคุณ [Add-Type] ดูที่ตารางภายในแบบคงที่เพื่อแปล "ชื่อบางส่วน" เป็น "ชื่อเต็ม"
หาก "ชื่อบางส่วน" ไม่ปรากฏในตารางสคริปต์ของคุณจะล้มเหลว
หากคุณมีแอสเซมบลีหลายรุ่นที่ติดตั้งบนคอมพิวเตอร์ของคุณไม่มีอัลกอริทึมอัจฉริยะให้เลือกระหว่างพวกเขา คุณจะได้อันใดอันหนึ่งปรากฏในตารางของพวกเขาอาจเป็นอันเก่าและล้าสมัย
หากเวอร์ชันที่คุณติดตั้งนั้นใหม่กว่าเวอร์ชั่นที่ล้าสมัยในตารางสคริปต์ของคุณจะล้มเหลว
เพิ่มประเภทไม่มี parser อัจฉริยะของ "บางส่วนของชื่อ"
.LoadWithPartialNames
ชอบ
สิ่งที่ Microsoft กล่าวว่าคุณควรจะทำจริง ๆเป็นดังนี้:
Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
หรือถ้าคุณรู้เส้นทางสิ่งนี้:
Add-Type -Path 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.VisualBasic\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualBasic.dll'
ชื่อยาวที่กำหนดสำหรับชุดประกอบเรียกว่าชื่อรัดกุมซึ่งเป็นชื่อเฉพาะของรุ่นและชุดประกอบและบางครั้งเรียกว่าชื่อเต็ม
แต่นี่เป็นคำถามที่ยังไม่ได้รับคำตอบ:
ฉันจะตรวจสอบชื่อที่รัดกุมของสิ่งที่ถูกโหลดบนระบบของฉันด้วยชื่อบางส่วนที่กำหนดได้อย่างไร
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).Location;
[System.Reflection.Assembly]::LoadWithPartialName($TypeName).FullName;
สิ่งเหล่านี้ควรใช้งานได้:
Add-Type -AssemblyName $TypeName -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
ถ้าฉันต้องการให้สคริปต์ของฉันใช้. dll รุ่นใดรุ่นหนึ่งโดยเฉพาะ แต่ฉันไม่แน่ใจว่าติดตั้งไว้ที่ใดฉันจะทราบได้อย่างไรว่าชื่อที่แข็งแกร่งมาจาก. dll
[System.Reflection.AssemblyName]::GetAssemblyName($Path).FullName;
หรือ:
Add-Type $Path -PassThru | Select-Object -ExpandProperty Assembly | Select-Object -ExpandProperty FullName -Unique
ถ้าฉันรู้ชื่อที่รัดกุมฉันจะกำหนดเส้นทาง. dll ได้อย่างไร
[Reflection.Assembly]::Load('Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a').Location;
และในหลอดเลือดดำที่คล้ายกันถ้าฉันรู้ชื่อประเภทของสิ่งที่ฉันใช้อยู่ฉันจะทราบได้อย่างไรว่าแอสเซมบลีใดมาจากไหน
[Reflection.Assembly]::GetAssembly([Type]).Location
[Reflection.Assembly]::GetAssembly([Type]).FullName
ฉันจะดูว่ามีแอสเซมบลีใดบ้าง
ผมขอแนะนำให้โมดูล GAC PowerShell Get-GacAssembly -Name 'Microsoft.SqlServer.Smo*' | Select Name, Version, FullName
ทำงานได้ค่อนข้างดี
- ฉันจะดูรายการที่
Add-Type
ใช้ได้อย่างไร
มันซับซ้อนกว่านี้เล็กน้อย ฉันสามารถอธิบายวิธีเข้าถึงมันสำหรับ PowerShell ทุกรุ่นด้วย. Net reflector (ดูการปรับปรุงด้านล่างสำหรับ PowerShell Core 6.0)
ก่อนอื่นให้ตรวจสอบว่าไลบรารีใดAdd-Type
มาจาก:
Get-Command -Name Add-Type | Select-Object -Property DLL
เปิด DLL ที่เป็นผลลัพธ์ด้วยตัวสะท้อนสัญญาณของคุณ ฉันใช้ILSpyสำหรับเรื่องนี้เพราะมันเป็น FLOSS แต่ C # reflector ใด ๆ ก็ควรใช้งานได้ เปิดMicrosoft.Powershell.Commands.Utility
ไลบรารี่นั้นแล้วดู ภายใต้ควรจะมีMicrosoft.Powershell.Commands
AddTypeCommand
ในรายการรหัสสำหรับสิ่งนั้นมีคลาสส่วนตัว, InitializeStrongNameDictionary()
. ที่แสดงรายการพจนานุกรมที่แมปชื่อสั้น ๆ กับชื่อที่รัดกุม มีเกือบ 750 รายการในห้องสมุดที่ฉันดู
อัปเดต:ตอนนี้ PowerShell Core 6.0 เป็นโอเพ่นซอร์ส สำหรับรุ่นที่คุณสามารถข้ามขั้นตอนข้างต้นและดูรหัสโดยตรงออนไลน์ในพื้นที่เก็บข้อมูล GitHub ของพวกเขา ฉันไม่สามารถรับประกันได้ว่ารหัสนั้นจะตรงกับ PowerShell รุ่นอื่นใด ๆ