성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아래의 글을 보면, MoveWindow 하면 될 듯한데요. ^^...
[Tom Lee] 안녕하세요 올려주신 글 참고하여 WPF 어플리케이션 안에 Uni...
[정성태] A graphical depiction of the steps ...
[정성태] 질문을 주셔서 출판사 측에 문의를 했습니다. 약 한 달 정도 후...
[Thorondor
] @정성태 개인 블로그인데도 거의 커뮤니티 급 인 것 같아요. 요...
[정성태] Roll A Lisp In C - Reading ; https...
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>ASP.NET에서 System.BadImageFormatException 예외가 발생하는 경우</h1> <p> 대개, System.BadImageFormatException 예외가 발생하는 것은 플랫폼 설정이 맞지 않기 때문이고 이럴 때는 응용 프로그램이 정상적으로 실행되지 않을 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > System.BadImageFormatException ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/519'>http://www.sysnet.pe.kr/2/0/519</a> supportedRuntime 옵션과 System.BadImageFormatException 예외 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/1233'>http://www.sysnet.pe.kr/2/0/1233</a> </pre> <br /> 하지만, 때로는 <a target='tab' href='http://www.sysnet.pe.kr/2/0/510'>이 예외를 Thrown 설정으로 켜놓으면</a> 원치 않게 발생하는 경우도 있는데요. 예를 들어, 콜스택이 다음과 같은 상황으로 System.BadImageFormatException 예외가 발생할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > > mscorlib.dll!System.Reflection.RuntimeAssembly.nLoad(System.Reflection.AssemblyName fileName, string codeBase, System.Security.Policy.Evidence assemblySecurity, System.Reflection.RuntimeAssembly locationHint, ref System.Threading.StackCrawlMark stackMark, System.IntPtr pPrivHostBinder, bool throwOnFileNotFound, bool forIntrospection, bool suppressSecurityChecks) + 0x25 bytes mscorlib.dll!System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity, System.Reflection.RuntimeAssembly reqAssembly, ref System.Threading.StackCrawlMark stackMark, System.IntPtr pPrivHostBinder, bool throwOnFileNotFound, bool forIntrospection, bool suppressSecurityChecks) + 0x15c bytes mscorlib.dll!System.Reflection.RuntimeAssembly.InternalLoad(string assemblyString, System.Security.Policy.Evidence assemblySecurity, ref System.Threading.StackCrawlMark stackMark, System.IntPtr pPrivHostBinder, bool forIntrospection) + 0x54 bytes mscorlib.dll!System.Reflection.RuntimeAssembly.InternalLoad(string assemblyString, System.Security.Policy.Evidence assemblySecurity, ref System.Threading.StackCrawlMark stackMark, bool forIntrospection) + 0x17 bytes mscorlib.dll!System.Reflection.Assembly.Load(string assemblyString) + 0x1e bytes System.Web.dll!System.Web.Configuration.CompilationSection.LoadAssemblyHelper(string assemblyName, bool starDirective) + 0x27 bytes <span style='color: blue; font-weight: bold'>System.Web.dll!System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() + 0xc5 bytes </span> System.Web.dll!System.Web.Configuration.CompilationSection.LoadAssembly(System.Web.Configuration.AssemblyInfo ai) + 0x2e bytes System.Web.dll!System.Web.Configuration.AssemblyInfo.AssemblyInternal.get() + 0x1a bytes System.Web.dll!System.Web.Compilation.BuildManager.GetReferencedAssemblies(System.Web.Configuration.CompilationSection compConfig) + 0x8b bytes System.Web.dll!System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies() + 0x1a bytes System.Web.dll!System.Web.Compilation.BuildManager.CallPreStartInitMethods(string preStartInitListPath, out bool isRefAssemblyLoaded) + 0x70 bytes System.Web.dll!System.Web.Compilation.BuildManager.ExecutePreAppStart() + 0x7f bytes System.Web.dll!System.Web.Hosting.HostingEnvironment.Initialize(System.Web.Hosting.ApplicationManager appManager, System.Web.Hosting.IApplicationHost appHost, System.Web.Configuration.IConfigMapPathFactory configMapPathFactory, System.Web.Hosting.HostingEnvironmentParameters hostingParameters, System.Security.Policy.PolicyLevel policyLevel, System.Exception appDomainCreationException) + 0x2a3 bytes System.Web.dll!System.Web.Hosting.HostingEnvironment.Initialize(System.Web.Hosting.ApplicationManager appManager, System.Web.Hosting.IApplicationHost appHost, System.Web.Configuration.IConfigMapPathFactory configMapPathFactory, System.Web.Hosting.HostingEnvironmentParameters hostingParameters, System.Security.Policy.PolicyLevel policyLevel) + 0x18 bytes [Appdomain Transition] System.Web.dll!System.Web.Hosting.ApplicationManager.CreateAppDomainWithHostingEnvironment(string appId, System.Web.Hosting.IApplicationHost appHost, System.Web.Hosting.HostingEnvironmentParameters hostingParameters) + 0x157c bytes System.Web.dll!System.Web.Hosting.ApplicationManager.CreateAppDomainWithHostingEnvironmentAndReportErrors(string appId, System.Web.Hosting.IApplicationHost appHost, System.Web.Hosting.HostingEnvironmentParameters hostingParameters) + 0x25 bytes System.Web.dll!System.Web.Hosting.ApplicationManager.GetAppDomainWithHostingEnvironment(string appId, System.Web.Hosting.IApplicationHost appHost, System.Web.Hosting.HostingEnvironmentParameters hostingParameters) + 0x74 bytes System.Web.dll!System.Web.Hosting.ApplicationManager.CreateObjectInternal(string appId, System.Type type, System.Web.Hosting.IApplicationHost appHost, bool failIfExists, System.Web.Hosting.HostingEnvironmentParameters hostingParameters) + 0x48 bytes System.Web.dll!System.Web.Hosting.ProcessHost.StartApplication(string appId, string appPath, out object runtimeInterface) + 0x109 bytes [Native to Managed Transition] </pre> <br /> 보시면, bin 폴더의 모든 어셈블리를 로드하라는 메서드가 있는데 소스 코드를 보면 오류 원인을 알 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > internal Assembly[] LoadAllAssembliesFromAppDomainBinDirectory() { string binDirectoryInternal = HttpRuntime.BinDirectoryInternal; Assembly assembly = null; Assembly[] assemblyArray = null; if (System.Web.Util.FileUtil.DirectoryExists(binDirectoryInternal)) { <span style='color: blue; font-weight: bold'>FileInfo[] files = new DirectoryInfo(binDirectoryInternal).GetFiles("*.dll");</span> if (files.Length != 0) { ArrayList list = new ArrayList(files.Length); for (int i = 0; i < files.Length; i++) { string assemblyNameFromFileName = Util.GetAssemblyNameFromFileName(files[i].Name); if (!assemblyNameFromFileName.StartsWith("App_Web_", StringComparison.Ordinal)) { if (!this.GetAssembliesCollection().IsRemoved(assemblyNameFromFileName)) { assembly = this.LoadAssemblyHelper(assemblyNameFromFileName, true); } if (assembly != null) { list.Add(assembly); } } } assemblyArray = (Assembly[]) list.ToArray(typeof(Assembly)); } } if (assemblyArray == null) { assemblyArray = new Assembly[0]; } return assemblyArray; } </pre> <br /> 즉, bin 폴더의 모든 DLL을 로드해서 Assembly.Load를 해보는 것인데 만약 Native DLL이라도 있는 경우라면 여지없이 System.BadImageFormatException 예외가 발생합니다. 이것이 귀찮아서라도 System.BadImageFormatException 항목을 "Exception Settings"의 "Thrown" 항목에서 제외시켜야만 합니다.<br /> <br /> 다행히, 이를 비켜가는 방법이 있습니다. 이는 compilation 섹션에 의해 발생하는 것이므로 다음과 같이 원하는 항목에 대해 <remove />로 명시해 주면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <?xml version="1.0" encoding="utf-8"?> <configuration> ...[생략]... <system.web> ...[생략]... <compilation debug="true" targetFramework="4.0"> <assemblies> <span style='color: blue; font-weight: bold'><remove assembly="db2app"/></span> <remove assembly="Microsoft.VisualStudio.Web.PageInspector.Loader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <add assembly="System.Data.Entity.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> </assemblies> </compilation> ...[생략]... </system.web> ...[생략]... </configuration> </pre> <br /> 위의 설정에서는 db2app.dll 파일을 로드할 필요 없다는 것을 알립니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 그래도 ASP.NET 환경에서는 System.BadImageFormatException 예외가 발생하는 상황이 하나 더 있습니다. 예외 상황은 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > System.BadImageFormatException occurred HResult=-2146234344 Message=Could not load file or assembly 'file:///D:\....WebSiteTest4\bin\db2app.dll' or one of its dependencies. The module was expected to contain an assembly manifest. Source=mscorlib FileName=file:///D:\....WebSiteTest4\bin\db2app.dll FusionLog==== Pre-bind state information === LOG: Where-ref bind. Location = D:\....WebSiteTest4\bin\db2app.dll LOG: Appbase = file:///D:/....WebSiteTest4/ LOG: Initial PrivatePath = D:\....WebSiteTest4\bin Calling assembly : (Unknown). === LOG: This is an inspection only bind. LOG: Using application configuration file: D:\....WebSiteTest4\web.config LOG: Using host configuration file: C:\...\Documents\IISExpress\config\aspnet.config LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config. LOG: Attempting download of new URL file:///D:/....WebSiteTest4/bin/db2app.dll. ERR: Failed to complete setup of assembly (hr = 0x80131018). Probing terminated. StackTrace: at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) InnerException: </pre> <br /> 콜 스택은 이렇고.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > > mscorlib.dll!System.Reflection.RuntimeAssembly.nLoad(System.Reflection.AssemblyName fileName, string codeBase, System.Security.Policy.Evidence assemblySecurity, System.Reflection.RuntimeAssembly locationHint, ref System.Threading.StackCrawlMark stackMark, System.IntPtr pPrivHostBinder, bool throwOnFileNotFound, bool forIntrospection, bool suppressSecurityChecks) + 0x25 bytes mscorlib.dll!System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity, System.Reflection.RuntimeAssembly reqAssembly, ref System.Threading.StackCrawlMark stackMark, System.IntPtr pPrivHostBinder, bool throwOnFileNotFound, bool forIntrospection, bool suppressSecurityChecks) + 0x15c bytes mscorlib.dll!System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity, System.Reflection.RuntimeAssembly reqAssembly, ref System.Threading.StackCrawlMark stackMark, bool throwOnFileNotFound, bool forIntrospection, bool suppressSecurityChecks) + 0x1e bytes mscorlib.dll!System.Reflection.RuntimeAssembly.InternalLoadFrom(string assemblyFile, System.Security.Policy.Evidence securityEvidence, byte[] hashValue, System.Configuration.Assemblies.AssemblyHashAlgorithm hashAlgorithm, bool forIntrospection, bool suppressSecurityChecks, ref System.Threading.StackCrawlMark stackMark) + 0x69 bytes mscorlib.dll!System.Reflection.Assembly.ReflectionOnlyLoadFrom(string assemblyFile) + 0x24 bytes <span style='color: blue; font-weight: bold'>Microsoft.Owin.Host.SystemWeb.dll!Owin.Loader.DefaultLoader.GetDefaultConfigurationString(System.Func<System.Reflection.Assembly,string[]> defaultTypeNames) + 0x18a bytes Microsoft.Owin.Host.SystemWeb.dll!Owin.Loader.DefaultLoader.LoadImplementation(string startupName) + 0x69 bytes Microsoft.Owin.Host.SystemWeb.dll!Owin.Loader.DefaultLoader.Load(string startupName) + 0x13 bytes Microsoft.Owin.Host.SystemWeb.dll!Microsoft.Owin.Host.SystemWeb.OwinBuilder.Build() + 0x47 bytes </span> mscorlib.dll!System.Lazy<Microsoft.Owin.Host.SystemWeb.OwinAppContext>.CreateValue() + 0xa5 bytes mscorlib.dll!System.Lazy<Microsoft.Owin.Host.SystemWeb.OwinAppContext>.LazyInitValue() + 0x16f bytes mscorlib.dll!System.Lazy<Microsoft.Owin.Host.SystemWeb.OwinAppContext>.Value.get() + 0x79 bytes Microsoft.Owin.Host.SystemWeb.dll!Microsoft.Owin.Host.SystemWeb.OwinApplication.Instance.get() + 0x12 bytes Microsoft.Owin.Host.SystemWeb.dll!Microsoft.Owin.Host.SystemWeb.OwinHttpModule.Init(System.Web.HttpApplication context) + 0x2d bytes System.Web.dll!System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(System.IntPtr appContext, System.Web.HttpContext context, System.Reflection.MethodInfo[] handlers) + 0x1a7 bytes System.Web.dll!System.Web.HttpApplication.InitSpecial(System.Web.HttpApplicationState state, System.Reflection.MethodInfo[] handlers, System.IntPtr appContext, System.Web.HttpContext context) + 0xb8 bytes System.Web.dll!System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(System.IntPtr appContext, System.Web.HttpContext context) + 0x119 bytes System.Web.dll!System.Web.HttpApplicationFactory.GetPipelineApplicationInstance(System.IntPtr appContext, System.Web.HttpContext context) + 0x37 bytes System.Web.dll!System.Web.Hosting.PipelineRuntime.InitializeApplication(System.IntPtr appContext) + 0xab bytes [Appdomain Transition] [Native to Managed Transition] </pre> <br /> 원인은 Microsoft.Owin.Host.SystemWeb 어셈블리 때문인데요, 소스 코드는 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > internal static OwinAppContext Build() { string str = ConfigurationManager.AppSettings["owin:Configuration"]; DefaultLoader loader = new DefaultLoader(); return Build(loader.Load(str ?? string.Empty)); } public Action<IAppBuilder> Load(string startupName) => (this.LoadImplementation(startupName) ?? this._next(startupName)); private Action<IAppBuilder> LoadImplementation(string startupName) { if (string.IsNullOrWhiteSpace(startupName)) { startupName = GetDefaultConfigurationString(assembly => new string[] { "Startup", assembly.GetName().Name + ".Startup" }); } Tuple<Type, string> typeAndMethodNameForConfigurationString = GetTypeAndMethodNameForConfigurationString(startupName); if (typeAndMethodNameForConfigurationString == null) { return null; } ... } </pre> <br /> GetDefaultConfigurationString 메서드에서 역시 /bin 폴더의 모든 어셈블리를 로드해 보는 것이 문제인데요. 아쉽게도 이를 우회할 수 있는 공식적인 방법은 없습니다. 단지, 위의 소스 코드에서 볼 수 있듯이 Build 메서드에서 "owin:Configuration"의 결과에 따라 GetDefaultConfigurationString 메서드의 수행을 비켜갈 수 있기 때문에 OWIN을 쓰지 않는 경우라면 AppSettings에 다음과 같은 항목을 넣어주면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <?xml version="1.0" encoding="utf-8"?> <configuration> ...[생략]... <appSettings> <span style='color: blue; font-weight: bold'><add key="owin:Configuration" value="blah.blah" /></span> ...[생략]... </appSettings> ...[생략]... </configuration> </pre> <br /> value 문자열은 OWIN을 쓰지 않는 경우라면 무엇을 넣어도 상관없습니다. OWIN을 쓰는 경우라면 어떤지 모르겠지만, OWIN을 쓸 상황이라면 아마 대부분 native DLL을 사용하지 않을 것이므로 저런 문제가 발생하지는 않을 것입니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1139
(왼쪽의 숫자를 입력해야 합니다.)