그래서 여기 내 작업에서 다른 프로젝트에서 사용되는 DLL을 가져 오는 WPF 프로젝트가 있습니다. 의존성이 혼란 스럽습니다. 여기에이 기술을 사용했습니다 : http://www.digitallycreated.net/Blog/61/combining-multiple-assemblies-into-a-single-exe-for-a-wpf-application 종속성을 단일 실행 파일에 포함 시키십시오.Assembly.Load (byte())를 호출 할 때 AssemblyResolve 이벤트가 발생합니다.
이제 종속성 내부에서 특정 메서드를 호출하면 AssemblyResolve 이벤트가 발생합니다. 내 OnResolveAssembly 이벤트가 실행되면 어셈블리가 포함 된 리소스 (멋진 버전)로 어셈블리를 찾고 "Assembly.Load (assembyRawBytes)"를 반환합니다. 이 시점에서 (OnResolveAssembly 시작 부분에 중단 점을 사용하여) F11을 누르면, 또 같은 이벤트가 호출됩니다. 그것은 같은 어셈블리를 위해서도 사용됩니다 (args.Name은 동일합니다).
이 재귀 이벤트 호출을 피할 수 없기 때문에이 스택을 오버플로 할 수 있습니다.
MSDN 문서는 실제로 FileNotFoundException 또는 BadImageFormatException을 제외하고 Assembly.Load가 실패 할 수 있다고 말하지 않습니다.
Assembly.Load를 호출하기 전에 내가 OnResolveAssembly를 언인 킹하려고했지만 VS에서 신비한 죽음이 생겼다. 멍청이.
여기에 몇 가지 규칙이 있지만 아마도 문제를 찾기 시작할 수있는 몇 가지 아이디어가 좋을 것입니다.
문제가있는 DLL에서 무엇이 잘못 되었는가에 대한 힌트가 있는지 살펴볼 것입니다 (혼합 어셈블리일까요?).
가 여기 내 OnResolveAssembly 핸들러의 : 당분간
private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
AssemblyName assemblyName = new AssemblyName(args.Name);
string path = assemblyName.Name + ".dll";
if (assemblyName.CultureInfo.Equals(System.Globalization.CultureInfo.InvariantCulture) == false)
{
path = String.Format(@"{0}\{1}", assemblyName.CultureInfo, path);
}
using (Stream stream = executingAssembly.GetManifestResourceStream(path))
{
if (stream == null)
return null;
byte[] assemblyRawBytes = new byte[stream.Length];
stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length);
assemblyDictionary.Add(assemblyName.Name, Assembly.Load(assemblyRawBytes));
return assemblyDictionary[assemblyName.Name];
}
}
, 나는 (내 모든 리소스를 반복하고 그들에 Assembly.Load을 시도하고, 검색을 위해 사전에 저장하여 해결했습니다)이 OnResolveAssembly 이벤트 기간 동안 :
[STAThread]
public static void Main()
{
AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
Assembly executingAssembly = Assembly.GetExecutingAssembly();
string[] resources = executingAssembly.GetManifestResourceNames();
foreach (string resource in resources)
{
if (resource.EndsWith(".dll"))
{
using (Stream stream = executingAssembly.GetManifestResourceStream(resource))
{
if (stream == null)
continue;
byte[] assemblyRawBytes = new byte[stream.Length];
stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length);
try
{
assemblyDictionary.Add(resource, Assembly.Load(assemblyRawBytes));
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print("Failed to load: " + resource + " Exception: " + ex.Message);
}
}
}
}
App.Main();
}
private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
AssemblyName assemblyName = new AssemblyName(args.Name);
string path = assemblyName.Name + ".dll";
if (assemblyDictionary.ContainsKey(path))
{
return assemblyDictionary[path];
}
return null;
}
그것은 (이하 "실패"어셈블리) 내 두 번째 조각에서 미세한로드 지금 잘 작동 할 것 같다,하지만 나는 그것이 작동하지 않는 이유를 배우고 싶네 먼저.
코드 스 니펫이 필요합니다. –
내가 찾은 내 코드와 해결 방법이 추가되었습니다. –
@JonathanYee AssemblyResolve가 Assembly.Load (byte []) 호출에서 실제로 발생합니까? 이것은 내가 정확히 [여기] (http://stackoverflow.com/questions/24718917/can-a-call-to-assembly-loadbyte-raise-the-appdomain-assemblyresolve-event)를 찾고있는 경우입니다. 나는 그런 예를 만들 수 없었다. 자세한 내용을 알려 주실 수 있습니까? –