Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일
 

.NET Reflection을 대체할 System.Reflection.Metadata 소개

초기 .NET 1.x 시절에는 .NET DLL/EXE에 구현된 타입 정보를 알아보기 위해 Assembly.Load 메서드를 사용했는데요, 이때 해당 어셈블리가 로드되면 잠기는 문제가 발생하지만 어셈블리를 내리려면 AppDomain이 함께 내려가야 한다는 부작용으로 인해 이후 Assembly.ReflectionOnlyLoad 메서드가 나옵니다.

Assembly.ReflectionOnlyLoad
; https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.reflectiononlyload?view=netframework-4.8

이것은 어셈블리를 코드로써 로드하지 않고 메타데이터만 살펴볼 수 있도록 허용하므로 DLL/EXE가 잠기지 않는다는 장점이 있습니다. 그러던 것이, .NET Core가 나오면서 아예 순수 메타데이터 자체를 다룰 수 있도록 System.Reflection.Metadata가 나왔습니다. 이에 대해 검색해 보면 사용 예제가 하나 눈에 띄는데요,

Metadata Tools
; https://github.com/dotnet/metadata-tools

dotnet/metadata-tools
; https://github.com/dotnet/metadata-tools/blob/master/src/Microsoft.Metadata.Visualizer/MetadataVisualizer.cs

아쉽게도 .NET Framework 버전으로 나와 있는 데다 .NET Core에서는 일부 컴파일 오류가 발생해 직접 사용할 수가 없습니다. 그래서 ^^ 개인적으로 최대한 수정해 다음의 github 예제로 올렸습니다.

DotNetSamples/NetCore/Microsoft.Metadata.Visualizer/
; https://github.com/stjeong/DotNetSamples/tree/master/NetCore/Microsoft.Metadata.Visualizer

딱 하나, WriteForwarders를 못 옮겼는데요,

public void Visualize(int generation = -1)
{
    this.reader = (generation >= 0) ? readers[generation] : readers.Last();

    WriteModule();
    WriteTypeRef();
    WriteTypeDef();
    WriteField();
    WriteMethod();
    WriteParam();
    WriteMemberRef();
    WriteConstant();
    WriteCustomAttribute();
    WriteDeclSecurity();
    WriteStandAloneSig();
    WriteEvent();
    WriteProperty();
    WriteMethodImpl();
    WriteModuleRef();
    WriteTypeSpec();
    WriteEnCLog();
    WriteEnCMap();
    WriteAssembly();
    WriteAssemblyRef();
    WriteFile();
    //WriteForwarders();
    WriteExportedType();
    WriteManifestResource();
    WriteGenericParam();
    WriteMethodSpec();
    WriteGenericParamConstraint();

    WriteUserStrings();
    WriteStrings();
    WriteBlobs();
    WriteGuids();
}

나중에 기회 되면 손을 보겠습니다. ^^ 아니면 이 글을 읽으시는 분 중에 수정하셔서 PR 보내주셔도 좋겠고.




참고로 다음은 Microsoft.Metadata.Visualizer 예제 프로젝트를 이용해 스스로의 메타데이터를 출력한 결과입니다.

Microsoft.Metadata.Visualizer.dll
********************************************************************************
Module (0x00):
=====================================================================================================================
   Gen  Name                                        Mvid                                         EncId  EncBaseId
