Initial commit: EG-BIM installer plans and design concepts

This commit is contained in:
jychoi4 committed 2026-10-19 09:24:15 +09:00
commit 54f0cfe360
25 files changed
+4251

No files matched your search

@@ -0,0 +1,59 @@
# 요구사항과 기존 프로그램 현황
EG-BIM의 기존 설치 기반을 보존하면서 네트워크 배포를 추가한다. 설치 도구 변경과 앱 구조 변경을 한 번에 강제하지 않는 방향으로 검토한다.
## 확정 요구사항
| 항목 | 내용 |
| --- | --- |
| 운영 환경 | Windows 데스크톱 프로그램 |
| 대상 소스 | `D:\egbim\repo\14.1` |
| 기존 배포 | InstallShield `.ism`에서 생성한 EXE |
| 기존 설치 위치 | `C:\Program Files\Baron` 하위 |
| 설치 도구 | 향후 InstallShield 사용 중단 |
| 패키지 운영 | 버전별 관리 및 배포용 업로드 |
| 업데이트 | 현재 설치 버전에 맞는 변경분 패치와 전체 설치 경로 모두 지원 |
| 배포 순서 | 개발자 테스터 → 1차 테스터 → 2차 테스터 → 일반 사용자 |
| 추가 검토 | Microsoft Store 배포 |
네트워크 설치는 파일 전달 방식이고 MSI·EXE·MSIX는 설치 형식이다. 네트워크 설치에 MSI가 필수인 것은 아니다. 현재 프로젝트에 MSI를 권고하는 이유는 기존 MSI 제품과의 업그레이드 연속성이다.
## 저장소 확인 결과
| 항목 | 확인 내용 | 영향 |
| --- | --- | --- |
| 설치 프로젝트 | `InstallShield/src/EG-BIM_V1.13.1.ism` | 새 설치 정의를 작성하기 위한 참고 자료 |
| 설치 엔진 | MSI Property·Directory·Upgrade 테이블과 사용자 지정 작업 존재 | 기존 제품 식별자를 활용한 전환 검토 가능 |
| 설치 범위 | `ALLUSERS=1` | PC 전체 설치, 적용 단계의 관리자 권한 필요 |
| 설치 경로 | `ProgramFiles64Folder\Baron`, 앱 하위 폴더 `EG-BIM` | 기본 실행 위치는 `Baron\EG-BIM\Grimi.exe` 구성 |
| 제품 버전 | `.ism`의 `1.13.1.0`, `version.config`의 `1.13.1` | 엔진 버전 `14.1`과 제품 버전 분리 |
| 제품 식별자 | UpgradeCode `{E6381427-A8BC-4506-A428-CE860BDA119F}` | 과거 배포본에서도 일관적인지 확인 필요 |
| 앱 구성 | IntelliCAD 기반 네이티브 코드, .NET 8/WPF, C++/CLI 모듈 | 네이티브·관리형 런타임 및 플러그인 호환성 검증 |
| 선행 조건 | .NET 8 Desktop Runtime, VC++ 재배포 패키지, 웹 설치형 .NET Framework 등의 항목 등록 | 실제 필요한 런타임과 포함 조건을 정리해야 함 |
| 서비스 | 검토한 `.ism`의 ServiceInstall·ServiceControl 테이블은 비어 있음 | 다른 실행 파일이나 사용자 지정 작업의 서비스·드라이버 사용 여부는 별도 확인 |
`.ism`의 File 테이블은 4,701행, Registry 테이블은 379행이다. 이는 설치 정의의 규모이며 최종 설치되는 고유 파일 수나 현재 필요한 항목 수와 동일하다고 단정하지 않는다.
## 기존 업데이트와 설정 보존
`Pet.Entry`는 `BaronSoftware.Update` 2.0.0을 참조한다. 업데이트 옵션에는 제품 코드 `E901`, 표시 버전, 다운로드 폴더, 테스트 모드와 채널이 들어간다. 채널은 현재 로그인 사용자의 `IsCenter()`·`IsFamily()` 결과에 따라 `Center`, `Family`, `External` 중 하나를 선택한다.
새 4개 그룹을 이 값들과 자동으로 대응시키지 않는다. 기존 채널의 업무상 의미와 서버의 인증 방식을 확인한 뒤 매핑한다. 앱의 `E901` 코드와 MSI의 GUID ProductCode는 서로 다른 식별자다.
제품 버전은 호스트 실행 파일 `Grimi.exe`의 FILEVERSION에서 읽는다. 사용자 레지스트리와 CUI를 백업·복원하는 코드도 있으며, 엔진 버전에 종속된 일부 설정은 복원에서 제외한다. 오프라인 라이선스 사용자는 현재 진입 코드에서 자동 업데이트를 건너뛰므로 별도 배포 경로가 필요하다.
## 참고 파일
아래 경로는 모두 대상 소스 루트 `D:\egbim\repo\14.1` 기준이다.
- `InstallShield/src/EG-BIM_V1.13.1.ism`
- `InstallShield/src/Script Files/Setup.rul`
- `InstallShield/version.config`
- `InstallShield/관리지침.md`
- `Source/Module/Pet.Entry/Pet.Entry.csproj`
- `Source/Module/Pet.Entry/Global.cs`
- `Source/Module/Pet.Entry/Entry.cs`
- `Source/Module/Pet.Entry/Services/UpdateService.cs`
- `Source/Module/Pet.Entry/Services/UserDataBackup/UserDataLocalBackupService.cs`
- `Source/Module/Nyng.Interop.Interface/Nyng.Interop.Interface.vcxproj`
- `CoWork/Export/IrxPackages/IrxInstaller/README.md`
+56
View File
@@ -0,0 +1,56 @@
# InstallShield 대체와 기존 설치본 전환
권고안은 WiX로 MSI를 작성하고 Burn으로 필수 런타임과 MSI를 묶은 전체 설치 EXE를 만드는 것이다. 사용자에게는 기존처럼 EXE 설치 파일을 제공할 수 있다. WiX 채택과 도구 버전·이용 조건은 구현 시작 전에 확정한다.
## 대체 도구 검토
| 선택지 | 장점 | 이 프로젝트의 주요 과제 |
| --- | --- | --- |
| WiX MSI + Burn EXE | MSI 업그레이드 체계 활용, 설치 정의의 코드 관리, 런타임 묶음 설치 | 기존 구성요소·레지스트리·사용자 지정 작업 이관 |
| Inno Setup EXE | 스크립트 기반 제작, 저장소에 IRX SDK 설치 경험 존재 | 기존 MSI 제거 및 새 설치 실패 복구를 별도 설계 |
| MSIX | Store 관리 업데이트와 패키지 배포 기능 | 설치 경로, CAD 연동, 데이터 저장, 자체 업데이트 구조 검증 |
WiX와 Burn의 기능은 [WiX 공식 설명](https://docs.firegiant.com/wix/)을 참고한다. IRX SDK 설치기는 본 프로그램과 설치 범위·목적이 다르므로 그대로 재사용한다고 가정하지 않는다.
## 산출물과 설치 경로
- `EG-BIM.msi`: 앱 파일, 레지스트리, 바로가기 등 설치 정의.
- `Setup.exe`와 MSI·분할 CAB·필수 런타임 폴더: 대용량 제품의 기본 전체 설치 레이아웃. 단일 파일이 가능한 경우에만 `FullSetup.exe`로 묶는다.
- `Patch.msp`: 지원하는 기준 버전에서 목표 버전으로 갱신하는 Windows Installer 패치. 세부 정책은 [버전별 패치](08-version-patching.md)를 따른다.
- `WebSetup.exe`: 서버의 고정된 MSI·CAB·런타임을 받아 설치하는 네트워크 진입점. 사용자별 목표 릴리스 선택은 배포 서버/업데이터와 연계한다.
총 용량이 2GB를 넘을 때는 외부 CAB 분할을 사용하며 단일 CAB·개별 파일·서명 EXE의 한계를 별도로 검사한다. 자세한 출력 프로필과 제한 처리는 [릴리스 생성 설계](../code-design/05-release-pipeline.md)를 따른다.
신규 설치 기본 경로는 `%ProgramFiles%\Baron\EG-BIM`으로 하고 기존 설치본은 실제 등록 경로를 탐지해 유지한다. 사용자 지정 경로를 무조건 기본 경로로 변경하지 않는다. 설치 경로와 사용자 데이터 경로는 분리하며 일반 사용자에게 프로그램 폴더의 광범위한 쓰기 권한을 부여하지 않는다.
## 기존 제거 작업의 위험
`Setup.rul`의 `CleanAfterUninstall`은 앱 폴더 일부, AppData의 설정·도구 폴더, 공용 데이터 일부, 사용자·시스템 레지스트리를 삭제한다. CAD 파일 확장자 `.dwg`, `.dxf` 등의 키도 삭제 대상이다.
`.ism`의 `UnintallAction`은 `REMOVE="ALL"` 조건으로 연결되어 있어 업그레이드 중 구버전 제거에서도 실행될 수 있다. 새 설치기에서 제거 동작을 개선하더라도 이미 설치된 구버전의 제거 동작이 자동으로 바뀌지는 않는다.
현재 설정의 RemoveExistingProducts는 InstallInitialize보다 앞에 있다. 새 설치기는 기존 제거와 신규 설치의 실행 순서 및 실패 복구를 다시 설계한다. WiX의 `afterInstallInitialize` 방식은 검토 후보지만 사용자 지정 파일·레지스트리 삭제까지 자동 복구된다고 가정하지 않는다. [WiX MajorUpgrade 동작](https://docs.firegiant.com/wix/schema/wxs/majorupgrade/)
## 전환 절차
1. 지원할 기존 버전별 ProductCode·UpgradeCode·설치 경로·필수 런타임을 수집한다.
2. 실행 중인 앱과 관련 도구를 확인하고, 작업 저장 후 종료하도록 안내한다.
3. 사용자 설정·CUI·사용자 추가 리소스를 제거 대상 밖에 백업한다. 백업 성공을 검증하기 전에는 기존 제품을 제거하지 않는다.
4. 새 설치 파일과 런타임을 모두 확보하고 서명·해시·디스크 공간을 검증한다.
5. 검증된 업그레이드 순서로 기존 제품 제거와 새 제품 설치를 수행한다.
6. 호환되는 사용자 설정을 복원하고, 도면 열기·저장·출력·인증·플러그인 실행을 확인한다.
7. 설치 완료 후 상태 확인까지 성공한 경우에만 백업 정리를 허용한다.
현재 백업·복원 코드는 일부 예외를 내부에서 처리하고 성공 여부를 호출자에게 명확히 전달하지 않는다. 전환용 경로에는 결과 상태와 실패 로그를 추가한다. 백업을 다운로드 임시 폴더 정리와 함께 삭제하지 않도록 수명도 분리한다.
PC 전체 설치와 HKCU·AppData의 사용자별 데이터를 구분한다. 다른 관리자 계정으로 UAC를 승인한 경우에도 원래 사용자의 설정을 다뤄야 하며, 여러 사용자의 프로필은 각 소유자와 복원 시점을 정의한다.
## MSI 식별자와 복구
기존 UpgradeCode를 계승하는 Major Upgrade를 우선 검토하되, 실제 배포본의 아키텍처·언어·제품 식별자와 함께 시험한다. 새 Major Upgrade의 ProductCode와 패키지 식별자는 적절히 갱신한다. GUID 복사만으로 호환성이 보장되지는 않는다.
위 Major Upgrade 권고는 최초 설치기 전환과 설치 구조가 달라지는 업데이트에 적용한다. 이후 모든 릴리스의 ProductCode를 변경하지 않는다. 같은 제품 계열의 MSP Minor Upgrade는 ProductCode와 구성요소 규칙을 유지하며 ProductVersion을 올리는 방향으로 설계한다. 전체 설치 파일의 갱신 방식도 해당 패치 계열과 일치시킨다. [Windows Installer 업데이트 구분](https://learn.microsoft.com/en-us/windows/win32/msi/patching-and-upgrades)
Windows Installer는 제품 버전 비교에 앞의 세 필드를 사용한다. 네 번째 숫자만 올려 새 업데이트를 구분하는 설계를 피하고, 제품 버전과 빌드 식별자의 매핑을 정한다. [ProductVersion 규칙](https://learn.microsoft.com/en-us/windows/win32/msi/productversion)
설치 중 실패 복구와 설치 완료 후 이전 릴리스 복귀는 별도 기능이다. 데이터 형식 변경으로 복귀가 불가능하면 더 높은 제품 버전의 수정 릴리스를 배포한다. 새 빌드에서 InstallShield 사용을 중단하더라도 최초 전환 시 기존 설치본의 등록된 제거 엔진을 호출할 수는 있다.
+67
View File
@@ -0,0 +1,67 @@
# 버전별 패키지 관리와 업로드
패키지는 등록 후 변경하지 않고 배포 정책만 변경한다. 같은 릴리스를 개발자 테스트부터 일반 배포까지 사용하며, 수정이 필요하면 새 릴리스를 만든다.
## 버전 및 관리 정보
| 정보 | 목적 |
| --- | --- |
| productId | 제품 식별. 기존 업데이트 제품 코드 `E901`과의 관계 정의 |
| productVersion | 사용자 표시와 업그레이드 판정에 사용할 제품 버전 |
| engineVersion | IntelliCAD 등 엔진 버전. 현재 대상은 `14.1` |
| releaseId / buildId | 고유 릴리스·빌드 식별자와 소스 커밋 연결 |
| platform / architecture | Windows 및 x64 등 대상 플랫폼 |
| artifacts | 파일 종류, 저장 경로, 크기, 최종 SHA-256, 서명 검증 결과 |
| patchTargets | 패치별 허용 기준 릴리스·제품 식별자·패치 이력·목표 릴리스 |
| fallbackArtifactId | 패치 적용 불가 또는 복구 후 사용할 동일 목표 버전의 전체 설치 파일 |
| compatibility | 지원 OS, 필수 런타임, 최소 업데이터 버전, 허용 업그레이드 경로 |
| recovery | 복구 가능한 릴리스와 데이터 호환 조건 |
예시 저장 경로는 다음과 같다. 값은 운영 체계를 설명하기 위한 예시다.
```text
/packages/egbim/1.13.2/build-001/windows-x64/FullSetup.exe
/packages/egbim/1.13.2/build-001/windows-x64/EG-BIM.msi
/patches/egbim/release-001/to-release-002/windows-x64/Patch.msp
/manifests/egbim/release-001.json
```
같은 URL의 바이너리를 교체하지 않는다. 패키지는 장기 캐시가 가능하고, 현재 그룹별 대상 버전을 반환하는 응답은 사용자 간 공유 캐시로 섞이지 않도록 한다.
위 `FullSetup.exe`는 단일 파일 출력이 가능한 경우의 예시다. 대용량 패키지는 MSI·분할 CAB·런타임을 각각 아티팩트로 등록하고 의존 관계와 전체 설치 실행 경로를 함께 저장한다. `fallbackArtifactId`도 필요한 모든 파일을 참조하는 설치 레이아웃/매니페스트로 연결해야 한다. 생성 프로그램의 데이터와 출력 계약은 [Rust + Tauri 설계](../code-design/README.md)를 따른다.
## 업로드와 공개 절차
| 단계 | 처리 | 실패 시 결과 |
| --- | --- | --- |
| 빌드 | 버전 반영, 난독화, 파일 서명, 패키징, 패키지 서명 | 업로드 중단 |
| 임시 업로드 | 필요하면 분할·재개 지원, 공개 저장 경로와 격리 | 전송 재시도 |
| 서버 검증 | 최종 해시·크기·서명·필수 파일·중복 릴리스 확인 | 공개 불가 |
| 설치 검증 | 신규 설치·지원 기준별 패치·전체 설치 전환·실행 확인 | 승인 불가 |
| 릴리스 등록 | 검증한 아티팩트와 메타데이터를 고정 | 그룹 공개 전 상태 유지 |
| 그룹 공개 | 승인된 그룹의 대상 릴리스를 원자적으로 변경 | 기존 정책 유지 |
권장 상태는 `Uploaded → Verified → Ready`이며 검증 실패는 `Rejected`로 관리한다. 그룹 배포 상태는 패키지 상태와 별도로 둔다. Ready는 모든 사용자에게 공개됐다는 뜻이 아니다.
CI 업로드를 기본으로 하되 관리자 수동 업로드도 같은 검증을 거친다. 업로드 권한과 일반 사용자 배포 승인 권한을 분리하고, 누가 어떤 릴리스를 어느 그룹에 공개했는지 기록한다. 동시에 두 배포가 변경될 때는 정책 버전 비교로 충돌을 검출한다.
## 서버 역할
| 구성 | 역할 |
| --- | --- |
| 패키지 저장소 | 서명된 파일과 불변 메타데이터 보관 |
| 배포 API | 인증, 장치·그룹 판정, 대상 버전 및 다운로드 권한 반환 |
| 관리 DB | 릴리스, 그룹, 배포 정책, 승인 이력 |
| 결과 수집 | 다운로드·설치·실행 상태와 오류 집계 |
인터넷 배포는 오브젝트 저장소와 CDN, 사내망 배포는 내부 HTTPS 서버를 후보로 둔다. 특정 클라우드 사업자는 아직 정하지 않았다. 비공개 테스트 패키지는 실제 다운로드 경로에도 접근 통제를 적용한다.
버전별 패치는 최초 필수 범위에 포함한다. 릴리스마다 전체 설치 파일을 유지하고, 지원하는 기준 버전에는 변경분 패치를 함께 제공한다. 서버는 그룹의 목표 릴리스를 먼저 결정한 뒤 설치 상태에 맞는 패치 또는 전체 설치 파일을 선택한다. 적용 범위와 복구 정책은 [버전별 패치](08-version-patching.md)를 따른다.
## 무결성과 보존
해시는 전송 중 변조·손상을 검출하지만 서버의 메타데이터와 해시가 함께 바뀌는 공격까지 막지는 못한다. 패키지의 Authenticode 서명과 배포 메타데이터 서명을 별도로 검토한다. 메타데이터에는 버전·만료·허용된 업그레이드 경로와 키 교체 정책이 필요하다. [TUF 메타데이터 설계](https://theupdateframework.io/docs/metadata/)
현재 배포 대상, 복구 대상, 진행 중인 설치가 참조하는 패키지는 삭제하지 않는다. Store에 등록한 URL도 해당 버전의 배포 수명 동안 유지한다. 보존 기간은 사용자 접속 주기와 저장 비용을 확인한 뒤 확정한다.
패치 생성·검증에 필요한 기준 및 목표 MSI, 서명 완료 원본 파일, WiX 설치 정의와 빌드 정보도 해당 기준 버전의 지원 기간 동안 보관한다. 후속 패치가 의존하는 이전 패치·원본을 삭제하지 않는다. 패키지 등록 정보에는 지원하는 각 기준에서 목표 상태로 도달하는 검증 결과를 연결한다.
+66
View File
@@ -0,0 +1,66 @@
# 사용자 그룹별 4단계 배포
하나의 릴리스를 네 그룹에 순차적으로 공개한다. 초기에는 담당자가 관측 결과를 확인한 후 다음 단계를 승인하는 방식을 권고한다.
## 그룹 구성
| 단계 | 대상 | 주요 확인 사항 | 관찰 기간 예시 |
| --- | --- | --- | --- |
| 1 | 개발자 테스터 | 설치, 실행, 핵심 기능, 복구 | 1일 |
| 2 | 1차 테스터 | 내부 실제 업무, 기존 데이터 호환 | 1~2일 |
| 3 | 2차 테스터 | 다양한 OS·장비·권한·네트워크 환경 | 2~3일 |
| 4 | 일반 사용자 | 확대 배포 안정성 및 서버 부하 | 단계적 확대 |
기간은 초기 제안이며 승인 기준으로 확정된 값이 아니다. EG-BIM의 사용 빈도를 고려해 최소 설치 수, 실제 실행 수, 관찰 시간을 함께 정한다. 2차 테스터는 단순 인원 확대보다 대표성 있는 환경 구성이 중요하다.
## 대상 결정
서버는 인증된 사용자·등록 장치·제품·설치 버전·환경 정보를 바탕으로 대상 릴리스를 반환한다. 클라이언트가 보낸 그룹 문자열만으로 테스트 버전을 허용하지 않는다.
PC 전체 설치이므로 장치별 유효 그룹을 하나로 결정한다. 여러 사용자의 그룹이 충돌하면 적용할 우선순위와 관리자의 장치 고정 정책을 정의한다. 최초 설치는 앱 로그인 전이므로 로그인·장치 등록·만료되는 등록 코드 중 식별 수단을 준비한다.
기존 `Center`, `Family`, `External`, 테스트 모드는 업무상 의미를 확인한 뒤 새 그룹으로 매핑한다. 테스트 모드를 개발자 그룹과 자동으로 동일시하지 않는다. 오프라인 라이선스에는 전체 설치 파일을 이용한 별도 경로를 둔다.
## 배포 정책
그룹별로 릴리스 ID, 시작 시각, 배포 비율, 상태, 승인 이력과 정책 버전을 관리한다. 일반 사용자 그룹 내에서 `5% → 20% → 50% → 100%`로 확대하는 방법은 선택 사항이다.
자체 비율 배포는 `장치 ID + 배포 ID`의 고정 해시로 대상을 결정한다. 배포 ID를 유지한 채 임계값만 올려 기존 선정 장치가 제외되지 않도록 한다. Store 자체 점진 배포의 대상 선정은 Microsoft가 관리하며 이 규칙과 다르다.
예시:
```text
개발자 테스터: release-002
1차 테스터: release-002
2차 테스터: release-001
일반 사용자: release-001
```
2차 테스터 승인 시 해당 정책만 release-002로 변경한다. 패키지를 다시 빌드하거나 재서명하지 않는다.
하나의 목표 릴리스는 전체 설치 파일과 기준별 패치로 구성될 수 있다. 각 장치에는 현재 설치 상태에 맞는 아티팩트를 제공하되 목표 버전은 그룹 정책을 따른다. 같은 패치를 단계마다 다시 생성하지 않으며 지원 기준별 패치와 전체 설치 경로를 모두 검증한 결과로 승격한다. 특정 패치만 중지한 경우에는 해당 목표 릴리스의 전체 설치가 별도로 승인되어 있을 때만 전환하고, 릴리스 전체 중지라면 어느 경로로도 우회하지 않는다.
## 승인과 중지
- 최소 설치·실행 수 및 관찰 기간을 충족해야 한다.
- 설치 성공률, 설치 후 실행, 도면 작업 등 핵심 기능을 확인한다.
- 기존 버전 대비 비정상 종료·오류 증가가 허용 범위 안에 있어야 한다.
- 실행 불가·데이터 손상 등 중대 장애가 있으면 다음 단계 승격을 막는다.
수치 기준과 담당자는 구현 전 확정한다. 설치 성공률의 분모는 설치를 실제 시작한 건수 등으로 명시하고, 다운로드 실패·사용자 취소·재부팅 대기·미응답을 별도로 집계한다. 미응답 장치를 성공으로 취급하지 않는다.
패치 ID와 기준→목표 릴리스별 성공률, 실패 후 전체 설치 전환 횟수도 별도 집계한다. 전체 설치로 복구된 장치를 패치 자체의 성공으로 기록하지 않는다.
배포 중지 후에는 새 설치 허가를 차단한다. 클라이언트는 다운로드 이후 설치 직전에 중지 상태를 다시 확인한다. 이미 시작한 설치를 강제 종료하지 않으며, 오프라인 장치의 중지 반영 시점에는 한계가 있다. 설치 완료 장치의 복구는 별도 정책으로 실행한다.
## 클라이언트 진행 상태
```text
대상 조회 → 호환성 확인 → 다운로드 → 서명·해시 검증
→ 설치 허가 재확인 → 설정 백업 → 앱 종료·설치
→ 재부팅 필요 처리 → 실행 상태 확인 → 결과 보고
```
동일 설치 시도의 상태 보고는 중복 전송을 허용하되 서버에서 중복 집계하지 않는다. 네트워크 단절 시 결과를 보관해 재전송하고, 서버 장애만으로 기존 앱 사용을 차단하지 않는다. 필수 보안 업데이트의 실행 제한은 별도 정책으로 결정한다.
배포 링 운영의 참고 자료는 [Microsoft 배포 계획 가이드](https://learn.microsoft.com/en-us/windows/deployment/update/create-deployment-plan)다.
+50
View File
@@ -0,0 +1,50 @@
# Microsoft Store 배포 방식
현재 EG-BIM에는 자체 업데이터와 PC 전체 설치 구조가 있으므로 MSI·EXE 등록 경로를 우선 검토한다. Store 배포에 MSIX가 반드시 필요한 것은 아니다.
## 두 경로의 차이
| 항목 | MSI·EXE 등록 | MSIX 제출 |
| --- | --- | --- |
| 파일 보관 | 자체 HTTPS 저장소 | Microsoft 호스팅 |
| 서명 | 게시자가 설치 파일과 포함 PE 파일 서명 | Store가 패키지 서명 처리 |
| 업데이트 | 자체 업데이터 담당 | Store 관리 |
| 지정 테스터 배포 | 자체 서버에서 구현 | Package Flights 지원 |
| 비율 배포 | 자체 서버에서 구현 | Store 점진 업데이트 지원 |
| 현재 앱 적용 | 기존 경로와 설치 기능을 유지하는 방향 | 경로·레지스트리·CAD 연동·업데이터 검증 필요 |
[Microsoft 배포 방식 비교](https://learn.microsoft.com/en-us/windows/apps/distribute-through-store/how-to-distribute-your-win32-app-through-microsoft-store)
## MSI 및 EXE 제출 조건
1. 버전별 고정 HTTPS 다운로드 URL을 제출한다.
2. 제출한 URL의 파일은 이후 덮어쓰지 않는다. 새 파일은 새 URL로 등록한다.
3. 무인 설치를 지원한다. 설치 UI는 표시하지 않지만 UAC 표시는 허용된다.
4. 설치 중 본체나 런타임을 추가 다운로드하지 않는 전체 설치 파일이어야 한다.
5. 설치 파일과 포함된 PE 파일에 신뢰 가능한 코드 서명이 있어야 한다.
Store용은 필요한 오프라인 런타임과 MSI를 포함한 단일 `FullSetup.exe` 등 제출 요건을 만족하는 파일로 만든다. 대용량으로 단일 파일의 생성·서명 제한을 넘으면 이 경로를 사용 가능하다고 간주하지 않는다. 자체 배포용 분할 CAB 폴더나 작은 `WebSetup.exe`가 그대로 Store 제출을 대신하는 것은 아니다. 현재 `.ism`의 웹 설치형 선행 조건은 그대로 이관하지 않고 실제 의존성을 정리한다. [공식 패키지 요구사항](https://learn.microsoft.com/en-us/windows/apps/publish/publish-your-app/msi/app-package-requirements), [출력 프로필과 용량 검사](../code-design/05-release-pipeline.md)
## 자체 배포와 함께 운영
자체 사이트와 Store에서 같은 검증 완료 전체 설치 파일을 사용할 수 있다. Store에는 일반 사용자에게 공개할 릴리스만 등록한다. 최초 설치 후의 업데이트는 자체 서버가 그룹별로 제어한다.
Store MSI·EXE 등록은 자체 서버의 4단계 배포 정책을 대신하지 않는다. 자체 서버의 배포 중지와 Store의 새 사용자 설치 중지는 별도 조치다. 두 경로의 공개 상태와 설치 패키지 버전을 함께 기록해야 한다.
Store 등록·심사 시점과 자체 배포 시점을 조정하고, Store의 오래된 전체 설치 파일로 시작한 사용자가 최신 허용 릴리스로 이동하는 경로도 검증한다.
Store의 신규 설치용 등록 파일은 항상 전체 MSI·EXE로 유지한다. MSP를 신규 설치 파일 대신 제출하지 않는다. 설치 이후 자체 업데이터는 [버전별 패치 정책](08-version-patching.md)에 따라 호환되는 MSP를 적용할 수 있으며, 해당 버전의 전체 설치본과 패치 적용 결과가 같은 관리 상태가 되는지 검증한다.
## MSIX로 전환할 경우
Package Flights에 개발자·1차·2차 테스트 그룹을 구성하고 정식 제출을 일반 사용자 단계에 연결할 수 있다. Microsoft 계정으로 테스터를 등록하고 Flight도 인증 절차를 거친다. 초기 앱 제출 게시 후 Flight를 구성하는 흐름을 고려한다. [Package Flights](https://learn.microsoft.com/en-us/windows/apps/publish/package-flights)
Store 점진 배포는 기존 사용자의 업데이트에 대한 비율 제어다. 최초 설치에도 같은 비율 제한이 적용된다고 가정하지 않는다. 중지는 이미 업데이트된 앱을 이전 버전으로 되돌리지 않으므로 수정 릴리스를 준비해야 한다. [점진 배포](https://learn.microsoft.com/en-us/windows/apps/publish/gradual-package-rollout)
MSIX 전환 시에는 고정 설치 경로, 설치 위치 쓰기, 외부 CAD·플러그인·COM 연동, 사용자 설정 이동, 런타임을 검증한다. 현재 구조만으로 불가능하다고 판정한 것은 아니다. [MSIX 준비 사항](https://learn.microsoft.com/en-us/windows/msix/desktop/desktop-to-uwp-prepare)
## SmartScreen과 설치 경로
Microsoft 공식 안내는 Store를 통한 MSI·EXE 설치 과정에는 SmartScreen 경고가 없고 UAC는 나타날 수 있다고 구분한다. 이는 Microsoft가 해당 EXE를 재서명한다는 의미가 아니다. Store에서 제공하는 MSIX 패키지 서명 처리와 다르다.
같은 EXE를 자체 웹사이트에서 내려받으면 일반 다운로드의 SmartScreen 평판 판단을 받는다. Store 등록만으로 자체 배포 URL까지 경고 면제가 되지는 않는다. Store 설치 후 자체 업데이터가 내려받는 파일도 별도의 서명·검증이 필요하며 Store 설치 경로의 효과를 그대로 가정하지 않는다. [코드 서명 및 배포 경로 비교](https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/code-signing-options)
@@ -0,0 +1,79 @@
# 코드 서명 서비스와 SmartScreen
WiX는 설치 패키지 생성 도구다. 회사 명의의 코드 서명 인증서 또는 서명 서비스는 별도로 준비해야 한다. WiX 빌드에서 서명 도구를 호출해 자동화할 수 있다.
## 역할과 서비스 선택
| 구성 | 역할 |
| --- | --- |
| WiX·Burn | MSI·설치 EXE 생성 |
| 코드 서명 인증서 또는 서비스 | 검증된 게시자 신원과 서명용 키 제공 |
| SignTool 등 | 인증서·서비스를 이용한 서명 및 검증 |
기존 회사 인증서가 있다면 명의·유효기간·키 접근 방식·빌드 연동 가능 여부를 먼저 확인한다. 새로 도입한다면 Azure Artifact Signing의 Public Trust를 우선 검토한다. 다른 인증기관의 코드 서명 인증서도 선택 가능하다.
Azure Artifact Signing은 Microsoft가 운영하며 이전 이름은 Trusted Signing이다. 게시자에는 신원 확인을 받은 회사의 법인명이 사용된다. 제품을 Microsoft Corporation 명의로 서명해 주는 서비스가 아니다. 이 서비스를 사용하면 해당 서명을 위해 다른 인증기관 인증서를 별도로 구매할 필요는 없다. [서비스 소개](https://azure.microsoft.com/en-us/products/artifact-signing), [게시자 명의 FAQ](https://learn.microsoft.com/en-us/azure/artifact-signing/faq)
한국 소재 조직은 현재 Public Trust 신청 대상이다. 개인 개발자는 미국·캐나다 제한이 있다. 일반 공개 배포에는 Public Trust를 사용하며 Public Trust Test나 Private Trust를 대신 사용하지 않는다. 가입 자격은 서비스의 [현재 설정 안내](https://learn.microsoft.com/en-us/azure/artifact-signing/quickstart)에서 확인한다. 일부 Windows 배포 개요 문서의 지역 목록보다 이 서비스 전용 안내를 우선 참고한다.
## 요금
2026-10-16에 확인한 공식 공개 요금은 다음과 같다.
| 요금제 | 계정당 월 기본료 | 월 포함 서명 | 초과 서명 |
| --- | --- | --- | --- |
| Basic | US$9.99 | 5,000회 | 회당 US$0.005 |
| Premium | US$99.99 | 100,000회 | 회당 US$0.005 |
원화 청구액은 적용 환율·세금·계약에 따라 달라진다. 별도 빌드·저장소·CDN 비용은 이 표에 포함하지 않는다. [공식 요금표](https://learn.microsoft.com/en-us/azure/artifact-signing/how-to-change-sku)
과금 단위는 사용자 설치 횟수가 아니라 서명 횟수다. 300개 파일을 각각 한 번 서명하면 약 300회이고, 여기에 MSI·Burn 엔진·최종 설치 파일 및 재서명 횟수를 더한다. 완성된 동일 패키지를 1만 명이 설치해도 그 이유로 추가 서명은 발생하지 않는다. Basic으로 시작하되 실제 파일 수와 릴리스 횟수를 측정한다.
## 서명 대상
| 대상 | 처리 |
| --- | --- |
| 자체 제작 EXE·DLL | 최종 빌드 파일을 회사 명의로 서명 |
| IRX 등 기타 확장자 | 실제 PE 모듈인지 확인하고 지원되는 서명·검증 경로 적용 |
| 이미 유효하게 서명된 자체 파일 | 게시자·무결성 확인 후 유지 가능 |
| 외부 DLL·런타임 | 공급자 서명을 검증·보존, 미서명 파일은 공급자 배포본과 서명·재배포 조건 검토 |
| MSI | 패키지 생성 후 서명 |
| MSP | 패치 생성 후 서명·타임스탬프, 적용 후 목표 PE 파일의 서명도 검증 |
| Burn 설치 EXE | 내부 엔진과 최종 번들 각각 서명 |
| 네트워크 설치기·업데이터 | 각각 서명 |
이미 존재하는 EXE도 재빌드 없이 서명할 수 있다. 서명은 파일 바이트와 해시를 바꾸므로 최종 해시는 서명 후 계산한다. .NET의 `.snk` 강력한 이름 서명은 Authenticode 코드 서명을 대체하지 않는다.
Store MSI·EXE 제출은 설치 파일과 포함된 모든 PE 파일의 서명을 요구하므로 설치 EXE만 서명해서는 충분하지 않다. [Store 패키지 요구사항](https://learn.microsoft.com/en-us/windows/apps/publish/publish-your-app/msi/app-package-requirements)
## 빌드 순서
```text
버전 반영·빌드·난독화 완료
→ 배포 폴더에 파일 수집
→ 기존 서명 검사 및 필요한 PE 파일 서명·타임스탬프
→ 검증
→ MSI 생성·서명·타임스탬프
→ Burn 번들 생성
→ Burn 엔진 서명·재결합·최종 EXE 서명·타임스탬프
→ 최종 검증·해시 계산
→ 업로드
```
서명 후 버전 정보 변경이나 난독화를 수행하지 않는다. SHA-256과 RFC 3161 타임스탬프를 적용하고, 타임스탬프 실패도 배포 실패로 처리한다. 유효기간 내 서명 증거는 인증서 만료 후 검증에 필요하지만 인증서 폐기 등의 조건도 영향을 준다. [SignTool](https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool), [WiX 서명 연동](https://docs.firegiant.com/wix/tools/signing/)
패치는 보관된 기준 패키지와 서명이 완료된 목표 파일로 구성된 업데이트 패키지를 입력으로 생성한다. MSP에도 별도로 서명하고 최종 해시를 계산한다. 적용 후 설치되는 자체 PE 파일은 목표 릴리스의 서명·해시와 일치해야 한다. 사용자 PC에 서명 키를 배포하거나 클라이언트에서 재서명하지 않는다. MSP 및 패치용 EXE의 서명 횟수도 요금 산정에 포함한다.
키는 저장소·배포 패키지·사용자 PC에 넣지 않는다. 보호된 서명 서비스 또는 장치를 사용하고 배포 빌드에 필요한 권한만 부여한다. Azure는 인증서가 갱신되므로 업데이터에서 인증서 지문 하나를 영구 고정하지 않는다. 체인·코드 서명 용도·배포자 식별·갱신 정책을 함께 설계한다. [인증서 수명 관리](https://learn.microsoft.com/en-us/azure/artifact-signing/concept-certificate-management)
## SmartScreen의 한계
Azure Artifact Signing을 사용해도 SmartScreen 경고가 발생할 수 있다. SmartScreen은 게시자 평판과 해당 파일 해시의 평판을 함께 평가한다. 외부 인증서로 서명했어도 새 파일의 평판이 부족하면 경고가 나올 수 있으며, Azure 서명도 즉시 신뢰를 보장하지 않는다. EV 인증서 역시 현재 경고 면제를 보장하지 않는다. [Microsoft SmartScreen 설명](https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/smartscreen-reputation)
| 배포 경로 | 기대할 수 있는 동작 |
| --- | --- |
| 자체 웹 + Azure 서명 | 유효한 게시자 확인, 초기 SmartScreen 경고 가능 |
| 자체 웹 + 외부 OV·EV 서명 | 유효한 게시자 확인, 초기 SmartScreen 경고 가능 |
| Store에서 직접 설치 | 공식 안내상 Store 설치 중 SmartScreen 경고 없음, UAC는 가능 |
Azure 선택의 근거는 비용과 자동화 편의성이다. SmartScreen 경고 제거를 구매 효과로 약속하지 않는다. 일반 사용자의 설치 마찰을 줄이려면 Store 경로를 함께 운영한다. UAC, SmartScreen, 백신 탐지는 서로 다른 기능이므로 경고 종류를 구분해 수집한다. [배포 경로 비교](https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/code-signing-options)
@@ -0,0 +1,65 @@
# 구현 순서와 검증 계획
첫 검증 목표는 기존 InstallShield 설치본을 새 설치본으로 전환하면서 사용자 설정과 CAD 연동을 보존하는 것이다. 이 경로를 검증한 뒤 서버의 단계 배포를 연결한다.
## 구현 전 결정할 항목
| 항목 | 현재 상태 | 필요한 결정·확인 |
| --- | --- | --- |
| 새 설치 도구 | WiX + Burn 권고 | 채택 여부, 지원 버전, 이용 조건 |
| 서명 | Azure Public Trust 우선 검토 | 기존 인증서, 법인 명의, 신청 자격, 서명량 |
| 기존 배포본 | 저장소의 1.13.1 설정 확인 | 실제 지원할 이전 EXE·MSI와 설치 로그 확보 |
| 업데이트 라이브러리 | NuGet 2.0.0 호출부 확인 | 명령 실행·권한·검증·복구 지원 범위 |
| 버전별 패치 | 필수 요구사항, MSP 우선 검토 | 지원 기준 버전, 누적 범위, 식별자·구성요소 규칙, 복구 절차 |
| 그룹 | 4단계 요구 확정 | 기존 채널과 매핑, 장치별 충돌 규칙 |
| 서버 | 구성 역할 제안 | 사내망·인터넷 범위, 사용자 수, 패키지 용량 |
| 승인 기준 | 관찰 기간 예시만 제시 | 최소 표본, 성공률, 장애 기준, 담당자 |
| Store | MSI·EXE 경로 우선 검토 | 계정·제품 등록, 서명·무인 설치·오프라인 조건 |
## 단계별 구현
1. **설치 목록 정리**: `.ism`에서 파일·레지스트리·바로가기·선행 조건·사용자 지정 작업을 추출하고 현재 앱에 필요한 항목을 판별한다. 실제 배포 대상 파일의 서명 목록도 만든다.
2. **새 전체 설치기**: WiX MSI와 Burn 전체 EXE를 구현하고 설치 경로·무인 설치·재부팅 상태·로그·런타임 설치를 검증한다.
3. **기존 설치본 전환**: 사용자별 백업, 기존 제거, 새 설치, 선택적 설정 복원, 실패 복구를 구현한다. 다른 CAD 제품과의 파일 연결도 확인한다.
4. **서명 자동화**: PE 파일부터 최종 EXE까지 서명·타임스탬프·검증을 빌드에 연결하고 최종 해시를 생성한다.
5. **패키지와 업로드**: 임시 업로드, 검증, 불변 릴리스 등록, 접근 통제, 감사 이력을 구현한다.
6. **버전별 패치**: 기준과 목표 패키지에서 MSP 생성, 지원 기준 검증, 서명, 패치 선택, 실패 상태 복구와 전체 설치 전환을 구현한다. 패치 지원을 위해 MSI 식별자·구성요소 규칙은 2단계부터 반영한다.
7. **4단계 배포**: 서버의 그룹 결정, 기존 업데이터 연동, 결과 수집, 수동 승격, 중지와 수정 릴리스를 연결한다.
8. **Store 제출 준비**: 전체 오프라인 설치, 모든 PE 서명, 무인 설치, 고정 URL, 정식 릴리스 공개 순서를 검증한다.
전체 설치와 버전별 패치는 최초 필수 범위다. 자체 바이너리 차분 엔진, 자동 승격, 복잡한 관리 화면은 측정 결과에 따라 확장한다. MSP와 별개인 독자 파일 교체 엔진은 우선 구현하지 않는다.
## 필수 검증 시나리오
| 분야 | 시나리오 | 통과 조건 |
| --- | --- | --- |
| 신규 설치 | 깨끗한 지원 Windows, 런타임 없는 상태 | 전체 EXE로 오프라인 설치·실행 가능 |
| 권한 | 일반 사용자, 관리자, 다른 계정으로 UAC 승인 | 필요한 단계만 승격, 원래 사용자 데이터 보존 |
| 기존 업그레이드 | 지원할 각 구버전, 사용자 지정 경로 | 제품 중복·경로 이동·설정 손실 없이 전환 |
| 버전별 패치 | 각 지원 기준→목표, 누적 적용, 중간 버전 생략 | 전체 설치와 동일한 목표 파일·설치 정보·기능 상태 |
| 패치 적용 거부 | 다른 기준, 아키텍처·제품 불일치, 변경·누락 파일 | 잘못된 패치 실행 금지, 승인된 전체 경로 선택 |
| 패치 이력 | 중복 적용, 이전 패치 존재, 설치 캐시 부족 | 이력 일관성, 재시도 안전성, 원본 필요 시 확보 또는 복구 |
| 패치 실패 | 적용 중 중단, 재부팅 대기, 롤백 실패 | 현재 상태 확인 후 복구, 불확실한 상태에서 전체 설치 강행 금지 |
| 패치와 설치 관리 | 패치 후 복구·제거·다음 업데이트, 전체 설치로 동일 버전 전환 | MSI 및 Burn 등록과 파일 상태 일치 |
| 사용자 데이터 | CUI, 레지스트리, 추가 리소스, 여러 사용자 | 소유자별 백업·복원, 엔진 종속 설정 제외 |
| CAD 공존 | 다른 CAD 설치 및 파일 연결 존재 | 타사 소유 연결·설정 훼손 없음 |
| 핵심 기능 | 인증, 도면 열기·저장·출력, 플러그인 | 기존 지원 기능 정상 동작 |
| 실패 복구 | 백업 실패, 설치 실패, 전원 중단, 디스크 부족 | 복구 가능한 상태와 로그·백업 보존 |
| 실행 중 업데이트 | 도면 편집 중, 파일 잠금, 중복 설치 요청 | 저장·종료 안내, 설치 직렬화, 작업 손실 방지 |
| 네트워크 | 중단·재개, 프록시, 만료 다운로드 URL | 재시도 가능, 불완전 파일 실행 금지 |
| 패키지 검증 | 손상·변조 파일, 다른 게시자, 만료 메타데이터 | 실행 차단 및 원인 기록 |
| 그룹 | 중복 소속, 조작된 채널, 비율 확대, 그룹 변경 | 서버 정책에 따른 일관된 대상 결정 |
| 배포 중지 | 다운로드 전·후 및 설치 시작 후 | 새 설치 차단 범위 명확, 진행 중 설치 강제 종료 없음 |
| 결과 집계 | 재전송, 중복 이벤트, 미응답, 재부팅 대기 | 중복 성공 집계 없음, 미응답을 성공 처리하지 않음 |
| Store | 전체 EXE 무인 설치·제거·수정 설치 | 제출 조건 및 자체 업데이트와의 호환성 충족 |
| 공개 다운로드 | 실제 HTTPS 다운로드 후 실행 | 서명·게시자·타임스탬프 확인, SmartScreen 결과 별도 기록 |
새 설치기의 성공 여부와 SmartScreen 경고 유무는 별도 평가한다. 서명 검증 통과만으로 SmartScreen 무경고를 합격 조건으로 보장하지 않는다.
## 완료 기준
지원 대상 구버전에서의 전환, 데이터 보존, 설치 실패 복구, 무인·오프라인 설치, 서명 검증이 통과해야 첫 개발자 그룹에 공개한다. 이후 각 그룹의 관측 기준을 통과하면 동일 패키지를 다음 그룹에 공개한다.
해당 릴리스가 지원한다고 선언한 모든 패치 기준의 적용 시험과 전체 설치 복구 경로가 통과해야 패치 지원 완료로 판단한다. 기준 버전 범위는 승인 전에 명시하고, 미검증 기준은 자동 패치 대상에서 제외한다. 상세 기준은 [버전별 패치](08-version-patching.md)를 따른다.
서버의 배포 중지와 Store 공개 상태 변경을 함께 다루는 운영 절차를 마련한다. 설치 완료 후 치명적 장애는 검증된 복구 릴리스 또는 높은 버전의 수정 릴리스로 대응한다. 일반 사용자의 다운그레이드를 임의로 허용하지 않는다.
+79
View File
@@ -0,0 +1,79 @@
# 버전별 패치와 복구
버전별 패치는 필수 요구사항이다. 현재 설치된 버전과 상태를 확인해 변경분만 적용할 수 있어야 하며, 신규 설치·최초 설치기 전환·패치 비호환 상태를 위한 전체 설치 패키지도 함께 제공한다.
## 권장 구현 방식
WiX가 생성하는 Windows Installer 패치인 MSP를 우선 검토한다. MSP는 기준 패키지와 업데이트 패키지의 차이를 담으며, 변경 내용에 따라 전체 설치보다 다운로드와 설치 부담을 줄일 수 있다. 모든 릴리스의 패치가 반드시 작아지는 것은 아니므로 생성 후 크기를 비교한다. [WiX 패치 지원](https://docs.firegiant.com/wix/tools/patches/)
MSI가 관리하는 파일을 별도 ZIP 업데이터로 덮어쓰는 방식은 우선 채택하지 않는다. 파일만 바꾸면 설치 복구·제거·버전 등록과 실제 파일이 어긋날 수 있다. MSI 관리 밖의 독립 콘텐츠가 있다면 소유 범위를 명확히 나눈 뒤 별도 방식으로 검토한다.
| 상황 | 기본 경로 |
| --- | --- |
| 미설치 PC | 전체 설치 |
| 기존 InstallShield 설치본에서 새 설치 체계로 전환 | 검증된 전체 설치 업그레이드 |
| 같은 제품 계열에서 패치 규칙을 만족하는 변경 | 해당 기준을 지원하는 MSP |
| 여러 버전을 건너뛰는 업데이트 | 기준을 명시한 누적·직접 패치, 없으면 전체 설치 |
| 제품 구조·아키텍처·필수 런타임 변경 등 패치 비호환 | 검증된 전체 설치 업그레이드 |
| 패치 대상 파일 변경·누락, 기준 또는 이력 불일치 | 패치 적용 차단 후 검증된 복구·전체 설치 경로 |
이 표의 최초 전환 정책은 프로젝트 권고안이다. 기존 InstallShield 패키지에 MSP를 적용하는 것이 기술적으로 항상 불가능하다는 뜻은 아니다.
## MSI 패치 계열 설계
최초 전환은 Major Upgrade로 검토하되, 이후 패치 가능한 계열은 ProductCode와 구성요소 식별·경로 규칙을 안정적으로 유지한다. 버전을 구분하는 패치는 Minor Upgrade를 우선 사용해 ProductVersion을 올리고, 변경된 MSI의 PackageCode는 갱신한다. 앱의 버전 명명 규칙과 Windows Installer의 Major·Minor 구분은 같은 의미가 아니다. [Windows Installer 업데이트 구분](https://learn.microsoft.com/en-us/windows/win32/msi/patching-and-upgrades)
새 WiX 설치 정의부터 패치 가능성을 고려한다. 파일 추가·삭제·이동, 구성요소 키 경로, 레지스트리 변경이 패치 규칙을 만족하는지 검사하고, 규칙에 맞지 않으면 전체 업그레이드로 전환한다. 기준 버전의 MSI, 서명된 실제 파일, 구성요소 정의, WiX 빌드 정보와 도구 버전을 보관한다.
Burn EXE를 통해 설치한 제품은 MSP 적용 후에도 번들 표시 버전·MSI 등록·복구·제거가 일관되도록 설계한다. 직접 MSP 실행 또는 패치용 번들 중 실행 방식을 정하고, 이후 전체 설치와의 탐지·업데이트 경로까지 시험한다. 전체 파일을 다시 실행하는 것만으로 같은 ProductCode의 Minor Upgrade나 복구가 자동 처리된다고 가정하지 않는다.
## 패키지와 메타데이터
전체 설치본과 여러 패치를 하나의 목표 릴리스에 연결한다. 패치 아티팩트마다 다음 정보를 관리한다.
| 필드 | 의미 |
| --- | --- |
| patchId / artifactId | 변경 불가능한 패치 식별자 |
| targetReleaseId | 적용 완료 시 도달할 목표 릴리스 |
| supportedBases | 허용 기준 릴리스·빌드·설치 정보의 명시적 목록 |
| installerIdentity | 제품 코드, 아키텍처, 언어, 설치 범위 |
| patchState | 필요한 기존 패치와 대체되는 패치, 적용 순서 |
| requirements | 최소 업데이터, OS·런타임 조건, 공간·재부팅 조건 |
| integrity | 패치 크기·해시·서명, 필요한 기준 파일 및 목표 파일 검증 정보 |
| fallbackArtifactId | 동일 목표 릴리스의 검증된 전체 설치 경로 |
표시 버전 문자열만으로 패치 가능 여부를 판정하지 않는다. 같은 버전에서 다시 빌드한 파일, 아키텍처, 적용된 패치 이력 등이 다를 수 있다. 클라이언트의 파일 검증은 공급자가 관리하는 대상에 한정하고 사용자 CUI·도면·사용자 설정은 기준 해시와 같아야 하는 파일에 포함하지 않는다.
## 선택 예시
아래 버전은 모두 전환 후 같은 패치 계열이라는 가정의 예시다. 실제 지원 여부를 의미하지 않는다.
| 현재 상태 | 그룹 목표 | 선택 |
| --- | --- | --- |
| 미설치 | 2.0.2 | 2.0.2 전체 설치 |
| 2.0.0, 기준 일치 | 2.0.2 | 2.0.0→2.0.2 누적 패치 |
| 2.0.1, 기준 일치 | 2.0.2 | 2.0.1→2.0.2 패치 |
| 2.0.1, 기준 불일치 | 2.0.2 | 검증된 복구·전체 설치 경로 |
| 2.0.2 | 2.0.2 | 정상 상태라면 작업 없음 |
| 2.0.3 | 2.0.2 | 일반 정책에서 다운그레이드하지 않음 |
초기에는 지원 기준에서 목표까지 한 번에 도달하는 패치를 우선한다. 누적 패치는 선언한 모든 기준과 패치 이력을 검증한다. 모든 과거 버전 쌍의 패치를 만들 필요는 없으며, 지원 범위 밖은 전체 설치로 연결한다. 지원 기준 범위와 보존 기간은 운영 규모에 맞춰 확정한다.
## 적용과 실패 처리
1. 인증된 그룹의 목표 릴리스를 결정하고 현재 설치 정보·패치 이력·기준 상태를 조회한다.
2. 검증된 적용 경로 중 패치를 선택한다. 호환 패치가 없거나 이점이 없으면 승인된 전체 경로를 선택한다.
3. 패치를 다운로드하고 서명·해시·호환 조건을 검증한다. 설치 직전 배포 중지 여부를 다시 확인한다.
4. 설정 백업 성공과 앱 종료를 확인하고 다른 설치 작업과 직렬화한다.
5. Windows Installer로 적용하고 종료 코드·재부팅 필요 여부·패치 등록 상태를 기록한다.
6. 목표 파일 및 자체 PE 서명, 설치 버전, 핵심 기능을 검증한 후 성공을 확정한다.
다운로드 실패는 원본 설치를 변경하지 않은 상태에서 재시도한다. 적용 실패는 먼저 롤백 완료·재부팅 대기·현재 설치 상태를 판별한다. 상태가 확인되고 전체 경로가 허용될 때만 전체 설치로 전환한다. 롤백 실패나 불확실한 상태에서는 로그·백업을 보존하고 복구 대상으로 표시하며 무조건 덮어쓰지 않는다.
패치 제거를 통한 이전 버전 복귀는 패치가 제거 가능하게 작성되고 데이터 호환성이 검증된 경우에만 허용한다. 그 외에는 더 높은 버전의 수정 릴리스를 사용한다. 클라이언트 캐시·원본 패키지가 필요한 복구·제거 경로도 시험한다.
## 배포와 완료 기준
지원 기준별 패치는 전체 설치본과 함께 4단계 배포를 통과한다. 동일 목표에 도달하더라도 각 패치 경로의 검증 결과가 필요하다. 전체 릴리스 중지는 패치와 전체 설치 모두에 적용한다.
패치 적용 후 새로 설치한 목표 버전과 공급자 관리 파일·레지스트리·등록 버전·기능 상태가 일치해야 한다. 사용자 데이터는 보존하며 동일 바이트 상태를 요구하지 않는다. 패치 후 복구·제거·다음 업데이트와 실패 복구를 [검증 계획](07-implementation-and-validation.md)에 포함한다.
+40
View File
@@ -0,0 +1,40 @@
# EG-BIM 네트워크 설치 및 배포 계획
기준일: 2026-10-16, Asia/Seoul. 대상 프로그램: `D:\egbim\repo\14.1`.
EG-BIM의 기존 Windows 설치 구조를 유지하면서 InstallShield를 대체하고, 버전별 패키지 관리와 4단계 그룹 배포를 지원한다. Microsoft Store 배포와 코드 서명도 함께 준비한다.
사용자가 확정한 사항은 Windows 데스크톱 앱 배포, InstallShield 사용 중단, 버전별 패키지 관리와 패치 지원, 업로드 체계, 개발자 테스터부터 일반 사용자까지의 4단계 배포다. Microsoft Store 배포는 검토 대상이다.
현재 권고안은 **WiX MSI + Burn 전체 설치 EXE + 자체 배포 서버 및 업데이터**다. Store에는 전체 설치 EXE를 등록하는 경로를 우선 검토한다. WiX 채택, Azure 서명 서비스 계약, 세부 운영 기준은 아직 확정되지 않았다.
## 문서 목록
생성 프로그램의 구현 설계는 [Rust + Tauri 설계 문서](../code-design/README.md)에 별도로 정리한다. 파일·레지스트리 편집, 버전/GUID, 전체 릴리스·MSP 생성, 대용량 분할 출력과 화면/CLI 계약을 다룬다.
| 문서 | 내용 |
| --- | --- |
| [01 요구사항과 기존 프로그램 현황](01-requirements-and-current-state.md) | 확정 요구사항, 저장소 확인 결과, 설치 경로와 기존 업데이트 구조 |
| [02 설치기 전환](02-installer-migration.md) | InstallShield 대체, WiX와 Burn, 구버전 마이그레이션과 복구 |
| [03 버전별 패키지와 업로드](03-package-and-upload.md) | 버전 체계, 불변 패키지, 저장소, 검증과 공개 절차 |
| [04 사용자 그룹별 단계 배포](04-staged-rollout.md) | 4개 그룹, 대상 결정, 승인 기준, 배포 중지와 관측 |
| [05 Microsoft Store 배포](05-microsoft-store.md) | MSI·EXE 및 MSIX 경로 비교, 제출 조건, 자체 배포와의 관계 |
| [06 코드 서명과 SmartScreen](06-code-signing-and-smartscreen.md) | 서명 대상과 순서, 서비스 비용, 게시자, SmartScreen 한계 |
| [07 구현 순서와 검증 계획](07-implementation-and-validation.md) | 선행 결정, 구현 단계, 마이그레이션 및 배포 시험 |
| [08 버전별 패치](08-version-patching.md) | 기준 버전별 패치 선택, MSP, 누적 패치, 실패 복구 및 전체 설치 전환 |
## 설계 원칙
1. 테스트부터 일반 배포까지 같은 서명 완료 패키지를 사용한다.
2. 파일 업로드와 사용자 공개를 별도 상태로 관리한다.
3. 기존 설치 경로와 사용자 설정을 보존한다.
4. 설치 대상 버전은 서버에서 인증된 사용자·장치와 정책으로 결정한다.
5. 배포 중지, 설치 중 실패 복구, 설치 완료 후 장애 복구를 구분한다.
6. 코드 서명과 SmartScreen 평판을 구분한다. Azure 서명도 경고 면제를 보장하지 않는다.
7. 버전별 패치를 필수 지원하며, 전체 설치 파일도 함께 유지한다. 적용 가능한 기준 버전과 설치 상태를 검증한 뒤 패치를 실행한다.
## 검토 범위
기존 코드와 `.ism`을 읽어 설치 및 업데이트 구조를 확인했다. 새 설치기 구현, 인증서 발급, 서명, Store 제출, 실제 설치·제거 시험은 수행하지 않았다. 특히 기존 `BaronSoftware.Update` NuGet 패키지는 호출부만 확인했으며 내부 구현을 검증한 상태가 아니다.
외부 서비스 가격과 Store 정책은 기준일에 확인한 공식 문서를 따른다. 계약·출시 시점에는 각 문서의 공식 링크에서 다시 확인한다.