Powershell 세션에 .NET 어셈블리를 올바르게 추가하는 방법은 무엇입니까?


24

여기에서 사용하는 소프트웨어를 백업하는 API 인 .NET 어셈블리 (dll)가 있습니다. 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.

사이트에서 동일한 기능을 사용하는 예가있는 다른 .NET 어셈블리 인 DotNetZip 에서 동일한 cmdlet을 사용하면 작동하지 않습니다.

결국 리플렉션을 사용하여 어셈블리를로드 할 수있는 것으로 보입니다.

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

마지막 메서드가 작동하는 것처럼 보이는 Load, LoadFrom 또는 LoadFile 메서드의 차이점을 이해하지 못합니다.

그러나 여전히 인스턴스를 만들거나 개체를 사용할 수없는 것 같습니다. 시도 할 때마다 Powershell이 ​​공개 유형을 찾을 수 없다는 오류가 발생합니다.

수업이 있다는 것을 알고 있습니다.

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

---- 발췌의 시작 ----

   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오류를 알리기 위해 try catch로 LoaderExceptions 속성을 인쇄하고 LoaderExceptions 속성을 인쇄 할 수 있습니까 ? 더 자세한 오류 메시지가있는 예외를 제공 할 수 있습니다.

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

9
이것은 나를 위해 작동하지 않았지만 야구장에 나를 데려갔습니다. 캐치 안에서 LoaderExceptions 객체는 다음 위치에 있습니다. $ _. Exception.LoaderExceptions
— Brett

상대 경로를 사용하는 방법이 없습니까?
— 아 미트

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

다음 설정을 사용하여 powershell에 사용자 지정 csharp 컨트롤을로드했습니다. Powershell 내에서 컨트롤을 사용자 정의하고 활용할 수 있습니다.

여기 블로그 링크가 있습니다

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

그리고 여기 소스와의 코드 프로젝트 링크가 있습니다

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


3
서버 결함에 오신 것을 환영합니다! 우리는 답변이 내용을 가리키는 포인터가 아닌 내용을 포함하는 것을 선호합니다. 이 이론적으로 질문에 대답 할 수 있습니다 동안, 바람직 할 것이다 여기에 대한 대답의 본질적인 부분을 포함하고 참조 할 수 있도록 링크를 제공합니다.
— jscott

0

이 LoaderExceptions오류 레코드 안에 숨겨져 있습니다. 추가 유형 오류가 오류 목록의 마지막 오류 인 경우 오류 $Error[0].InnerException.LoaderExceptions를 표시하는 데 사용 하십시오. 대부분의 라이브러리는로드되지 않은 다른 라이브러리에 종속되어 있습니다. 당신도 Add-Type하나 하나, 아니면 그냥이 목록을 확인하고 사용 -ReferencedAssemblies에 인수를 Add-Type.


$ Error [0] .Exception.LoaderExceptions를 따르고 Eris의 조언을 따르십시오.
— Tahir Hassan

-1

난 당신이 지금까지 생각 지도 모르지 이 현상에 대한 답을 발견했다. 동일한 문제가 발생한 후이 게시물을 보았습니다 ... 어셈블리를로드하고 어셈블리에 포함 된 유형을 볼 수는 있었지만 정적 클래스에서 인스턴스를 인스턴스화 할 수 없었습니다. EFTIDY입니까? 깔끔한, EFTidyNet.TidyNet.Options 또는 무엇? Ooooo Weeee ... 문제 ... 문제 ... 아무것도 될 수 있습니다. 그리고 정적 메소드와 DLL 유형을 살펴보면 유망한 것이 없습니다. 지금 나는 우울 해지고 있었다. 컴파일 된 C # 프로그램에서 작업했지만, 사용하기 위해 인터 페트 언어로 실행하고 싶었습니다 ... Powershell.

내 솔루션을 찾았지만 여전히 입증되고 있지만 기뻐하고 이것을 공유하고 싶었습니다. 내가 관심을 보인 기능을 사용하는 작은 console.exe 앱을 빌드 한 다음 디 컴파일하거나 IL 코드를 표시하는 것으로 확인하십시오. Red-Gate의 리플렉터와 Powershell 언어 생성기 애드 인 및 Wallah를 사용했습니다! 적절한 생성자 문자열이 무엇인지 보여주었습니다! :-) 시도 해봐. 이 문제에 직면 한 사람이라면 누구나 효과가 있기를 바랍니다.


2
그리고 ... 적절한 생성자 문자열은 무엇입니까? 이것은 실제로 질문에 쓰여진 방식으로 대답하지 않습니다. 또한 ServerFault에 오신 것을 환영합니다!
— Austinian
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.