성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] The Windows Registry Adventure #1: ...
[정성태] systemd for Developers I ; https:/...
[정성태] 엄밀히 object 타입의 인스턴스가 다른 타입으로 형변환 가능...
[정성태] 아래의 글에서 나오는 "Windows Application Pa...
[정성태] The history of calling conventions,...
[정성태] Secure and Deploy .NET Windows Form...
[정성태] Get Started with Milvus Vector DB i...
[정성태] cyberark/PipeViewer - A tool that...
[정성태] WinForms in a 64-Bit world – our st...
[정성태] 예제에서 SELECT_SQL도 내부적으로는 SqlCommand/...
글쓰기
제목
이름
암호
전자우편
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'>supportedRuntime 옵션과 System.BadImageFormatException 예외</h1> <p> 최근에 다음과 같은 오류를 만났습니다.<br /> <br /> <img alt='badformat_appconfig_1.png' src='/SysWebRes/bbs/badformat_appconfig_1.png' /><br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> <span style='color: blue; font-weight: bold'>Unhandled Exception: System.BadImageFormatException: Could not load file or assembly</span> 'ConsoleApplication1.exe' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.<br /> File name: 'ConsoleApplication1.exe'<br /> </div><br /> <br /> 머리로는 <a target='tab' href='http://www.sysnet.pe.kr/2/0/519'>BadImageFormatException이 x86/x64의 불일치에서 오는 문제</a>라고만 생각하고 있어서 제법 애를 먹었는데요. 원인은, .NET 4.0 대상으로 빌드한 응용 프로그램에 다음과 같은 <a target='tab' href='https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/startup/supportedruntime-element'>supportedRuntime 정책</a>을 적용했기 때문이었습니다.<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"?> <configuration> <startup> <span style='color: blue; font-weight: bold'><supportedRuntime version="v2.0.50727"/> <supportedRuntime version="v4.0.30319"/></span> </startup> </configuration> </pre> <br /> 즉, 4.0으로 빌드한 경우 v2.0.50727 항목으로 인해 오류가 발생한 것입니다. 이를 해결하려면, 다음과 같이 순서를 바꾸는 것도 가능은 합니다.<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"?> <configuration> <startup> <span style='color: blue; font-weight: bold'><supportedRuntime version="v4.0.30319"/> <supportedRuntime version="v2.0.50727"/></span> </startup> </configuration> </pre> <br /> 그렇지만, 이런 식의 해결방법은 (동작은 하지만) 잘못 판단된 것입니다. 왜냐하면, 위의 프로그램을 .NET 2.0만 설치된 환경에서 실행하면 예외가 발생하기 때문입니다. 즉, 2.0의 supportedRuntime을 두 번째 선택으로 미뤄놓은 아무런 의미가 없는 것입니다.<br /> <a name='supportedRuntime'></a> <br /> 그렇다면, supportedRuntime이 언제 의미가 있는 것일까요?<br /> <br /> <hr style='width: 50%' /><br /> <br /> supportedRuntime은 사실, 하위 버전으로 빌드된 어셈블리를 상위버전의 환경에서 구동할 때 호환을 위해 명시해 주는 데 의미가 있습니다. 간단하게 예를 들어볼까요?<br /> <br /> 다음과 같은 Console 응용 프로그램을 만들고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > class Program { static void Main(string[] args) { Console.WriteLine(Environment.Version.ToString()); } } </pre> <br /> 이를 .NET 2.0으로 컴파일 합니다. 이 상태에서, 아래와 같은 app.config 구성으로 .NET 2.0/4.0이 모두 설치된 컴퓨터에서 실행하면 어떤 결과가 나올까요?<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"?> <configuration> <startup> <supportedRuntime version="v4.0.30319"/> <supportedRuntime version="v2.0.50727"/> </startup> </configuration> </pre> <br /> "v4.0.30319"가 위에 있으니 Environment.Version 출력값은 (제 컴퓨터 기준으로) "4.0.30319.239"입니다. 반면, 버전 번호의 자리를 바꿔서 출력하면 이번엔 "v2.0.50727"이 위에 있으므로 (제 컴퓨터 기준으로) "2.0.50727.5448" 결괏값이 나옵니다.<br /> <br /> 정리해 보면, supportedRuntime은 하위 버전의 응용 프로그램이 어떤 .NET Framework 런타임에서 실행할지를 결정하는 옵션입니다. 따라서, 처음 이 글의 문제로 돌아가서, supportedRuntime의 순서를 바꿀 것이 아니라 해당 응용 프로그램을 .NET 2.0 대상으로 빌드하는 것이 적절한 해결책입니다. (아니면, 아예 모든 supportedRuntime 옵션을 제거하든가.)<br /> <br /> 참고로, 기타 supportedRuntime의 종류에 관해서는 예전에 정리둔 것이 있으니 한번 봐두시는 것도 좋겠습니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > app.config의 supportedRuntime 종류 ; <a target='tab' href='http://www.sysnet.pe.kr/2/2/178'>http://www.sysnet.pe.kr/2/2/178</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> 간단한 문제를 내 볼까요? ^^ 그렇다면 .NET 2.0으로 빌드된 exe를 아무런 app.config 파일 없이 .NET 4.0만 설치된 컴퓨터에서 실행하면 어떻게 될까?<br /> <br /> 그런 경우, 다음과 같이 예외가 발생합니다.<br /> <br /> <img alt='badformat_appconfig_2.png' src='/SysWebRes/bbs/badformat_appconfig_2.png' /><br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET Framework Initialization Error Unable to find a version of the runtime to run this application. </pre> <br /> 만약, 이 응용 프로그램을 정상적으로 구동하고 싶다면 app.config에 다음과 같은 설정을 추가해 주면 됩니다.<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"?> <configuration> <startup> <supportedRuntime version="v4.0.30313"/> </startup> </configuration> </pre> <br /> 또 다른 경우를 생각해 볼까요? .NET 1.1 exe 파일을 .NET 1.1/4.0은 설치되었지만 .NET 2.0이 설치되지 않은 컴퓨터에서 다음과 같이 2.0을 지원한다고 지정해 두면 어떻게 될까요?<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"?> <configuration> <startup> <supportedRuntime version="v2.0.50727"/> </startup> </configuration> </pre> <br /> 이런 경우에도 역시 예외가 발생하면서 실행은 안되지만, 다행히 2.0을 설치할 것인지를 물어보는 대화상자가 뜹니다.<br /> <br /> <img alt='badformat_appconfig_3.png' src='/SysWebRes/bbs/badformat_appconfig_3.png' /><br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > To run this application, you first must install one of the following versions of the .NET Framework: v2.0.50727 Would you like to download and install version v2.0.50727 of the .NET Framework now? </pre> <br /> 이번엔 닷넷 프레임워크 버전 격차를 늘려서, .NET 1.1 exe 파일을 .NET 4.0만 설치된 컴퓨터에서 다음과 같이 4.0을 지원한다고 지정해 두면 어떻게 될까요?<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"?> <configuration> <startup> <supportedRuntime version="v4.0.30319"/> </startup> </configuration> </pre> <br /> 걱정하지 마세요. ^^ (대부분의 경우) 실행이 아주 잘됩니다. 여기서 supportedRuntime을 가장 극적으로 사용할 수 있는 사례가 나옵니다. 즉, .NET 1.x/2.0/3.0/3.5/4.0에 상관없이 실행되어야 할 프로그램을 만들어야 한다면 해당 응용 프로그램은 .NET 1.1 버전으로 빌드하고 다음과 같이 supportedRuntime 목록을 구성해 주면 되는 것입니다. <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"?> <configuration> <startup> <supportedRuntime version="v1.1.4322"/> <supportedRuntime version="v2.0.50727"/> <supportedRuntime version="v4.0.30319"/> </startup> </configuration> </pre> <br /> 또는 일반적으로 최신 버전의 닷넷 프레임워크가 성능이 더 나아지기 때문에 다중 CLR이 설치된 경우에는 가장 최신의 것을 적용받도록 다음과 같이 거꾸로 순서를 지정하는 것도 좋습니다.<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"?> <configuration> <startup> <supportedRuntime version="v4.0.30319"/> <supportedRuntime version="v2.0.50727"/> <supportedRuntime version="v1.1.4322"/> </startup> </configuration> </pre> <br /> 어떤 설정이든, .NET 1.1로 빌드된 응용 프로그램은 어떤 버전의 닷넷 프레임워크라도 설치되어 있으면 정상적으로 실행이 될 것입니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1504
(왼쪽의 숫자를 입력해야 합니다.)