วิธีเพิ่มแอสเซมบลี. NET ลงในเซสชัน Powershell อย่างถูกต้อง


24

ฉันมี. NET assembly (dll) ซึ่งเป็น API สำหรับซอฟต์แวร์สำรองข้อมูลที่เราใช้ที่นี่ มันมีคุณสมบัติและวิธีการบางอย่างที่ฉันต้องการใช้ประโยชน์จากสคริปต์ Powershell ของฉัน อย่างไรก็ตามฉันพบปัญหามากมายกับการโหลดชุดประกอบครั้งแรกจากนั้นใช้ประเภทใดก็ได้เมื่อโหลดชุดประกอบแล้ว

เส้นทางไฟล์ที่สมบูรณ์คือ:

C:\rnd\CloudBerry.Backup.API.dll

ใน PowerShell ฉันใช้:

$dllpath = "C:\rnd\CloudBerry.Backup.API.dll"
Add-Type -Path $dllpath

ฉันได้รับข้อผิดพลาดด้านล่าง:

Add-Type : Unable to load one or more of the requested types. Retrieve the
LoaderExceptions property for more information.
At line:1 char:9
+ Add-Type <<<<  -Path $dllpath
+ CategoryInfo          : NotSpecified: (:) [Add-Type], ReflectionTypeLoadException
+ FullyQualifiedErrorId : System.Reflection.ReflectionTypeLoadException,Microsoft.PowerShell.Commands.AddTypeComma
ndAdd-Type : Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

การใช้ cmdlet เดียวกันกับแอสเซมบลี. NET อื่นDotNetZipซึ่งมีตัวอย่างของการใช้ฟังก์ชันการทำงานเดียวกันบนไซต์ก็ไม่ได้ผลสำหรับฉันเช่นกัน

ในที่สุดฉันก็พบว่าฉันสามารถโหลดชุดประกอบโดยใช้การสะท้อน:

[System.Reflection.Assembly]::LoadFrom($dllpath)

แม้ว่าฉันจะไม่เข้าใจความแตกต่างระหว่างวิธีการโหลด, LoadFrom หรือ LoadFile ที่วิธีสุดท้ายดูเหมือนว่าจะทำงาน

อย่างไรก็ตามฉันยังคงไม่สามารถสร้างอินสแตนซ์หรือใช้วัตถุได้ ทุกครั้งที่ฉันลองฉันพบข้อผิดพลาดที่อธิบายว่า Powershell ไม่สามารถค้นหาประเภทสาธารณะใด ๆ ได้

ฉันรู้ว่ามีชั้นเรียน:

$asm = [System.Reflection.Assembly]::LoadFrom($dllpath)
$cbbtypes = $asm.GetExportedTypes()
$cbbtypes | Get-Member -Static

---- start of excerpt ----

   TypeName: CloudBerryLab.Backup.API.BackupProvider

Name                MemberType Definition
----                ---------- ----------
PlanChanged         Event          System.EventHandler`1[CloudBerryLab.Backup.API.Utils.ChangedEventArgs] PlanChanged(Sy...
PlanRemoved         Event          System.EventHandler`1[CloudBerryLab.Backup.API.Utils.PlanRemoveEventArgs] PlanRemoved...
CalculateFolderSize Method     static long CalculateFolderSize()
Equals              Method     static bool Equals(System.Object objA, System.Object objB)
GetAccounts         Method     static CloudBerryLab.Backup.API.Account[],     CloudBerry.Backup.API, Version=1.0.0.1, Cu...
GetBackupPlans      Method     static CloudBerryLab.Backup.API.BackupPlan[], CloudBerry.Backup.API, Version=1.0.0.1,...
ReferenceEquals     Method     static bool ReferenceEquals(System.Object objA, System.Object objB)
SetProfilePath      Method     static System.Void SetProfilePath(string profilePath)

---- จุดสิ้นสุดของข้อความที่ตัดตอนมา ----

การพยายามใช้วิธีการคงที่ล้มเหลวฉันไม่รู้ว่าทำไม !!!

[CloudBerryLab.Backup.API.BackupProvider]::GetAccounts()
Unable to find type [CloudBerryLab.Backup.API.BackupProvider]: make sure that the     assembly containing this type is load
ed.
At line:1 char:42
+ [CloudBerryLab.Backup.API.BackupProvider] <<<< ::GetAccounts()
    + CategoryInfo          : InvalidOperation:     (CloudBerryLab.Backup.API.BackupProvider:String) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound

คำแนะนำใด ๆ ชื่นชม !!

คำตอบ:


15

คุณช่วยล้อมรอบAdd-Typeด้วยลอง catch และพิมพ์คุณสมบัติ LoaderExceptions เนื่องจากข้อผิดพลาดที่ระบุว่าต้องทำ มันอาจให้ข้อยกเว้นกับข้อความแสดงข้อผิดพลาดที่ละเอียดมากขึ้น

try
{
    Add-Type -Path "C:\rnd\CloudBerry.Backup.API.dll"
}
catch
{
    $_.Exception.LoaderExceptions | %
    {
        Write-Error $_.Message
    }
}

9
มันไม่ได้ผลสำหรับฉัน แต่มันทำให้ฉันอยู่ใน ballpark ภายในจับวัตถุ LoaderExceptions ตั้งอยู่ที่นี่:. _ $ Exception.LoaderExceptions
เบร็ท

ไม่มีวิธีใช้เส้นทางสัมพัทธ์หรือ
Amit

