대부분의 사람들은 지금까지 System.Reflection.Assembly.LoadWithPartialName
더 이상 사용 Add-Type -AssemblyName Microsoft.VisualBasic
되지 않는다고LoadWithPartialName
알고 있지만 다음 보다 훨씬 잘 작동하지 않는 것으로 나타났습니다 .
[Add-Type]은 시스템 컨텍스트에서 요청을 구문 분석하지 않고 "부분 이름"을 "전체 이름"으로 변환하기 위해 정적 내부 테이블을 찾습니다.
"부분 이름"이 표에 나타나지 않으면 스크립트가 실패합니다.
컴퓨터에 여러 버전의 어셈블리가 설치되어 있으면 선택할 수있는 지능형 알고리즘이 없습니다. 테이블에 나타날 것, 아마도 오래되고 오래된 것 중 하나를 얻을 것입니다.
설치 한 버전이 표에서 더 이상 사용되지 않는 버전 인 경우 스크립트가 실패합니다.
추가 유형에는와 같은 "부분 이름"에 대한 지능적인 구문 분석기가 없습니다
.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
사용 하는 목록을 어떻게 볼 수 있습니까?
이것은 조금 더 복잡합니다. .Net 리플렉터를 사용하여 모든 버전의 PowerShell에서 액세스하는 방법을 설명 할 수 있습니다 (PowerShell Core 6.0의 경우 아래 업데이트 참조).
먼저, 어떤 라이브러리 Add-Type
가 제공 되는지 확인하십시오 .
Get-Command -Name Add-Type | Select-Object -Property DLL
리플렉터로 결과 DLL을 엽니 다. FLOSS이기 때문에 ILSpy 를 사용 했지만 C # 리플렉터가 작동해야합니다. 해당 라이브러리를 열고에서 찾아보십시오 Microsoft.Powershell.Commands.Utility
. 아래 Microsoft.Powershell.Commands
에 있어야합니다 AddTypeCommand
.
이를위한 코드 목록에는 개인 클래스가 InitializeStrongNameDictionary()
있습니다. 여기에는 짧은 이름을 강력한 이름으로 매핑하는 사전이 나열됩니다. 내가 본 라이브러리에는 거의 750 개의 항목이 있습니다.
업데이트 : 이제 PowerShell Core 6.0이 오픈 소스입니다. 해당 버전의 경우 위의 단계를 건너 뛰고 GitHub 리포지토리에서 직접 온라인으로 코드를 볼 수 있습니다 . 그러나 해당 코드가 다른 버전의 PowerShell과 일치한다고 보장 할 수는 없습니다.