rubrapack 매뉴얼←↑→

11 레지스트리, 환경 변수, INI 파일, 파일 형식과 링크

목표: 다른 프로그램이 찾는 설정을 Hello 에 준다 - 모든 형식의 레지스트리 값, 환경 변수, INI 파일의 한 줄 - 그리고 Windows 가 .hello 파일과 hello: 링크를 Hello 로 열게 한다.

11.1 2분 만에 보는 레지스트리#

Windows 레지스트리는 폴더처럼 짜인 설정 데이터베이스다: 키는 다른 키와 값을 담고, 값에는 이름, 형식, 데이터가 있다. 맨 위 키("루트")는:

루트담는 것
HKLM(HKEY_LOCAL_MACHINE)컴퓨터 전체의 설정; 쓰려면 관리자 권한이 필요하다
HKCU(HKEY_CURRENT_USER)지금 사용자의 설정
HKCR(HKEY_CLASSES_ROOT)파일 형식과 링크(둘을 합쳐 보인 것)
HKMUrubrapack(과 Windows Installer)의 "모든 사용자용이면 HKLM, 한 사용자용이면 HKCU"

Windows 에서 regedit 를 실행하면 둘러볼 수 있다(모르는 것은 바꾸지 않는다).

11.2 원본#

# tutorial 11: hello.toml
format = 1

[package]
name = "Hello"
manufacturer = "Example Software"
version = "$(VERSION)"
arch = "x64"
upgrade-code = "{3F2A6C1D-8B4E-4F7A-9C2D-5E6F7A8B9C0D}"

[define]
VERSION = "1.9.0"

[dir.INSTALLDIR]
path = "$(ProgramFiles)/Hello"

[file.Hello]
dir = "INSTALLDIR"
source = "dist/hello.exe"

[file.Settings]
dir = "INSTALLDIR"
source = "dist/settings.ini"

[registry.InstallDir]
root = "HKLM"
key = 'SOFTWARE\Example Software\Hello'
name = "InstallDir"
value = "[INSTALLDIR]"

[registry.Greeting]
root = "HKLM"
key = 'SOFTWARE\Example Software\Hello'
name = "Greeting"
value = "Hello, world"
with = "file:Hello"

[registry.Runs]
root = "HKLM"
key = 'SOFTWARE\Example Software\Hello'
name = "MaxRuns"
type = "dword"
value = 100

[registry.BigNumber]
root = "HKLM"
key = 'SOFTWARE\Example Software\Hello'
name = "Limit"
type = "qword"
value = "0x100000000"

[registry.Colors]
root = "HKLM"
key = 'SOFTWARE\Example Software\Hello'
name = "Colors"
type = "multi"
value = ["red", "green", "blue"]

[registry.LogPath]
root = "HKLM"
key = 'SOFTWARE\Example Software\Hello'
name = "LogPath"
type = "expand"
value = "%TEMP%\\hello.log"

[registry.Legacy32]
root = "HKLM"
key = 'SOFTWARE\Example Software\Hello'
name = "Mode"
value = "compatible"
view = "32"

[registry.OldKey]
root = "HKLM"
key = 'SOFTWARE\Example Software\Hello Old'
remove = true

[registry.UserChoice]
root = "HKLM"
key = 'SOFTWARE\Example Software\Hello'
name = "FirstRun"
type = "dword"
value = 1
keep = true

[env.HelloHome]
name = "HELLO_HOME"
value = "[INSTALLDIR]"

[env.Path]
name = "PATH"
value = "[INSTALLDIR]"
mode = "append"

[ini.InstalledVersion]
dir = "INSTALLDIR"
file = "settings.ini"
section = "hello"
key = "installed"
value = "[ProductVersion]"

[ini.Plugins]
dir = "INSTALLDIR"
file = "settings.ini"
section = "hello"
key = "plugins"
value = "core"
mode = "add"

[assoc.HelloDoc]
extension = ".hello"
prog-id = "Example.HelloDocument"
description = "Hello document"
target = "file:Hello"
icon = "file:Hello"
args = "--open \"%1\""

