본문 바로가기

STUDY/ㄴ WINDOWS

The Desktop Files

Windows PE 확장
Wes Miller

적극적인 고객 중에는 5년 전 Windows PE를 릴리스하기 전부터 추가 기능을 요구하는 사람들이 있었습니다. 그러나 아쉽게도 Windows PE는 운영 체제 계층을 추가하는 방식으로 확장이 가능한 Windows XP Embedded처럼 확장이 용이하도록 설계되지 않았습니다. 물론 Windows PE도 기본적인 확장 기능은 제공합니다.

이러한 기본 기능에는 Windows® 응용 프로그램이 작동되도록 하는 Win32® 지원 기능, 네트워크를 통해 통신하고 Windows를 설치할 수 있는 네트워킹 및 대용량 저장소 지원 기능 등이 있습니다. 그러나 셸의 경우에는 처음부터 우리가 원하는 방식으로 구현하고자 했습니다. 때문에 기존의 Windows 탐색기 셸 대신 cmd.exe를 사용하여 Windows PE 환경에서 실행할 수 있는 작업을 제한했을 뿐만 아니라, 모든 자동 작업에 따라 기본 환경을 쉽게 스크립트로 작성할 수 있도록 셸을 만들었습니다.

하지만 Windows PE의 확장이 불가능한 것은 아니며 단지 그 범위가 제한될 뿐입니다. 예를 들면 그림 1(전체 목록은 아님)에 나열된 기술을 하나라도 요구하는 응용 프로그램은 작동하지 않거나 비정상적으로 작동할 수 있습니다.

따라서 응용 프로그램에서 요구하는 기술을 정확하게 파악해야 합니다. 어떻게 이를 파악할 수 있을까요? Windows PE를 릴리스하기 전에 ADO, HTA(HTML 응용 프로그램) 및 WSH(Windows 스크립트 호스트) 구성 요소가 Windows PE에서 작동하도록 만들려고 했을 때에도 이와 같은 문제에 직면했었습니다. 본 기사에서 이러한 종속성을 추적하는 방법을 설명하겠지만, MKIMG 명령의 범위를 벗어나서 Windows PE 이미지에 Windows 바이너리를 추가할 경우 EULA(최종 사용자 사용권 계약)에 위배된다는 점에 유의해야 합니다. 사용자 환경에서 이러한 변경 사항을 적용하려면 Microsoft로부터 추가 라이선스를 취득해야 합니다.


종속성 이해

응용 프로그램의 .inf 파일을 메모장에서 열고 주의 깊게 살펴보면 많은 것을 배울 수 있습니다. 실제로 이는 응용 프로그램을 이해하고 종속성을 파악하는 가장 손쉬운 방법입니다. 일반적으로 Windows PE는 많은 계층으로 이루어져 있기 때문에 응용 프로그램이 안정적으로 실행되도록 하려면 종속성을 여러 수준에 걸쳐 디버깅해야 합니다. 다시 말해 응용 프로그램의 고유한 직접적 종속성과 이러한 각 종속성으로 인해 부수적으로 발생하는 종속성을 해결해야 합니다. 따라서 주의를 기울이지 않으면 종속성이 단계적으로 매우 복잡해질 수 있습니다. 실수로, 또는 고의로 구성 요소를 몇 개만 추가해도 이미지의 크기와 복잡성이 크게 증대될 수 있습니다.

응용 프로그램을 설명하는 .inf 파일이 있는 경우 해당 .inf 파일에 의해 시스템에 추가되는 레지스트리 키와 파일을 확인하면 종속성을 파악하기 위한 단서를 얻을 수 있습니다. .inf 파일에서 CopyFiles 섹션과 AddReg 섹션을 살펴보면 됩니다. 이러한 항목은 응용 프로그램, DLL, 응용 프로그램이 종속된 기타 파일을 가리킵니다. Windows PE의 세 가지 추가 기능(ADO, HTA 및 WSH) 중에서 WSH가 가장 만들기 쉽습니다. 이전 Windows 버전의 경우 재배포 가능한 버전의 WSH가 아직 제공되며 Windows의 현재 버전에는 WSH의 파일 연결을 수행하는 .inf 파일(%windir%\inf\wsh.inf)이 포함되어 있기 때문에 Windows PE에 WSH를 비교적 간단하게 설치할 수 있습니다.


