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.