=====================================================================================================================
1: 0    'Microsoft.Metadata.Visualizer.dll' (#b10)  {5592d697-bdc0-4859-aced-22e20a3efaee} (#1)  nil    nil

TypeRef (0x01):
===================================================================================================================================
    Scope                     Name                                                   Namespace
===================================================================================================================================
 1: 0x23000001 (AssemblyRef)  'CompilationRelaxationsAttribute' (#921)               'System.Runtime.CompilerServices' (#11bf)
 2: 0x23000001 (AssemblyRef)  'RuntimeCompatibilityAttribute' (#987)                 'System.Runtime.CompilerServices' (#11bf)
 3: 0x23000001 (AssemblyRef)  'DebuggableAttribute' (#853)                           'System.Diagnostics' (#1185)
 4: 0x01000003 (TypeRef)      'DebuggingModes' (#1234)                               nil
 5: 0x23000001 (AssemblyRef)  'TargetFrameworkAttribute' (#87e)                      'System.Runtime.Versioning' (#a81)
...[생략]...
99: 0x23000002 (AssemblyRef)  'Stream' (#b46)                                        'System.IO' (#22a)
9a: 0x23000003 (AssemblyRef)  'PEReaderExtensions' (#1444)                           'System.Reflection.Metadata' (#236)
9b: 0x23000001 (AssemblyRef)  'Enum' (#bbc)                                          'System' (#b89)
9c: 0x23000001 (AssemblyRef)  'StringComparison' (#f98)                              'System' (#b89)

TypeDef (0x02):
=================================================================================================================================================================================================================================================================================================================
   Name                           Namespace                                EnclosingType         BaseType              Interfaces  Fields                 Methods                Attributes                                                                                       ClassSize  PackingSize
=================================================================================================================================================================================================================================================================================================================
1: '<Module>' (#221)              nil                                      nil                   nil                   nil         nil                    nil                    0                                                                                                0          0
2: 'MetadataVisualizer' (#10e5)   'Microsoft.Metadata.Visualizer' (#10c7)  nil                   0x0100000c (TypeRef)  nil         0x04000001-0x04000006  0x06000001-0x06000035  0x00100101 (AutoLayout, AnsiClass, Class, Public, Sealed, BeforeFieldInit)                       0          0
3: 'Program' (#b6a)               'Microsoft.Metadata.Visualizer' (#10c7)  nil                   0x0100000c (TypeRef)  nil         nil                    0x06000036-0x06000038  0x00100000 (AutoLayout, AnsiClass, Class, BeforeFieldInit)                                       0          0
4: 'TokenTypeComparer' (#1033)    nil                                      0x02000002 (TypeDef)  0x0100000c (TypeRef)  0x09000001  0x04000007-0x04000007  0x06000039-0x0600003b  0x00100103 (AutoLayout, AnsiClass, Class, NestedPrivate, Sealed, BeforeFieldInit)                0          0
5: '<>c' (#272)                   nil                                      0x02000002 (TypeDef)  0x0100000c (TypeRef)  nil         0x04000008-0x04000012  0x0600003c-0x06000047  0x00102103 (AutoLayout, AnsiClass, Class, NestedPrivate, Sealed, Serializable, BeforeFieldInit)  0          0
6: '<>c__DisplayClass29_0' (#fd)  nil                                      0x02000002 (TypeDef)  0x0100000c (TypeRef)  nil         0x04000013-0x04000014  0x06000048-0x06000049  0x00100103 (AutoLayout, AnsiClass, Class, NestedPrivate, Sealed, BeforeFieldInit)                0          0
7: '<>c__DisplayClass0_0' (#1c)   nil                                      0x02000003 (TypeDef)  0x0100000c (TypeRef)  nil         0x04000015-0x04000015  0x0600004a-0x0600004b  0x00100103 (AutoLayout, AnsiClass, Class, NestedPrivate, Sealed, BeforeFieldInit)                0          0

Field (0x04):
================================================================================================================================================
    Name                   Signature                                         Attributes                             Marshalling  Offset  RVA
================================================================================================================================================
 1: 'writer' (#108a)       06-12-35 (#8d5)                                   0x00000021 (Private, InitOnly)         nil          n/a     0
 2: 'readers' (#152b)      06-15-12-39-01-12-3D (#8d9)                       0x00000021 (Private, InitOnly)         nil          n/a     0
 3: 'aggregator' (#111f)   06-12-41 (#8e1)                                   0x00000021 (Private, InitOnly)         nil          n/a     0
...[생략]...
13: '<>4__this' (#140a)    06-12-08 (#95b)                                   0x00000006 (Public)                    nil          n/a     0
14: 'displayTable' (#425)  06-02 (#95f)                                      0x00000006 (Public)                    nil          n/a     0
15: 'args' (#1405)         06-1D-0E (#962)                                   0x00000006 (Public)                    nil          n/a     0

Method (0x06, 0x1C):
=======================================================================================================================================================================================================================================================================================================================
    Name                                   Signature                                                        RVA         Parameters             GenericParameters      ImplAttributes                                                                     Attributes  ImportAttributes  ImportName  ImportModule
=======================================================================================================================================================================================================================================================================================================================
 1: '.ctor' (#1144)                        20-02-01-12-35-15-12-39-01-12-3D (#966)                          0x00002050  0x08000001-0x08000002  nil                    0x00001881 (PrivateScope, Private, HideBySig, SpecialName, RTSpecialName)          0           0                 nil         nil
 2: '.ctor' (#1144)                        20-02-01-12-3D-12-35 (#972)                                      0x000020DD  0x08000003-0x08000004  nil                    0x00001886 (PrivateScope, Public, HideBySig, SpecialName, RTSpecialName)           0           0                 nil         nil
 3: '.ctor' (#1144)                        20-02-01-15-12-39-01-12-3D-12-35 (#97a)                          0x000020F9  0x08000005-0x08000006  nil                    0x00001886 (PrivateScope, Public, HideBySig, SpecialName, RTSpecialName)           0           0                 nil         nil
 4: 'VisualizeAllGenerations' (#1470)      20-00-01 (#6)                                                    0x00002108  nil                    nil                    0x00000086 (PrivateScope, Public, HideBySig)                                       0           0                 nil         nil
...[생략]...
49: '<TokenList>b__0' (#11e)               20-01-0E-11-80-89 (#a55)                                         0x0000487A  0x08000033-0x08000033  nil                    0x00000083 (PrivateScope, Assembly, HideBySig)                                     0           0                 nil         nil
4a: '.ctor' (#1144)                        20-00-01 (#6)                                                    0x00004893  nil                    nil                    0x00001886 (PrivateScope, Public, HideBySig, SpecialName, RTSpecialName)           0           0                 nil         nil
4b: '<Main>b__0' (#113)                    20-01-02-0E (#a5c)                                               0x0000489C  0x08000034-0x08000034  nil                    0x00000083 (PrivateScope, Assembly, HideBySig)                                     0           0                 nil         nil

Param (0x08):
=====================================================================================
    Name                       Seq#  Attributes                         Marshalling
=====================================================================================
 1: 'writer' (#108a)           1     0                                  nil
 2: 'readers' (#152b)          2     0                                  nil
...[생략]...
31: 'h' (#afc)                 1     0                                  nil
32: 'h' (#afc)                 1     0                                  nil
33: 'h' (#afc)                 1     0                                  nil
34: 'x' (#1781)                1     0                                  nil

MemberRef (0x0a):
============================================================================================================================================================
     Parent                 Name                                         Signature
============================================================================================================================================================
  1: 0x01000001 (TypeRef)   '.ctor' (#1144)                              20-01-01-08 (#1)
  2: 0x01000002 (TypeRef)   '.ctor' (#1144)                              20-00-01 (#6)
  3: 0x01000003 (TypeRef)   '.ctor' (#1144)                              20-01-01-11-11 (#a)
...[생략]...
13d: 0x01000022 (TypeRef)   'op_Implicit' (#1633)                        00-01-11-49-11-80-89 (#8b2)
13e: 0x01000072 (TypeRef)   'Equals' (#1414)                             00-03-02-0E-0E-11-82-71 (#8ba)

Constant (0x0b):
=================================================================
   Parent              Type                  Value
=================================================================
1: 0x08000007 (Param)  0x00000008 (Int32)    FF-FF-FF-FF (#8cc)
2: 0x0800001c (Param)  0x00000002 (Boolean)  01 (#8d1)
3: 0x08000021 (Param)  0x00000002 (Boolean)  00 (#8d3)

CustomAttribute (0x0c):
=========================================================================================================================================================================================================================
    Parent                 Constructor             Value
=========================================================================================================================================================================================================================
 1: 0x20000001 (Assembly)  0x0a000001 (MemberRef)  01-00-08-00-00-00-00-00 (#a65)
 2: 0x20000001 (Assembly)  0x0a000002 (MemberRef)  01-00-01-00-54-02-16-57-72-61-70-4E-6F-6E-45-78-63-65-70-74-69-6F-6E-54-68-72-6F-77-73-01 (#a6e)
...[생략]...
 d: 0x02000007 (TypeDef)   0x0a00000c (MemberRef)  01-00-00-00 (#b12)
 e: 0x08000008 (Param)     0x0a00000b (MemberRef)  01-00-00-00 (#b12)
 f: 0x08000009 (Param)     0x0a00000b (MemberRef)  01-00-00-00 (#b12)

StandAloneSig (0x11):
===================================================================================================
    Signature
===================================================================================================
 1: 07-02-02-15-12-4D-01-12-3D (#24)
 2: 07-02-08-02 (#d7)
 3: 07-01-02 (#ef)
...[생략]...
2b: 07-0A-12-1C-02-1D-0E-08-0E-12-81-B1-12-81-B5-12-3D-12-08-12-81-B9 (#80f)
2c: 07-02-11-5D-08 (#866)

Property (0x15, 0x17, 0x18):
===============================================================
   Name              Get                     Set  Attributes
===============================================================
1: 'IsDelta' (#26a)  0x06000006 (MethodDef)  nil  0

TypeSpec (0x1b):
===============================================
    Name
===============================================
 1: 15-12-79-01-1E-00 (#15)
 2: 15-12-81-9D-01-11-49 (#1c)
...[생략]...
19: 15-12-80-81-02-11-81-AD-11-49 (#726)
1a: 15-12-80-81-02-0E-02 (#826)

Assembly (0x20):
======================================================================================================
   Name                                     Version  Culture  PublicKey  Flags  HashAlgorithm
======================================================================================================
1: 'Microsoft.Metadata.Visualizer' (#10c7)  1.0.0.0  nil      nil        0      0x00008004 (Sha1)

AssemblyRef (0x23):
=======================================================================================================
   Name                                    Version   Culture  PublicKeyOrToken                Flags
=======================================================================================================
1: 'System.Runtime' (#780)                 4.1.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0
2: 'System.IO' (#22a)                      4.1.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0
3: 'System.Reflection.Metadata' (#236)     1.3.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0
...[생략]...
a: 'System.Reflection.Primitives' (#13b2)  4.0.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0
b: 'System.Console' (#74b)                 4.0.0.0   nil      B0-3F-5F-7F-11-D5-0A-3A (#8c3)  0

GenericParam (0x2a):
================================================================
   Name               Seq#  Attributes  TypeConstraints
================================================================
1: 'TEntity' (#17fa)  0     0           nil
2: 'T' (#234)         0     0           0x2c000001-0x2c000001
3: 'THandle' (#48b)   0     0           nil

MethodSpec (0x2b):
===============================================================
    Method                  Signature
===============================================================
 1: 0x0a000010 (MemberRef)  0A-01-12-3D (#53)
 2: 0x0a000015 (MemberRef)  0A-02-12-3D-15-11-45-01-11-49 (#b2)
 3: 0x0a000016 (MemberRef)  0A-01-15-11-45-01-11-49 (#ce)
 4: 0x0a00001a (MemberRef)  0A-01-12-3D (#53)
 5: 0x0a00001a (MemberRef)  0A-01-1D-0E (#106)
...[생략]...
13: 0x06000016 (MethodDef)  0A-01-11-81-AD (#731)
14: 0x0a00012c (MemberRef)  0A-01-0E (#842)
15: 0x0a000016 (MemberRef)  0A-01-11-49 (#1cd)

GenericParamConstraint (0x2c):
====================================================
   Parent                     Type
====================================================
1: 0x2a000002 (GenericParam)  0x1b000001 (TypeSpec)

#US (size = 2816):
  0: ''
  1: '>>>'
  9: '>>> Generation {0}:'
  31: '  '
  37: 'x'
  3b: ': '
...[생략]...
  af2: '''
  af6: '{'
  afa: '}'
  afe: ''
  aff: ''

#String (size = 6160):
  0: ''
  1: '<>9__20_0'
  b: '<Literal>b__20_0'
  1c: '<>c__DisplayClass0_0'
  31: '<>9__21_0'
  3b: '<Literal>b__21_0'
...[생략]...
  17cc: 'Any'
  17d0: 'EditAndContinueLogEntry'
  17e8: 'WriteDeclSecurity'
  17fa: 'TEntity'
  1802: 'WriteProperty'

#Blob (size = 2840):
  0:
  1: 20-01-01-08
  6: 20-00-01
  a: 20-01-01-11-11
  10: 20-01-01-0E
  15: 15-12-79-01-1E-00
  1c: 15-12-81-9D-01-11-49
  24: 07-02-02-15-12-4D-01-12-3D
...[생략]...
  afa: 01-00-07-31-2E-30-2E-30-2E-30-00-00
  b07: 01-00-05-31-2E-30-2E-30-00-00
  b12: 01-00-00-00
  b17:

#Guid (size = 16):
  1: {5592d697-bdc0-4859-aced-22e20a3efaee}




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]





[최초 등록일: ]
[최종 수정일: 6/26/2019 ]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer@outlook.com

비밀번호

댓글 쓴 사람
 



2020-08-01 10시46분
[이동우] 우연찮게 둘렀다가 잘보고갑니답!
[손님]

... [16]  17  18  19  20  21  22  23  24  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
12011정성태8/27/20191713사물인터넷: 57. C# - Rapsberry Pi Zero W와 PC 간 Bluetooth 통신 예제 코드파일 다운로드1
12010정성태8/27/20191271VS.NET IDE: 138. VSIX - DTE.ItemOperations.NewFile 메서드에서 템플릿 이름을 다국어로 설정하는 방법
12009정성태8/26/20191324.NET Framework: 858. C#/Windows - Clipboard(Ctrl+C, Ctrl+V)가 동작하지 않는다면?파일 다운로드1
12008정성태8/26/20191251.NET Framework: 857. UWP 앱에서 SQL Server 데이터베이스 연결 방법
12007정성태8/24/20191322.NET Framework: 856. .NET Framework 버전을 올렸을 때 오류가 발생할 수 있는 상황
12006정성태8/23/20192752디버깅 기술: 129. guidgen - Encountered an improper argument. 오류 해결 방법 (및 windbg 분석) [1]
12005정성태8/13/20192357.NET Framework: 855. 닷넷 (및 VM 계열 언어) 코드의 성능 측정 시 주의할 점 [2]파일 다운로드1
12004정성태8/12/20193060.NET Framework: 854. C# - 32feet.NET을 이용한 PC 간 Bluetooth 통신 예제 코드
12003정성태8/12/20191907오류 유형: 564. Visual C++ 컴파일 오류 - fatal error C1090: PDB API call failed, error code '3'
12002정성태8/12/20191670.NET Framework: 853. Excel Sheet를 WinForm에서 사용하는 방법 - 두 번째 이야기 [5]
12001정성태8/10/20192340.NET Framework: 852. WPF/WinForm에서 UWP의 기능을 이용해 Bluetooth 기기와 Pairing하는 방법
12000정성태8/9/20191753.NET Framework: 851. WinForm/WPF에서 Console 창을 띄워 출력하는 방법파일 다운로드1
11999정성태8/1/20191154오류 유형: 563. C# - .NET Core 2.0 이하의 Unix Domain Socket 사용 시 System.IndexOutOfRangeException 오류
11998정성태7/30/20191441오류 유형: 562. .NET Remoting에서 서비스 호출 시 SYN_SENT로 남는 현상파일 다운로드1
11997정성태7/30/20192014.NET Framework: 850. C# - Excel(을 비롯해 Office 제품군) COM 객체를 제어 후 Excel.exe 프로세스가 남아 있는 문제파일 다운로드1
11996정성태7/25/20192100.NET Framework: 849. C# - Socket의 TIME_WAIT 상태를 없애는 방법파일 다운로드1
11995정성태7/23/20191783.NET Framework: 848. C# - smtp.daum.net 서비스(Implicit SSL)를 이용해 메일 보내는 방법
11994정성태10/22/20192071개발 환경 구성: 454. Azure 가상 머신(VM)에서 SMTP 메일 전송하는 방법파일 다운로드1
11993정성태7/22/20191274오류 유형: 561. Dism.exe 수행 시 "Error: 2 - The system cannot find the file specified." 오류 발생
11992정성태7/22/20191356오류 유형: 560. 서비스 관리자 실행 시 "Windows was unable to open service control manager database on [...]. Error 5: Access is denied." 오류 발생
11991정성태7/18/2019910디버깅 기술: 128. windbg - x64 환경에서 닷넷 예외가 발생한 경우 인자를 확인할 수 없었던 사례
11990정성태3/16/20201874오류 유형: 559. Settings / Update & Security 화면 진입 시 프로그램 종료
11989정성태7/18/20191023Windows: 162. Windows Server 2019 빌드 17763부터 Alt + F4 입력시 곧바로 로그아웃하는 현상
11988정성태7/18/20191738개발 환경 구성: 453. 마이크로소프트가 지정한 모든 Root 인증서를 설치하는 방법
11987정성태7/17/20195134오류 유형: 558. 윈도우 - KMODE_EXCEPTION_NOT_HANDLED 블루스크린(BSOD) 문제
11986정성태7/18/20191091오류 유형: 557. 드라이브 문자를 할당하지 않은 파티션을 탐색기에서 드라이브 문자와 함께 보여주는 문제
... [16]  17  18  19  20  21  22  23  24  25  26  27  28  29  30  ...