Orca 및 스냅숏

MSI(Microsoft® Installer) 파일로 배포되는 응용 프로그램의 경우 두 가지 방법으로 종속성을 파악할 수 있습니다. MSI에 익숙한 사용자는 Windows Server® 2003 R2 Platform SDK(http://go.microsoft.com/fwlink/?LinkId=77941)의 일부로 배포되는 Windows Installer 파일 편집 도구인 Orca를 사용하여 MSI를 볼 수 있습니다. 또한 원하는 구성 요소에 대해 MSI를 설치하고 변경된 파일 및 레지스트리 키를 변경되기 전과 비교하여 분석할 수도 있습니다. 레지스트리 덤프 작업을 수행하고 응용 프로그램을 설치한 후 레지스트리를 다시 내보내고 WinDiff를 실행하면 됩니다("WinDiff 사용" 추가 기사 참조). 이 실행 결과를 템플릿으로 활용하여 레지스트리에 필요한 변경을 수행할 수 있습니다. 문제는 변경 사항이 엄청나게 많아질 수 있다는 점입니다. 어쨌든 이 방법은 .inf를 사용할 수 없는 경우(또는 응용 프로그램 작성자의 도움을 받을 수 없는 경우)에 가장 바람직한 방법입니다.

응용 프로그램 스냅숏을 만드는 프로세스는 모두 잘 알고 있을 것입니다. 본질적으로 스냅숏을 만드는 과정은 응용 프로그램이 실행되도록 하기 위해 수행하는 변경 전후 비교 분석과 동일합니다. 예전에는 Microsoft에서 이러한 작업을 수행하는 도구를 배포했지만(Windows 2000의 경우) 이후 버전의 Windows에서는 이 도구가 작동하지 않습니다. 이 작업은 여러 가지 상업용 응용 프로그램(설치 파일 재포장기)은 물론, 일부 무료 유틸리티를 사용하여 수행할 수도 있습니다. WinDiff가 포함되어 있는 Platform SDK(이전 단락의 링크 참조)를 설치하는 것도 하나의 방법입니다. 원칙적으로 WinDiff 비교 작업을 수행하려면 Windows Server 2003 서비스 팩 1(SP1)에 응용 프로그램을 설치하는 것이 좋습니다. 왜냐하면 사용해야 하는 Windows PE 버전이 Standard Edition 또는 Enterprise Edition(SP1 포함)에서 빌드된 Windows PE 1.6이기 때문입니다. Windows Server 2003을 사용하면 Windows PE와 가장 유사한 환경(MSI를 실행할 수 없는 환경임)에서 이 작업을 수행할 수 있습니다. "WinDiff 사용" 추가 기사의 단계를 따르십시오.

그러면 상당히 많은 양의 변경된 정보가 표시됩니다. 그러나 애석하게도 응용 프로그램 설치에 사용할 일종의 매니페스트를 만들기 위해 레지스트리 또는 파일 캡처에서 변경된 정보를 내보내는 간단한 방법은 없으므로 변경 내용을 수동으로 통합해야 합니다. 첫 번째 버전의 Windows PE에서는 이와 관련하여 어려운 문제에 직면했었습니다. 즉, Microsoft 내에는 Internet Explorer® 외부의 HTA 구성 요소에 대한 정의가 없었기 때문에 해당 구성 요소를 제대로 작동하도록 만드는 것은 어려운 문제였습니다. 결국 차이점을 일일이 비교함으로써 HTA가 작동하도록 지원할 수 있었습니다. Windows PE 레지스트리에 이러한 키를 수동으로 추가할 수 있지만 이 경우 Windows PE를 시작한 후에 키를 추가하는 것이 좋습니다. Windows PE 빌드 도구에 포함된 buildoptionalcomponents.vbs 스크립트를 통해 HTA, WSH 및/또는 ADO 지원 기능을 Windows PE에 설치하는 데 사용된 OC.bat 파일과 OC2.bat 파일을 살펴볼 수 있습니다.


유용한 도구

직접적인 종속성은 격리했더라도, 응용 프로그램이 종속된 모든 바이너리를 찾을 수 없는 경우가 많습니다. 예를 들어 일부 작업을 수행하는 데 다른 DLL 또는 OCX가 필요한지 여부를 알 수 없습니다. 그렇다면 어떻게 확인할 수 있을까요? Sysinternals의 유명한 개발자였던 Mark Russinovich(현재는 Microsoft의 기술적 동료)는 바로 이러한 기능을 수행하는 listdlls라는 유용한 유틸리티를 만들었습니다. listdlls는 www.microsoft.com/technet/sysinternals/utilities/ListDlls.mspx(영문)에서 다운로드할 수 있습니다. 이 유틸리티를 사용하려면 listdlls.exe > dlls.txt 명령을 실행한 다음 출력된 내용을 살펴보면 됩니다. 그림 2는 listdlls 자체에 대한 출력을 보여 줍니다. 이 목록을 Windows PE에 포함된 DLL 파일 및 OCX 파일과 비교하면 응용 프로그램의 모든 종속성이 구현되어 있는지 여부를 확인할 수 있습니다. listdlls의 경우 이미 구현되어 있습니다. Windows PE의 HTA 지원의 경우 다른 방법으로는 파악할 수 없었던 일부 종속성을 listdlls로 파악할 수 있었습니다.

그림 2 Lisdlls를 자체적으로 실행한 경우의 출력
그림 2 Lisdlls를 자체적으로 실행한 경우의 출력 (Click the image for a smaller view)

그러나 단순히 이 출력에 나열된 DLL이라고 해서 응용 프로그램이 작동하는 데 꼭 필요한 것은 아닙니다. 예를 들어 메모장을 로드하면 uxtheme.dll이라는 파일이 로드됩니다. Windows PE에서는 이 DLL을 사용할 수 없으며, Windows 테마가 사용되지 않으므로 실제로는 로드되지 않습니다. listdlls에 표시되는 DLL 중 실제로 필요한 DLL과 Windows 요청에 따라 로드되는 DLL을 파악하려면 안타깝게도 많은 시행착오를 거치거나 Windows의 하위 수준에 익숙해져야 합니다. Mark Russinovich와 David Solomon의 공저인 Microsoft Windows Internals, Fourth Edition(Microsoft Press®, 2004)을 읽어 보면 이와 관련하여 많은 도움을 얻을 수 있습니다.

실제로 Mark는 Windows 작업 관리자를 대체하는 무료로 제공되는 Process Explorer에 동일한 기능을 포함시켰습니다. 필자의 개인적인 견해지만 listdlls와의 차이점이라면 누락된 종속성을 찾거나 수집하기 위해 사용하거나 스크립트를 작성하기에는 listdlls의 출력이 더 간편하다는 것입니다.

이미지에 DLL을 추가한 후에도 몇 가지 작업을 더 수행해야 합니다. 즉, 등록이 필요한 DLL과 등록이 필요 없는 DLL을 파악해야 합니다. 안타깝게도 DLL을 일일이 등록해 보는 방법 외에는 간단하게 이러한 두 가지 유형의 DLL을 구분할 수 있는 방법이 없습니다. DLL 또는 OCX를 등록하려면 regsvr32 dllname.dll을 실행해야 합니다. 이 파일이 올바르게 작동하면 DLL이 등록되었다는 메시지가 표시됩니다. 그렇지 않으면 메시지가 표시되지 않을 수도 있지만, DLL 등록에 실패했거나 등록할 수 없다는 메시지가 표시되는 경우가 많습니다. Windows PE용 HTA 및 ADO 선택 구성 요소를 개발하면서 발견한 사실 중 하나는 DLL을 등록할 때는 설치용 .inf 파일을 임시로 쓰거나 기타 종속성(예: DLL에 필요한 특정 디렉터리)을 기록하기 위해 쓰기 가능한 저장소가 필요하다는 점입니다. 예전에는 Windows PE에서 이는 곧 오류를 의미했습니다. 다행히 Windows PE 2.0에서는 스크래치 공간이 기본적으로 제공되므로 이러한 작업이 아무 문제 없이 이루어집니다.

Mark가 만들어 최근에 발표한 세 번째 도구가 있는데 바로 Process Monitor입니다. Process Monitor는 Regmon과 Filemon을 결합한 유틸리티라고 할 수 있지만 완전히 새로운 계층인 프로세스 간 통신 계층을 추가하여 이 두 유틸리티보다 훨씬 자세한 정보를 제공합니다. 이 강력한 도구를 사용하면 Windows에서 응용 프로그램의 문제를 해결할 수 있을 뿐만 아니라 DLL 상호 종속성과 관련하여 실제로 수행되는 작업에 대한 궁금증을 해결할 수 있습니다. Process Monitor는 인터넷을 통해 다운로드(영문)할 수 있습니다.


Windows PE 파일 제거

Windows PE를 확장하는 기능 외에도 Windows PE의 크기를 작게 만드는 방법에 대한 문의가 많았습니다. 몇 가지 단계에 따라 Windows PE의 크기를 다소 줄일 수 있습니다. 정식으로 사용이 허가된 Windows PE 복사본에는 몇 가지 빌드 도구 및 설명서가 포함되어 있습니다. 이러한 문서 중에는 winpe.chm이라는 도움말 파일도 있습니다. 이 파일을 열고 Windows Preinstallation Environment User’s Guide(Windows 사전 설치 환경 사용자 가이드) 섹션을 살펴보면 Reducing the Size of Windows PE(Windows PE 크기 축소)라는 항목이 있습니다. 이 섹션에는 필요 없는 경우 안전하게 제거할 수 있는 파일의 목록이 나와 있습니다. 다음 세 곳의 섹션에 제거 가능한 파일과 관련된 내용이 나옵니다.

  • 글꼴 파일은 항상 안전하게 제거할 수 있습니다.
  • 네트워킹 관련 .inf 파일과 유틸리티는 제거할 수 있지만 빌드를 네트워크에서 사용하지 않을 계획인 경우에 한합니다.
  • 명령줄 유틸리티는 제거해서는 안 됩니다. 이러한 유틸리티의 기능과 제거할 경우 발생할 결과를 정확히 알지 못할 경우에는 유틸리티를 제거하지 않는 것이 좋습니다.

안전하게 제거할 수 있는 파일이 확인되면 mkimg.cmd에 의해 빌드가 완성된 후 일괄 파일 또는 기타 스크립트를 작성하여 Windows PE 빌드에서 해당 파일을 제거할 수 있습니다.


Windows PE 레지스트리 수정

빌드 시간에 선택적 구성 요소를 설치하지 않기로 한 것은 의도적인 결정이었습니다. 이로 인해 런타임에 시간이 좀 더 걸리긴 하지만 이러한 구성 요소를 Windows PE에 통합하기 위해 완전히 새로운 방법을 개발할 필요가 없어졌습니다. 이럴 시간이 없기도 했지만 이로 인해 해당 구성 요소가 완전히 제외될 뻔했습니다. 그러나 응용 프로그램에 대한 레지스트리 변경의 델타를 추가하는 것과 같은 레지스트리 변경을 수행하거나, 응용 프로그램이 정상적으로 작동하는 데 필요한 키를 편집하려 한다면 어떨까요? 이러한 작업은 그림 3에 나와 있는 regedit를 사용하여 다음 단계에 따라 간단히 수행할 수 있습니다.

  1. regedit를 실행하고 HKEY_LOCAL_MACHINE 하이브를 선택합니다.
  2. 파일 | 하이브 로드를 선택한 다음 Windows PE 빌드 위치를 탐색합니다. I386\System32\(또는 하드 드라이브에 설치할 이미지인 경우 MiniNT\System32)에서 setupreg.hiv를 선택합니다.
  3. 하이브의 임시 이름을 WinPE와 같이 입력하고 HKLM에서 해당 노드로 이동합니다.
  4. 이 키를 적절하게 수정합니다. 흥미로운 것은 이 노드가 일반적인 Windows 설치의 HKLM\System 노드와 사실상 같다는 점입니다.
  5. 수정이 끝났으면 3단계에서 만든 키를 HKLM에서 선택합니다. 이 단계를 올바르게 수행하지 않으면 시스템이 손상될 수 있습니다.
  6. 파일 | 하이브 언로드…를 선택하고, 예 | 아니요 대화 상자에서 예를 선택하여 매번 레지스트리가 분리되도록 합니다. 레지스트리가 잠기면 Windows PE가 성공적으로 빌드되지 않습니다.
그림 3 Windows PE 레지스트리 열기
그림 3 Windows PE 레지스트리 열기 (Click the image for a smaller view)

다음 단계에 따라 HKLM\System을 수정할 수 있습니다. I386\System32에는 레지스트리의 다른 부분을 수정할 수 있는 또 다른 두 개의 키가 있습니다. 그 중 DEFAULT는 Windows PE를 실행하는 동안 사용하는 SYSTEM을 비롯한 사용자의 기본 하이브이며 SOFTWARE는 HKLM\Software와 같습니다. 언제나 그렇듯이 레지스트리를 편집할 때에는 각별한 주의가 요구되며 반드시 필요한 경우에만 편집해야 합니다.

지금까지 즐겨 사용하는 문제 해결 또는 복구 도구를 Windows PE에 통합하는 데 도움이 되는 몇 가지 사항을 살펴보았습니다. 다음 달 기사에서는 역시 Mark Russinovich가 만든 유용한 시스템 관리 도구 모음인 PSTools 제품군에 대해 알아보겠습니다.

WinDiff 사용

WinDiff는 응용 프로그램의 종속성을 찾는 데 도움이 됩니다. 이 도구의 성공적인 설치와 실행을 위해서는 다음 단계를 따르십시오.

  1. 도구를 설치할 수 있도록 시스템을 준비합니다. 즉, 소요되는 시간을 최소화하고 초기 스냅숏과 최종 스냅숏 간의 파일 또는 레지스트리 변경 내용을 최소한으로 줄여야 합니다.
  2. 명령 프롬프트를 열고 reg export HKLM C:\HKLM1.reg를 실행하여 HKEY_Local_Machine 레지스트리 하이브를 완전히 내보냅니다.
  3. dir C:\*.* /S > C:\C1.txt를 실행하여 C: 드라이브(C:가 시스템 드라이브인 경우)의 모든 파일에 대해 전체 덤프 작업을 수행합니다.
  4. 응용 프로그램을 설치하고 설치 후 설정을 구성합니다.
  5. reg export HKLM C:\HKLM2.reg를 실행합니다.
  6. dir C:\*.* /S > C:\C2.txt를 실행합니다.
  7. WinDiff를 열고 File | Compare Files…(파일 | 파일 비교)를 선택하고 첫 번째 File Open(파일 열기) 대화 상자에서 HKLM1.reg를, 두 번째 대화 상자에서 HKLM2.reg를 각각 선택합니다.
  8. 그러면 어느 파일이 최신 파일인지를 나타내는 빨간색 메시지가 표시됩니다. 내보내는 HKLM 파일이 상당히 클 수 있으므로 이 작업에는 다소 시간이 걸립니다.
  9. 빨간색으로 표시된 텍스트를 두 번 클릭하여 차이점이 자세히 표시되도록 합니다.
  10. Options | Show Right-Only Lines(옵션 | 새로 추가된 줄만 표시)를 선택하면 비교 결과에 표시되는 내용을 구성할 수 있습니다. 그러면 두 번째 비교 파일에 새로 추가된 줄(새 파일 및 레지스트리 키)만 표시됩니다.

응용 프로그램과 관련된 키를 찾으려면 Find 기능을 사용해야 할 수도 있습니다. 그림 A와 그림 B에는 필자가 작성한 가상의 응용 프로그램에 대한 파일 및 레지스트리 변경 사항이 나타나 있습니다. 편리하게도 WinDiff에서는 복사 및 붙여넣기 기능을 사용할 수 있습니다. 이들 기능을 사용하려면 !> 줄을 클릭하고 원하는 줄을 선택하면 됩니다.

그림 A WinDiff 항목
그림 A WinDiff 항목 (Click the image for a smaller view)
그림 B WinDiff의 특정 키
그림 B WinDiff의 특정 키 (Click the image for a smaller view)


Wes Miller는 텍사스 오스틴에 있는 Pluck(www.pluck.com)에 근무하는 개발 관리자입니다. 이전에는 오스틴에 있는 Winternals Software에서 근무했으며 Microsoft에서 프로그램 관리자 및 Windows 제품 관리자로도 근무한 경력이 있습니다. 문의 사항이 있으신 분은 technet@getwired.com으로 연락하시기 바랍니다.