출처 : http://www.serious-code.net/moin.cgi/RedistributingVisualCppRunTimeLibrary
1 개요
- VisualCpp 8.0부터 뭔가 배포가 귀찮아졌다.
A required .DLL file, "MSVCR80.dll" was not found.
app.exe has failed to start because the application configuration is incorrect.
응용프로그램 구성이 올바르지 않기 때문에 이 응용 프로그램을 시작하지 못했습니다. 이 문제를 해결하려면 응용 프로그램을 다시 설치하십시오.
2 Side-by-side Assembly
- DLL 충돌 문제 때문에 마이크로소프트가 Side-by-side Assembly인지 뭔지를 만들었다. 같은 컴퓨터 안에서 여러 버전의 DLL을 동시에 실행할 수 있도록 해주는 기능인 모양이다. 즉 각각의 애플리케이션에게 독립적인 DLL 환경을 보장해준다는 말이다. 이 파일들은 \Windows\WinSxS 디렉토리에 존재한다. Side-by-side Assembly가 무엇인지는 .NET 어셈블리 쪽을 참고하기 바란다.
어쨌든 이것 때문에 기존 방식(배포할 애플리케이션과 같은 디렉토리에 VisualCpp 런타임 DLL을 같이 넣어두기)이 통하지 않게 되었다. 애플리케이션을 정상적으로 돌아가게 하기 위해서는 이 Side-by-side DLL들을 배포하고, 뭔가 레지스트리를 잔뜩 건드려야한다.
3 해결 방안
3.1 윈도우즈 인스톨러를 이용해 셋업 프로젝트를 만든다
- 아. 짱나.
3.2 VC 8.0 안에 있는 셋업 파일을 같이 배포한다
- "...\Microsoft Visual Studio 8\SDK\v2.0\Bootstrapper\Packages\vcredist_x86\vcredist_x86.exe"
- 또는 웹에서 다운로드받는다.
Visual C++ 2005 Redistributable Package (x86)
Visual C++ 2005 Redistributable Package (x64)
Visual C++ 2005 Redistributable Package (ia64)
Visual C++ 2005 SP1 Redistributable Package (x86)
Visual C++ 2005 SP1 Redistributable Package (x64)
Visual C++ 2005 SP1 Redistributable Package (ia64)
- 위 파일을 먼저 설치한 후, 원래 애플리케이션을 돌리면 된다. 그런데 이상하게 인스톨 화면도 딱히 없고, 프로세스 창에 msiexec.exe가 반응이 없는 채로 상당 시간 떠 있는 것을 볼 수 있다. 뭐 어쨌든 설치는 되더라. 비교적 간단한 방법이기는 하지만 이넘을 실행시키기 위해 필요한 것들이 많다는 게 문제다.
from http://www.codeproject.com/useritems/vcredists_x86.asp
OS | Installable | Required Service Pack | Other Software |
---|---|---|---|
Windows 3.x/NT/95 | No | N/A | N/A |
Windows 98/ME | Yes | Internet Explorer 5.0 required (included in Win98SE/ME) | Windows Installer 2.0 required |
Windows 2000 | Yes | Service Pack 3 required (includes Windows Installer 2.0) | Windows Installer 3.0 required |
Windows XP | Yes | Service Pack 2 Recommended | Windows Installer 3.0 required (included in Service Pack 2) |
Windows Server 2003 | Yes | Service Pack 1 Recommended | Windows Installer 3.0 required (Windows Installer 3.1 included in Service pack 1) |
Windows Vista | Yes | None | None |
3.3 Private Assembly를 설치한다
- 실행 파일 자체와 실행 파일에서 액세스하는 DLL들에 대한 manifest 파일들을 private assembly로서 같이 배포하면, 에러를 피할 수 있다. 실행 파일의 manifest 파일은 오브젝트 파일 생기는 디렉토리 잘 뒤져보면 있을 것이다. 대충 아래와 같은 내용이다.
XXX.exe.manifest
<?xml version='1.0' encoding='UTF-8' standalone='yes'?> <assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.VC80.MFC' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> </dependentAssembly> </dependency> </assembly>
그 다음 각각의 어셈블리, 즉 DLL에 대한 manifest 파일도 같이 배포해야 한다. (이 파일들은 기본적으로 ...\Microsoft Visual Studio 8\VC\redist 디렉토리 아래에 각 플랫폼 별로 존재한다.)
Microsoft.VC80.CRT.manifest
<?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.VC80.CRT" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" /> <file name="msvcr80.dll"/> <file name="msvcp80.dll"/> <file name="msvcm80.dll"/> </assembly>Microsoft.VC80.MFC.manifest
<?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.VC80.MFC" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" /> <file name="mfc80.dll"/> <file name="mfc80u.dll"/> <file name="mfcm80.dll"/> <file name="mfcm80u.dll"/> </assembly>이 manifest 파일과 DLL 파일들을 애플리케이션 실행 파일이 존재하는 디렉토리에 같이 넣어두면, 별도의 셋업 없이도 실행이 된다. 문제는 이렇게 했을 때, 저 DLL들의 새 버전이 나와도 XXX.exe는 이 혜택을 받을 수 없다는 점이다.
3.4 .NET framework 2.0을 설치한다
- 다운 열라 받아야함...
3.5 CRT 소스를 이용해 커스텀 CRT를 빌드한다
- 빌드한 파일을 마이크로소프트에서 배포하는 이름과 똑같은 이름으로 배포하면 법에 저촉되는 모양이다. 사실 빌드하기도 귀찮다.
3.6 정적 링크를 이용한다
- C/C++ > Code Generation 항목에서 DLL 버전 말고 정적 CRT를 사용하도록 한다. 제일 간단한 방법이기는 하지만, 온라인 게임 클라이언트 같은 경우에는 매번 업데이트 때마다 커다란 크기의 실행 파일을 다운로드받아야하는 단점이...
4 링크
- Bootstrapper for the VC++ 2005 Redists (with MSI 3.1)
- Visual C++ Deployment (C++)
- Visual C++ 배포 예제
- How to redistribute the Visual C++ Libraries with your application
- Visual C++ Libraries DLL Deployment
- How to build the 8.0 MFC and CRT DLLs with MSLU
- Redistributing Visual C++ Libraries
- Running C++ application built by VC++ Express on another computer
- Q&A on adapting VS2005 SP1 to build your applications
- How to silently install the VC++ runtime files redistributable package
- How to detect the presence of the VC 8.0 runtime redistributable package Updated VC 8.0 runtime redistributable packages are included in Visual Studio 2005 SP1
- How to detect whether or not the VS 2005 SP1 version of the VC++ runtime files redistributable package is installed on a system
- Building an MSI using WiX v3.0 that includes the VC 8.0 runtime merge modules
- http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=149470&SiteID=1
- http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=164465&SiteID=1
- see also VisualCpp