[protocol.HelloLink]
name = "hello"
description = "Hello link"
target = "file:Hello"

TOML 메모: 작은따옴표 문자열은 쓴 그대로 쓰이므로 'SOFTWARE\Example Software\Hello' 에는 백슬래시를 겹쳐 쓸 필요가 없다. 큰따옴표 안에서는 백슬래시가 이스케이프를 시작한다("%TEMP%\\hello.log").

11.3 레지스트리 값: [registry.ID]#

typeTOML 값레지스트리 형식
string(기본)문자열REG_SZ
expand%변수% 가 든 문자열REG_EXPAND_SZ - 값을 읽을 때 Windows 가 %TEMP% 를 펼친다
dword정수 0 .. 4294967295REG_DWORD, 32비트
qword정수, 또는 "0x" 와 16진수 16자리까지REG_QWORD, 64비트
binary16진수, "01ff"REG_BINARY
multi문자열 배열REG_MULTI_SZ

Windows Installer 는 REG_QWORD 를 스스로 쓰지 못한다. qword 값을 위해 rubrapack 은 작은 도우미 DLL 을 패키지에 더하고, 이것이 값을 쓰고 설치가 실패하면 이전 값을 되돌린다.

11.4 환경 변수: [env.ID]#

컴퓨터 전체의 변수(사용자별 설치에서는 사용자의 것)다. mode = "set"(기본)은 정하고, append 는 있는 것의 끝에 ;값 을, prepend 는 앞에 값; 을 더한다. 제품을 지우면 정확히 그만큼 되돌린다: HELLO_HOME 은 지워지고, PATH 에서는 ;C:\Program Files\Hello\ 만 빠진다. keep = true 는 남긴다. 설치 뒤에 시작한 프로그램이 바뀐 것을 본다(이미 열려 있던 터미널은 못 본다).

11.5 INI 파일: [ini.ID]#

INI 파일은 [섹션] 과 키=값 줄로 된 글 파일이다. mode = "set"(기본)은 섹션에 키=값 을 쓰고, add 는 값을 쉼표로 나눈 목록에 더하고(plugins=core, 또는 plugins=extra 가 있었다면 plugins=extra,core), remove 는 키를 지운다 - 파일을 설치하기 전에 하므로 옛 판이 남긴 INI 파일을 치운다. 제거는 set 과 add 가 쓴 것을 빼낸다. file 은 dir 안의 파일 이름이며, 패키지가 설치하는 파일이 아니어도 된다.

설치 뒤 settings.ini 는:

[hello]
greeting=Hello
installed=1.9.0
plugins=core

11.6 파일 형식: [assoc.ID]#

[assoc.HelloDoc] 는 Windows 가 .hello 파일을 Hello 로 열게 한다:

사용자가 .hello 에 이미 다른 프로그램을 골라 두었다면 Windows 는 그 선택을 지킨다.

11.7 링크: [protocol.ID]#

[protocol.HelloLink] 는 hello: 방식을 등록한다. 브라우저나 실행 상자의 hello:world 링크가 링크 전체를 인자로 Hello 를 시작한다.

11.8 우클릭 메뉴: [menu.ID]#

파일에 무언가를 하는 프로그램 - 변환한다, 검사한다, 폴더를 자기 안에서 연다 - 은 탐색기의 우클릭 메뉴에 자리가 있어야 한다. Hello 에는 그런 명령이 없지만, 있다면 이것이 전부다:

[menu.Greet]
on = [".hello", "folder"]         # .hello 파일과 폴더에서
text = "Greet with Hello"
text-ko = "Hello 로 인사"
target = "file:HelloExe"
args = "--greet \"%1\""           # "%1" 은 우클릭한 것