3

ฉันพบลิงค์นี้: http://www.madwithpowershell.com/2013/10/add-type-vs-reflectionassembly-in.html

เขาบอกว่า ".LoadWithPartialName" ถูกเลิกใช้แล้ว ดังนั้นแทนที่จะใช้ Add-Type อย่างต่อเนื่องกับวิธีการนั้นจะใช้ตารางแบบคงที่ภายในเพื่อแปล "ชื่อบางส่วน" เป็น "ชื่อเต็ม" ในตัวอย่างที่ระบุในคำถามCloudBerry.Backup.API.dllไม่มีรายการในตารางภายในของ PowerShell ซึ่งเป็นสาเหตุที่ใช้[System.Reflection.Assembly]::LoadFrom($dllpath)งานได้ มันไม่ได้ใช้ตารางเพื่อค้นหาชื่อบางส่วน


2

วิธีการข้างต้นบางอย่างไม่ได้ผลสำหรับฉันหรือไม่ชัดเจน

นี่คือสิ่งที่ฉันใช้ห่อ -AddPath สายและจับ LoaderExceptions:

try
{
   Add-Type -Path "C:\path\to.dll"
}
catch [System.Reflection.ReflectionTypeLoadException]
{
   Write-Host "Message: $($_.Exception.Message)"
   Write-Host "StackTrace: $($_.Exception.StackTrace)"
   Write-Host "LoaderExceptions: $($_.Exception.LoaderExceptions)"
}

ข้อมูลอ้างอิง
https://social.technet.microsoft.com/Forums/sharepoint/en-US/dff8487f-69af-4b64-ab83-13d58a55c523/addtype-inheritance-loaderexceptions


0

ฉันใช้การตั้งค่าต่อไปนี้เพื่อโหลดตัวควบคุม csharp ที่กำหนดเองใน powershell จะช่วยให้การควบคุมที่จะปรับแต่งและใช้จากภายใน PowerShell

นี่คือลิงค์บล็อก

http://justcode.ca/wp/?p=435

และนี่คือลิงค์ codeproject ที่มีแหล่งที่มา

http://www.codeproject.com/Articles/311705/Custom-CSharp-Control-for-Powershell


3
ยินดีต้อนรับสู่ Server Fault! เราชอบที่คำตอบนั้นมีเนื้อหาไม่ใช่ตัวชี้ไปที่เนื้อหา ในขณะที่สิ่งนี้อาจตอบคำถามในทางทฤษฎีมันก็ควรที่จะรวมส่วนสำคัญของคำตอบที่นี่และให้ลิงค์สำหรับการอ้างอิง
jscott

0

LoaderExceptionsถูกซ่อนอยู่ภายในบันทึกข้อผิดพลาด หากข้อผิดพลาดประเภทเพิ่มเป็นข้อผิดพลาดสุดท้ายในรายการข้อผิดพลาดใช้$Error[0].InnerException.LoaderExceptionsเพื่อแสดงข้อผิดพลาด เป็นไปได้มากว่าห้องสมุดของคุณขึ้นอยู่กับห้องสมุดอื่นที่ไม่ได้โหลด คุณสามารถAdd-Typeแต่ละคนหรือเพียงแค่ทำรายการและใช้อาร์กิวเมนต์-ReferencedAssembliesAdd-Type


ลองใช้ $ Error [0] .Exception.LoaderExceptions และทำตามคำแนะนำของ Eris
Tahir Hassan

-1

ฉันเดาว่าตอนนี้คุณอาจพบคำตอบของปรากฏการณ์นี้แล้ว ฉันวิ่งไปที่โพสต์นี้หลังจากพบปัญหาเดียวกัน ... ฉันสามารถโหลดชุดประกอบและดูประเภทที่มีอยู่ในชุดประกอบ แต่ไม่สามารถติดตั้งอินสแตนซ์ของคลาสแบบคงที่ได้ มันเป็น EFTIDY Tidy, EFTidyNet.TidyNet.Options หรืออะไร Ooooo Weeee ... ปัญหา ... ปัญหา ... มันอาจจะเป็นอะไรก็ได้ และการดูวิธีการคงที่และประเภทของ DLL ไม่ได้เปิดเผยสิ่งที่มีแนวโน้ม ตอนนี้ฉันกำลังหดหู่ ฉันใช้งานโปรแกรม C # ที่คอมไพล์แล้ว แต่สำหรับการใช้งานของฉัน

วิธีการแก้ปัญหาของฉันที่ฉันพบและยังคงได้รับการพิสูจน์ แต่ฉันดีใจและอยากจะแบ่งปันสิ่งนี้ สร้างแอป console.exe ขนาดเล็กที่ใช้งาน func ที่ฉันสนใจและจากนั้นดูในสิ่งที่จะถอดรหัสหรือแสดงรหัส IL ฉันใช้ตัวสะท้อนแสงของ Red-Gate และ Add-in ตัวสร้างภาษา PowerShell และ Wallah! มันแสดงให้เห็นว่าสตริงตัวสร้างที่เหมาะสมคืออะไร! :-) ลองมัน. และฉันหวังว่าจะได้ผลกับใครก็ตามที่ประสบปัญหานี้


2
และ ... สตริงคอนสตรัคเตอร์ที่เหมาะสมคืออะไร? นี่ไม่ได้ตอบคำถามอย่างที่เขียนไว้ นอกจากนี้ยินดีต้อนรับสู่ ServerFault!
ออสเตีย
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.