일반적으로 프로그램을 배포시 exe파일과 Application이 호출하는 dll파일은 동일한 폴더(또는 dll 파일이 System폴더에 위치)에 있어야 한다.
Microsoft 공식 배포처에서는 exe와 호출하는 라이브러리를 병합하는 프로그램을 배포중이지만, 컴파일러단에서 자체 해결할 수 있는 방법도 존재한다.
- 사용하고자 하는 dll을 프로젝트에 참조
- 해당 dll을 프로젝트 리소스에 추가
- 리소스에 추가된 dll의 속성 -> 빌드작업 속성 값을 포함 리소스로 지정
- 프로그램 진입점(Program.cs)에 코드를 아래와 같이 변경
- 리소스에 dll 파일 포함하기
- dll 파일 => 속성 => 빌드작업 ++ 포함리소스로 변경
using System.Reflection;
using System.IO;
/// <summary>
/// 해당 응용 프로그램의 주 진입점입니다.
/// </summary>
[STAThread]
static void Main() {
// 리소스 dll 취득
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
// .NET 4.0 이상
static Assembly ResolveAssembly(object sender, ResolveEventArgs args) {
Assembly thisAssembly = Assembly.GetExecutingAssembly();
var name = args.Name.Substring(0, args.Name.IndexOf(',')) + ".dll";
var resources = thisAssembly.GetManifestResourceNames().Where(s => s.EndsWith(name));
if (resources.Count() > 0) {
string resourceName = resources.First();
using (Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) {
if (stream != null) {
byte[] assembly = new byte[stream.Length];
stream.Read(assembly, 0, assembly.Length);
Console.WriteLine("Dll file load : " + resourceName);
return Assembly.Load(assembly);
}
}
}
return null;
}
// LINQ가 지원되지 않는 .NET 버전
static Assembly ResolveAssembly(object sender, ResolveEventArgs args) {
Assembly thisAssembly = Assembly.GetExecutingAssembly();
string resourceName = null;
string fileName = args.Name.Substring(0, args.Name.IndexOf(',')) + ".dll";
foreach (string name in thisAssembly.GetManifestResourceNames()) {
if (name.EndsWith(fileName)) {
resourceName = name;
}
}
if (resourceName != null) {
using (Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) {
if (stream != null) {
byte[] assembly = new byte[stream.Length];
stream.Read(assembly, 0, assembly.Length);
Console.WriteLine("Dll file load : " + resourceName);
return Assembly.Load(assembly);
}
}
}
return null;
}