Windows 에는 이런 메뉴가 둘 있고, 이 표가 둘 다 채운다. 옛 메뉴(Windows 10, Windows 11 의 "추가 옵션 표시")는 레지스트리를 읽고, 패키지가 그것을 적는다. Windows 11 메뉴는 신원이 있는 패키지의 항목만 받고 항목마다 작은 COM 클래스가 맡아야 한다 - rubrapack 이 그 클래스(메뉴 부품)를 가져오고, MSI 라면 프로그램 옆에 아주 작은 신원 패키지를 설치해 등록한다. 직접 쓸 코드도, 살 인증서도 없다. 자세한 이야기는 참조의 "탐색기의 우클릭 메뉴"에 있다.

11.9 COM 클래스: [com.ID]#

다른 프로그램이 클래스 ID 로, 또는 스크립트에서 Hello.Widget 같은 이름으로 객체를 만들어 쓰는 프로그램이나 DLL 은 COM 클래스로 등록해야 한다. Hello 에는 없지만, 패키지에 DLL widget.dll 이 있다면 이것으로 충분하다:

[com.Widget]
file = "file:WidgetDll"
class = "{8D1E2F30-4A5B-4C6D-8E7F-901A2B3C4D35}"     # rubrapack guid 가 하나 만들어 준다
description = "Hello widget"
prog-id = "Hello.Widget"
threading = "both"

그러면 PowerShell 이 New-Object -ComObject Hello.Widget 으로 객체를 하나 만든다. 제거하면 등록도 풀린다.

DLL 클래스는 파일 형식의 탐색기 처리기도 될 수 있다 - 탐색기가 .hello 파일에 보이는 그림, 미리 보기 창에 보이는 것, 나열하는 속성:

[handler.HelloThumbs]
kind = "thumbnail"                # 또는 "preview", "property"
class = "{8D1E2F30-4A5B-4C6D-8E7F-901A2B3C4D41}"     # DLL 의 [com.*] 클래스
types = [".hello"]

description 은 미리 보기 처리기의 이름이다. 속성 처리기는 컴퓨터별 패키지가 필요하다. MSIX 에서는 썸네일과 미리 보기 처리기는 동작하지만(미리 보기 처리기의 클래스는 threading = "sta") 속성 처리기는 동작하지 않으므로, 거기서 속성 처리기는 msi-only = true 를 붙인다.

11.10 해 보기#

설치한 뒤:

Hello 를 지우면 FirstRun 말고는 모두 사라진다.

11.11 안에서 무슨 일이 일어났나#

C:\work\hello> rubrapack inspect hello.msi Registry
...
Colors	2	SOFTWARE\Example Software\Hello	Colors	[~]red[~]green[~]blue[~]	C_f023...
Greeting	2	SOFTWARE\Example Software\Hello	Greeting	Hello, world	C_185f...
HelloDoc.Ext	0	.hello		Example.HelloDocument	C_185f...
LogPath	2	SOFTWARE\Example Software\Hello	LogPath	#%%TEMP%\hello.log	C_2e80...
Runs	2	SOFTWARE\Example Software\Hello	MaxRuns	#100	C_97ef...
...

둘째 열은 루트다(0 HKCR, 1 HKCU, 2 HKLM, -1 HKMU). 값 열은 Windows Installer 가 원하는 대로 첫 글자에 형식을 싣는다: #100 은 DWORD, #% 는 펼치는 문자열, [~] 는 여러 문자열을 가르고, #x 는 이진 데이터를 시작한다. 파일 형식과 링크는 프로그램 컴포넌트 안의 HKCR 아래 레지스트리 값일 뿐이다. QWORD 값은 이 표에 없다: 도우미 DLL 을 위한 속성 RP_QWORDS 에 실려 간다. 환경 변수는 Environment 표에 있다:

HelloHome	=-*HELLO_HOME	[INSTALLDIR]	C_0fa9...
Path	=-*PATH	[~];[INSTALLDIR]	C_82df...

이름에서 = 는 "정하기", - 는 "제거 때 지우기", * 는 "시스템 변수"다. 값의 [~] 는 원래 있던 것을 뜻한다.