C/C++ 격리된 응용 프로그램 및 side-by-side 어셈블리 문제 해결
업데이트: 2007년 11월
종속 Visual C++ 라이브러리를 찾을 수 없는 경우 C/C++ 응용 프로그램 로드에 실패할 수 있습니다. 발생 가능한 런타임 오류 목록은 Visual C++ 파일 재배포를 참조하십시오. 이 단원에서는 C/C++ 응용 프로그램 로드에 실패하는 가장 일반적인 이유에 대해 설명하고 문제를 해결하는 단계를 제공합니다.
Visual C++가 설치되어 있지 않은 컴퓨터에 응용 프로그램을 배포한 경우 Visual C++ 파일 재배포에 나열된 것과 비슷한 오류 메시지가 표시되면서 충돌이 발생하면 몇 가지 사항을 확인하여 오류의 원인을 파악해야 합니다.
Visual C++ 응용 프로그램의 종속성 이해에 설명된 단계를 수행합니다. Dependency Walker는 특정 응용 프로그램이나 DLL의 종속성 대부분을 표시할 수 있습니다. 누락된 DLL이 발견되면 응용 프로그램을 실행하려는 컴퓨터에 그러한 DLL을 설치하십시오.
운영 체제 로더에서는 매니페스트를 사용하여 응용 프로그램이 의존하는 어셈블리를 로드합니다. 매니페스트는 이진 파일 내에 리소스로 포함되거나 응용 프로그램 로컬 폴더에 외부 파일로 저장될 수 있습니다. 매니페스트가 이진 파일 내에 포함되어 있는지 여부를 확인하려면 이진 파일을 Visual Studio에서 열고 이진 파일의 리소스를 검색합니다. RT_MANIFEST라는 리소스를 찾을 수 있어야 합니다. 이진 파일 내에 포함된 매니페스트를 찾을 수 없는 경우 <binary_name>.<extension>.manifest와 유사한 이름의 외부 파일이 있는지 확인합니다.
매니페스트가 없는 경우 링커에서 프로젝트에 대한 매니페스트를 생성하도록 해야 합니다. 이 프로젝트에 대한 프로젝트 속성 대화 상자에서 매니페스트 생성 링커 옵션을 확인해야 합니다.
참고: 매니페스트를 생성하지 않고 Visual C++ 프로젝트를 빌드하는 기능은 지원되지 않습니다. Visual C++ 2005에서 빌드된 모든 C/C++ 프로그램은 Visual C++ 라이브러리에 대한 종속성을 설명하는 매니페스트를 포함해야 합니다.
이진 파일 내에 매니페스트가 포함된 경우 RT_MANIFEST의 ID가 이 형식의 이진 파일에 맞는지 확인합니다. 응용 프로그램의 경우 ID가 1이어야 하고, 대부분의 DLL의 경우 ID는 2여야 합니다. 매니페스트가 외부 파일에 있는 경우에는 XML 편집기나 일반 텍스트 편집기에서 이 파일을 엽니다. 매니페스트 및 배포 규칙에 대한 자세한 내용은 Manifests를 참조하십시오.
참고: Windows XP에서 응용 프로그램 로컬 폴더에 외부 매니페스트가 있는 경우 운영 체제 로더에서는 이진 파일 내에 포함된 매니페스트 대신 이 매니페스트를 사용합니다. Windows Server 2003 및 이후 버전의 Windows에서는 이와 반대로 포함된 매니페스트가 있는 경우 외부 매니페스트가 무시되고 포함된 매니페스트가 사용됩니다.
모든 DLL에 대해 매니페스트를 이진 파일에 포함하는 것이 좋습니다. LoadLibrary 호출을 통해 DLL이 로드되는 경우에는 외부 매니페스트가 무시됩니다. 자세한 내용은 Assembly manifests를 참조하십시오.
매니페스트에 열거된 모든 어셈블리가 컴퓨터에 제대로 설치되어 있는지 확인합니다. 매니페스트에서 각 어셈블리는 이름, 버전 번호 및 프로세서 아키텍처로 지정됩니다. 응용 프로그램이 side-by-side 어셈블리를 사용하는 경우 운영 체제 로더에서 Assembly Searching Sequence를 설명된 단계에 따라 검색할 수 있도록 어셈블리가 컴퓨터에 제대로 설치되어 있는지 확인합니다. 64비트 어셈블리는 32비트 프로세스에서 로드할 수 없고 32비트 운영 체제에서 실행될 수 없다는 점에 주의하십시오.
예제
Visual C++ 2005에서 빌드한 appl.exe라는 응용 프로그램이 있다고 가정합니다. 이 응용 프로그램의 매니페스트는 appl.exe 내에 ID가 1인 이진 리소스 RT_MANIFEST로 포함되어 있거나, 외부 파일인 appl.exe.manifest로 저장되어 있습니다. 매니페스트의 내용은 다음과 유사합니다.
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.xxxxx.y" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
이 매니페스트에서는 운영 체제 로더에 appl.exe가 버전이 9.0.xxxxx.y이고 32비트 x86 프로세서 아키텍처용으로 빌드된 Microsoft.VC90.CRT에 종속됨을 알려 줍니다.
종속 side-by-side 어셈블리는 공유 어셈블리 또는 전용 어셈블리로 설치될 수 있습니다. 예를 들어 Visual Studio 2005는 CRT 어셈블리를 Windows XP 환경에서는 %WINDIR%\WinSxS\x86_Microsoft.VC90.CRT_<version> 디렉터리에 또는 Windows Vista 환경에서는 %WINDIR%\winsxs\x86_microsoft.vc90.crt_<version> 디렉터리에 있는 공유 side-by-side 어셈블리로 설치합니다.
공유 Visual C++ CRT 어셈블리에 대한 assembly manifest도 Windows XP 환경에서는 %WINDIR%\WinSxS\Manifests\x86_microsoft.vc90.crt_<version>.manifest에 설치되고 Windows Vista 환경에서는 %WINDIR%\winsxs\Manifests\x86_microsoft.vc90.crt_<version>.manifest에 설치됩니다. 이 매니페스트는 어셈블리를 식별하고 어셈블리의 내용(이 어셈블리의 일부인 DLL)을 나열합니다.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<noInheritable/>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
<file name="msvcr90.dll" hash="3ca5156e8212449db6c622c3d10f37d9adb12c66" hashalg="SHA1"/>
<file name="msvcp90.dll" hash="92cf8a9bb066aea821d324ca4695c69e55b27cff" hashalg="SHA1"/>
<file name="msvcm90.dll" hash="7daa93e1195940502491c987ff372190bf199395" hashalg="SHA1"/>
</assembly>
또한 side-by-side 어셈블리는 정책 파일이라고도 하는 publisher configuration files를 사용하여 응용 프로그램 및 어셈블리에서 특정 버전의 side-by-side 어셈블리를 사용하지 않고 동일한 어셈블리의 다른 버전을 사용하도록 전역으로 리디렉션할 수 있습니다. 공유 Visual C++ CRT 어셈블리에 대한 정책은 Windows XP 환경에서는 %WINDIR%\WinSxS\Policies\x86_policy.9.0.Microsoft.VC90.CRT_<version>.policy에서, Windows Vista 환경에서는 %WINDIR%\winsxs\Manifests\x86_policy.9.0.microsoft.vc90.crt_<version>.manifest에서 확인할 수 있고 다음과 유사한 내용을 포함합니다.
</assembly>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Copyright © 1981-2001 Microsoft Corporation -->
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32-policy" name="policy.9.0.Microsoft.VC90.CRT" version="9.0.xxxxx.yy" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"/>
<bindingRedirect oldVersion="9.0.aaaaa.bbb-9.0.ccccc.d" newVersion="9.0.xxxxx.yy"/>
</dependentAssembly>
</dependency>
</assembly>
위 정책에서는 이 어셈블리의 9.0.aaaaa.bbb 버전을 요청하는 모든 응용 프로그램 및 어셈블리에서 컴퓨터에 설치된 최신 버전인 9.0.xxxxx.yy 버전 어셈블리를 대신 사용하도록 지정합니다. 응용 프로그램 매니페스트에 나오는 어셈블리 버전이 정책 파일에 지정된 경우 로더는 WinSxS 폴더에서 매니페스트에 지정된 버전의 어셈블리를 검색하고, 이 버전이 설치되어 있지 않으면 로드에 실패합니다. 어셈블리 버전 9.0.xxxxx.yy도 설치되지 않은 경우 어셈블리 버전 9.0.aaaaa.bbb을 요청하는 응용 프로그램의 로드는 실패합니다.
그러나 CRT 어셈블리를 응용 프로그램 로컬 폴더에 전용 side-by-side 어셈블리로 설치할 수도 있습니다. 운영 체제에서 CRT 또는 기타 어셈블리를 공유 어셈블리로 찾지 못하면 어셈블리를 전용 어셈블리로 검색하기 시작합니다. 다음과 같은 순서로 전용 어셈블리가 검색됩니다.
응용 프로그램 로컬 폴더에 <assemblyName>.manifest라는 이름의 매니페스트 파일이 있는지 확인합니다. 이 예제에서 로더는 appl.exe가 있는 폴더에서 Microsoft.VC90.CRT.manifest를 찾습니다. 매니페스트가 발견되면 로더는 응용 프로그램 폴더에서 CRT DLL을 로드합니다. CRT DLL을 찾을 수 없는 경우에는 로드에 실패합니다.
appl.exe 로컬 폴더에서 <assemblyName> 폴더를 열고 이 폴더가 존재하면 <assemblyName>.manifest를 이 폴더에서 로드합니다. 매니페스트가 발견되면 로더는 <assemblyName> 폴더에서 CRT DLL을 로드합니다. CRT DLL을 찾을 수 없는 경우에는 로드에 실패합니다.
로더에서 종속 어셈블리를 검색하는 방식에 대한 자세한 내용은 Assembly Searching Sequence를 참조하십시오. 로더에서 종속 어셈블리를 전용 어셈블리로 찾지 못하면 로드에 실패하고 "시스템이 지정된 프로그램을 실행할 수 없습니다."라는 메시지가 표시됩니다. 이 오류를 해결하려면 종속 어셈블리 및 이들 어셈블리의 일부인 DLL을 컴퓨터에 전용 또는 공유 어셈블리로 설치해야 합니다.
참고 항목
개념
격리된 응용 프로그램 및 side-by-side 어셈블리 개념