본문 바로가기

Microsoft/C# & ASP.NET

C# 어셈블리 묶기( .net DLL Merge)


참조 : http://bspfp.pe.kr/524


참조에서 제공하는 참조 

간단한 클래스 하나를 .NET DLL로 만들고 이를 사용하는 초간단 응용프로그램을 하나 만들었습니다.
그런데 매번 실행 파일과 DLL을 가지고 다니기가 너무 귀찮군요.
그래서 찾아보니 아래와 같은 자료가 있더군요.

[ILMerge 설명 페이지]
[ILMerge 다운로드 링크]

콘솔 응용 프로그램이군요.
아... 뭐 이리 복잡해!!!
그런데 위 페이지에 소개된 다른 방법도 있군요.

[MSDN Blogs 포스트]


IL Merge를 사용하지 않고 처리 하는 방법은 다음 과 같음 (MSDN Blogs 포스트 내용)


이 내용의 핵심은 단일 프로그램 또는 어셈블리에 참조하는 어셈블리를 리소스에 포함시켜 단일 프로그램으로 배포시키는데 목적이 있음.


테스트 구조는 다음과 같다.



MergeDLL 프로젝트는 testdll 프로젝트를 참조 하고 (솔루션 탐색기에서 프로젝트를 우클릭하여, 추가 > 기존항목 추가를 통해 DLL을 추가)

해당 testdll.dll을 리소스로 포함(testdll.dll 속성->빌드작업속성값 변경) 하여 빌드 한다.(Embedded Resource)

MergeDLL프로젝트 빌드시 "참조" 되는 testdll.dll 의 로컬 복사 속성을 False로 지정 한다.



아래의 소스크드를 보자

AppDomain.CurrentDomain.AssemblyResolve += (sender, bargs) =>
{
    string dllName = new AssemblyName(bargs.Name).Name + ".dll";
    var assem = Assembly.GetExecutingAssembly();
    string resourceName = null;
    foreach (string str in assem.GetManifestResourceNames())
    {
        if (str.IndexOf(dllName) != -1)
        {
            resourceName = str;
            break;
        }
    }
    if (resourceName == null) return null;
    using (var stream = assem.GetManifestResourceStream(resourceName))
    {
        Byte[] assemblyData = new Byte[stream.Length];
        stream.Read(assemblyData, 0, assemblyData.Length);
        return Assembly.Load(assemblyData);
    }

};

위 코드는 빌드 또는 프로그램이 실행될때 프로그램이 참조하는 어셈블리를 로드 할 수 없을 경우 AssemblyResolve 이벤트가 발생한다.

해당 이벤트가 발생 할 때 리소스의 어셈블리를 가져와 로드 시켜 주어 결과적으로 단일 프로그램으로 배포가 가능 하도록 만들어 준다.



테스트 Windows7 , Visual Studio 2012


테스트프로젝트

MergeDLL.zip