rubrapack 매뉴얼←↑→

39 출력을 Windows 와 대조하기

Microsoft 는 MSI 표 인코딩을 공개하지 않으므로 기준은 Windows 자신이다. 이 확인에는 Windows 컴퓨터와 Windows Installer API(msi.dll)만 있으면 된다. SDK 도구는 필요 없다.

39.1 데이터베이스가 열리고 풀린다#

  1. 파일을 MsiOpenDatabase 로 읽기 전용으로 연다 - 복합 파일과 문자열 풀이 받아들여진다는 뜻이다.
  2. 모든 표(와 _ForceCodepage, _SummaryInformation)를 MsiDatabaseExport 로 IDT 파일로 내보낸다.
  3. 자기 판독기가 내보낸 것과, 또는 msi.dll 로 만든 기준 데이터베이스(MsiOpenDatabase 만들기 모드, 65001 이 든 _ForceCodepage.idt 의 MsiDatabaseImport, 뷰를 통한 SQL CREATE TABLE/INSERT)의 IDT 와 비교한다. 바이트까지 같은 IDT 는 인코딩이 맞다는 뜻이다.

39.2 패키지가 설치된다#

설치 엔진은 msiexec 보다 프로그램에서 부른다. 그래야 단계마다 동기로 돌고 오류 코드를 돌려준다:

단계API기대
조용한 UIMsiSetInternalUI(INSTALLUILEVEL_NONE)
자세한 로그MsiEnableLog(모든 모드)무엇이 실패하면 읽는다
설치MsiInstallProduct(path, "")0
이름설치된 경로마다 FindFirstFile, 항목 자신의 UTF-16 이름을 정확히 비교같음
내용설치된 파일마다 MsiGetFileHash 와 자기 MsiFileHash 행같음
등록MsiGetProductInfo(ProductCode, InstalledProductName)자기 ProductName
복구설치된 파일 하나를 지우고 MsiReinstallProduct(ProductCode, ...)파일이 같은 이름으로 돌아옴
업그레이드판 N 위에 판 N+1 설치옛 ProductCode 없어지고 새것이 설치됨
다운그레이드판 N 을 다시 설치거부(1603, 로그에 거부한 동작의 이름)
기능MsiQueryFeatureState; MsiConfigureFeature(..., INSTALLSTATE_LOCAL)INSTALLLEVEL 보다 높은 수준은 켤 때까지 없음
되돌림InstallFiles 뒤에 실패하는 지연 사용자 지정 동작(형식 34 + 1024, "[SystemFolder]cmd.exe" /c exit 1)과 새 패키지 코드를 가진 판 N+1 의 사본을 N 위에 설치1603(로그: 오류 1722); N 은 그대로 등록되어 있고 파일도 그대로
제거MsiConfigureProduct(ProductCode, ..., INSTALLSTATE_ABSENT)0; 폴더, 키, 등록이 사라짐

컴퓨터 전체 설치에는 관리자 권한 프로세스가 필요하다. 시험 제품은 제 UpgradeCode 를 쓰고 같은 실행 안에서 지운다.

39.3 쓰기 전에 하는 검사#

msi.dll 은 깨진 데이터베이스를 많이 받아들이고, 실패하더라도 설치 때에야 실패한다(열 너비조차 강제하지 않는다). 작성기는 제 표를 먼저 검사해야 한다. rubrapack 의 build 는 다음 가운데 하나라도 어기는 패키지는 쓰지 않는다(진단 RP2001-RP2015):

39.4 Microsoft 의 ICE 규칙 [관찰]#

Windows SDK 의 "MSI Tools" 에는 MsiVal2 와 darice.cub 가 들어 있다. Microsoft 의 작성 도구들이 돌리는 내부 일관성 검사기(ICE)다: MsiVal2 package.msi darice.cub -f 가 실패한 것을 찍는다. Windows 에서만 돌고, 위의 검사보다 한 걸음 더 간다 - 표의 모양만이 아니라 뜻을 안다. rubrapack 의 시험 패키지(시험에 쓰는 모든 원본, 39개)에서 0.8.0 부터 나오는 것은 ICE52 하나다: AppSearch 의 비공개 속성(RpFound_<ID>, 기억하는 폴더). 명령줄이 "찾았다"고 꾸미지 못하게 일부러 비공개로 둔다. AppSearch 는 두 순서에서 모두 돌므로 서버 쪽에 넘길 필요가 없다.

나머지를 없애려고 0.8.0 이 바꾼 것 - 설치가 하는 일은 하나도 바뀌지 않는다:

셋은 진짜 결함이었고 고쳤다(0.4.3): 완료·취소·실패 페이지가 AdminUISequence 에 없어 전체 UI 의 관리 설치(msiexec /a)가 그 페이지 없이 끝났다(ICE20). 폴더를 키 경로로 쓰는 컴포넌트(INI 항목, [remove])가 CreateFolder 에 없었다(ICE18). 대화창이 있는 패키지에 ControlCondition 표가 없었는데, ICE17 은 대화창마다 이 표를 읽는다(검사 대신 오류 2228 로 멈췄다).

39.5 멀쩡해 보이지만 아닌 것#