# Visual Studio 2026 개발 Tornado Live 실행 > 2026-07-18: 현재 지정 개발 PC에서는 사용자가 Tornado2/PGM 마이그레이션 작업을 > 상시 허용했다. 아래 Git 제외 로컬 승인 파일은 이 개발 환경의 지속 설정으로 사용하며, > 매 실행이나 명령마다 새 계획 해시·대화형 승인을 요청하지 않는다. 운영/방송 대상에는 > 이 예외를 적용하지 않으며 자세한 범위는 > [개발 환경 상시 권한](DEVELOPMENT_ENVIRONMENT_AUTHORIZATION.md)을 따른다. ## 목적과 안전 기본 이 문서는 개발 PC의 Visual Studio 2026에서 `MBN_STOCK_WEBVIEW.LegacyParityApp`을 명확한 시작 대상으로 실행하고, 개발 Tornado2에 연결하는 방법을 설명한다. 솔루션 루트의 `.vsconfig`는 **WinUI 애플리케이션 개발** (`Microsoft.VisualStudio.Workload.Universal`) 워크로드를 요구한다. Visual Studio가 누락 구성 요소 설치를 안내하면 먼저 설치를 완료하고 Visual Studio를 다시 시작한다. `GetLatestMSVCVersion`이 `...\VC\Tools\MSVC`를 찾지 못하는 오류는 이 WinUI 워크로드가 빠진 설치에서 발생하는 사전 조건 오류이며 앱 코드나 K3D 연결 오류가 아니다. 지정 개발 PC의 Debug와 Release 전체 앱은 모두 보호된 `Live`로만 기동한다. 개발 Live는 다음 조건이 동시에 맞을 때 기존 Live 게이트를 설정한다. 1. 정상 무인자 실행이거나 시작 인자가 정확히 `--development-live` 하나이다. 2. 소스 전용 설정 빌드가 아닌 전체 runtime 빌드이다. 3. 아래 Git 제외 로컬 승인 파일이 존재하며 엄격한 스키마 검사를 통과한다. 조건이 하나라도 다르면 환경 변수를 설정하지 않는다. 로컬 파일이 없거나 읽기 권한이 없고, JSON 또는 해시 형식이 잘못된 경우에는 전체 앱의 Live 엔진 기동을 차단하고 명확한 오류를 표시한다. `DryRun`으로 폴백하지 않는다. 새 clone처럼 아직 검증된 runtime 연결이 없는 경우의 첫 F5는 예외적으로 소스 전용 설정 앱을 연다. 이 프로세스는 `--development-live`를 적용하지 않고 DB와 송출을 모두 차단한다. 화면에서 기존 코더의 `Cuts`와 `Res` 폴더, 두 개만 선택한다. 설정 버튼은 선택한 `Res\MmoneyCoder.ini`의 DB 형식을 확인하고, 검증된 PowerShell 초기화기를 통해 두 경로, 로컬 MSBuild binding, `C:\K3DAsyncEngine` x64 등록/파일, 지속 K3D pin, Development Live 승인 및 Debug x64 빌드를 함께 검증한다. 이 작업은 시간이 걸릴 수 있다. 설정 중에는 DB 연결, K3D COM 활성화, Tornado2/PGM 연결 또는 송출 명령을 실행하지 않는다. 설정을 완료한 뒤 창을 닫고 F5를 한 번 더 누르면 검증된 전체 앱이 시작된다. 기존 로컬 Live 설정과 충돌하면 화면은 자동으로 덮어쓰지 않고 `127.0.0.1:30001`, 채널 미지정, 고정 allowlist/timeout으로 교체된다는 안내와 별도 `기존 Live 설정 교체 후 다시 시도` 버튼을 표시한다. 이 명시적 재시도는 K3D pin과 runtime binding을 바꾸지 않는다. runtime binding 충돌이나 K3D pin 차이로 중단되면 대상을 검토한 뒤 아래 수동 교체 절차를 사용한다. 자세한 절차는 [개발 PGM 인수 절차](DEVELOPMENT_LIVE_HANDOFF.md#2-기존-자산-보유-pc-clone-후-1회-초기화)를 따른다. `MmoneyCoder.ini`의 DB 자격증명은 테스트 개발 서버용이라도 Git에 넣지 않는다. 첫 실행 설정은 파일을 복사하지 않고 형식만 검증한다. 빌드 출력, 선택 경로 설정과 MSIX에도 포함하지 않는다. 전체 앱은 저장된 `Res`의 정확한 `MmoneyCoder.ini`를 매 실행 직접 읽으며, 누락·손상된 파일을 LocalAppData나 환경 변수로 대체하지 않고 Live 기동을 차단한다. ## Visual Studio 시작 대상과 프로필 공유 솔루션 실행 프로필은 저장소 루트의 `MBN_STOCK_WEBVIEW.slnLaunch`에 있으며 다음 프로젝트만 시작한다. ```text src\MBN_STOCK_WEBVIEW.LegacyParityApp\MBN_STOCK_WEBVIEW.LegacyParityApp.csproj ``` `Debug|x64`와 `Release|x64`의 MSIX Deploy 대상도 루트 프로토타입이 아니라 이 프로젝트이다. Visual Studio의 시작 드롭다운에는 다음 프로필 하나만 표시된다. | 순서 | 프로필 | 동작 | |---:|---|---| | 1 | `MBN_STOCK_WEBVIEW.LegacyParityApp - Development Live (Package)` | `--development-live`를 전달한다. 유효한 로컬 승인 파일이 있을 때만 Live를 구성한다. | 개발 PC에서는 공유 실행 프로필 `Legacy Parity App (VS F5)`, 구성 `Debug` 또는 `Release`, 플랫폼 `x64`, Development Live 패키지 프로필을 선택하고 F5를 누른다. 앱은 단일 인스턴스이므로 구성을 바꿀 때 기존 인스턴스를 정상 종료한 뒤 다시 실행해야 한다. 패키지된 WinUI 3 full-trust 실행에서는 Visual Studio가 프로세스 명령줄에 인자를 전달해도 `LaunchActivatedEventArgs.Arguments`가 빈 문자열일 수 있다. 부트스트랩은 activation 인자가 비어 있을 때에만 `Environment.GetCommandLineArgs()`를 확인한다. 인자가 없으면 정상 Live 실행으로 처리하고, 정확히 `exe + --development-live`이면 호환 Live 실행으로 처리한다. 추가 인자가 있으면 합치거나 일부를 무시하지 않고 기동을 거부한다. Release도 Debug와 동일한 보호된 승인 파일과 검증을 사용한다. ## 로컬 승인 파일 ### 지속 K3D pin 첫 실행 자동 설정과 수동 Development Live 초기화는 모두 `C:\K3DAsyncEngine`의 HKLM x64 등록, CLSID·ProgID·TypeLib, AMD64와 회사 표준 vendor 배치를 먼저 검증한다. 검사를 통과한 최초 native/Interop DLL의 SHA-256은 다음 사용자 전용 파일에 지속 저장한다. ```text %LOCALAPPDATA%\MBN_STOCK_WEBVIEW\Config\k3d-pins.local.json ``` 이후 등록 DLL의 해시가 이 기준과 다르면 폴더 경로를 다시 저장해도 자동으로 pin을 바꾸지 않고 Development Live를 차단한다. 정식 DLL 교체 시에는 벤더 배포본 등으로 독립 검증한 `-NativeSha256`과 `-InteropSha256`을 제공하고 `Initialize-ExistingDevelopmentPc.ps1 -ReplaceK3DPin -ReplaceLiveConfig` 수동 절차를 사용해야 한다. `-ReplaceK3DPin`과 현재 등록 파일을 자동 채택하는 `-PinRegisteredK3D`는 함께 사용할 수 없다. 정확한 명령은 [개발 PGM 인수 절차](DEVELOPMENT_LIVE_HANDOFF.md#k3d-dll이-정식으로-교체된-경우)에 있다. ### Development Live 승인 실제 파일 경로는 다음과 같다. ```text %LOCALAPPDATA%\MBN_STOCK_WEBVIEW\Config\playout.development-live.local.json ``` 실제 파일명은 `.gitignore`에 포함되어 있다. 저장소의 `Config\playout.development-live.example.json`을 구조 참고용으로 사용하되, 예제의 해시 placeholder는 실행 가능한 값이 아니다. 실제 승인 파일은 정확히 다음 다섯 속성만 가진다. ```json { "schemaVersion": 1, "mode": "Live", "authorization": "I_AUTHORIZE_LIVE_PROGRAM_OUTPUT_FOR_THIS_LAUNCH", "nativeSha256": "<독립적으로 승인한 x64 K3D native DLL의 64자리 SHA-256>", "interopSha256": "<독립적으로 승인한 x64 K3D Interop DLL의 64자리 SHA-256>" } ``` 검사 규칙은 다음과 같다. - 파일 크기는 1~4096바이트이다. - 파일과 `%LOCALAPPDATA%` 아래의 중간 디렉터리는 reparse point가 아니다. - JSON 주석, trailing comma, 중복 속성, 알 수 없는 속성, 대소문자가 다른 속성을 허용하지 않는다. - `schemaVersion`은 숫자 `1`, `mode`는 정확히 `Live`, `authorization`은 위 문자열과 정확히 일치해야 한다. - 두 해시는 공백 없는 64자리 16진수여야 한다. 경로나 DLL은 Git에 기록하지 않는다. - 파일 없음, 잘못된 경로, 공유 위반, I/O 또는 읽기 권한 오류는 모두 같은 제한된 `authorization-unavailable` 결과로 처리하며 경로와 값은 로그에 표시하지 않는다. 수동 생성·교체 시에는 현재 설치 파일의 해시를 그 자리에서 계산했다는 이유만으로 승인 값으로 사용해서는 안 된다. 벤더 배포본 또는 기존에 독립 검수된 증적과 대조한 값을 사용한다. 첫 실행 자동 설정과 일반 수동 Development Live 초기화는 위 지속 K3D pin을 먼저 만들거나 대조한 뒤 같은 기준값으로 이 승인 파일을 발급한다. 파일 ACL은 현재 개발 사용자와 관리자만 수정할 수 있도록 유지한다. ## 기존 playout.local.json 기존 설정 파일 경로는 그대로이다. ```text %LOCALAPPDATA%\MBN_STOCK_WEBVIEW\Config\playout.local.json ``` 이 파일의 `mode`는 `Live`로 유지한다. Development Live 부트스트랩은 Debug와 Release 프로세스에서 검증된 Live authorization과 K3D 해시를 process scope로 적용한다. 기존 이중 게이트를 유지하기 위해 로컬 설정에는 `trustedLiveOutputEnabled: true`가 명시되어야 한다. 실제 cue의 `PlayoutCue.SceneName`은 builder의 대표 SceneCode가 아니라 활성 cut alias다. 전체 이관 UI를 개발 PGM에서 검증할 때 `testSceneAllowlist`에는 `LegacySceneRuntimeCoverage.ExpectedCutCodes`와 동일한 다음 45개 alias를 사용한다. ```text 5001, 5006, 5011, 5016, 50160, 5023, 5024, 5025, 5026, 5029, 5032, 5037, 5068, 5070, 5072, 5074, 5076, 5077, 5078, 5079, 5080, 5081, 5082, 5083, 5084, 5085, 5086, 50860, 5087, 5088, 6001, 6067, 8001, 8002, 8003, 8018, 8032, 8035, 8040, 8046, 8051, 8056, 8061, 8067, N5001 ``` `8010`과 `8086`은 활성 cue alias가 아니므로 넣지 않는다. 승인 Cuts에 종속 asset이 없는 장면은 allowlist에 있더라도 기존 asset 검증에서 계속 차단된다. ## 프로세스 범위 적용 순서 엄격한 파일 검사가 끝난 뒤 다음 값을 process scope에만 적용한다. 1. 승인된 native SHA-256 pin 2. 승인된 Interop SHA-256 pin 3. `MBN_STOCK_PLAYOUT_MODE=Live` 4. Live authorization — 항상 마지막에 설정 중간 환경 쓰기가 실패하면 기존 값을 복구하고 Live authorization을 새로 설정하지 않는다. `EnvironmentLiveAuthorization`은 `MainWindow`와 `IPlayoutEngine`을 만들 때 값을 한 번만 캡처하므로, 부트스트랩은 반드시 `new MainWindow()`보다 먼저 실행된다. Release 빌드도 Debug와 같은 로컬 승인 파일을 읽고 같은 안전 게이트를 적용한다. 이는 운영/방송 환경의 별도 승인 절차를 대체하지 않는다.