2010-12-10 3 views
0

WiX 3.0을 사용하고 있습니다. 업그레이드를 수행 할 때 모든 레지스트리 설정을 유지하려고합니다. 나는 그것이 간단하게 보이는 생각했기 때문에 업그레이드시 레지스트리 설정 유지

나는 다음 링크를 내가 재산 및 RegistrySearch 방식이 아닌 사용자 지정 작업 방식을 사용하는 것을 선호 http://www.mail-archive.com/[email protected]/msg28844.html

을 발견했다.

불행히도,이 접근법은 나에게 잘 맞지 않습니다. 내 프로젝트에는 일부 DWORD 및 SZ 유형 레지스트리 값이 있습니다. 모든 DWORD 형식 레지스트리 값의 경우 앞에 #이 추가됩니다. WiX 참조 설명서를 확인했습니다. 이것이 RegistrySearch의 작동 방식입니다.

업그레이드 후 결과는 모두 내 DWORD 유형 레지스트리가 SZ로 변경됩니다. 값 앞에 #이 붙는 것을 제외하고는 값이 같습니다. 예를 들어, DWORD 형식의 "LogLevel"레지스트리 값에서 값 2를 얻었습니다. 업그레이드 후 동일한 위치에 SZ 유형의 "LogLevel"레지스트리 값에서 "# 2"값을 얻습니다. 여기

내가 다시 넣어 전에 나를 LOG_LEVEL 속성에서 "#"을 잘라내 도움이 될 수있는 문자열 함수가 있는지 궁금 코드 조각

<Property Id='LOG_LEVEL' Value='Information'> 
    <RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/> 
</Property> 

<Component Id="RegistryKey"> 
    <RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'> 
     <RegistryValue Type='int' Name='LogLevel' Value='[LOG_LEVEL]'/> 
    </RegistryKey> 
</Component> 

입니다. 또는 업그레이드를 수행 할 때 레지스트리 키를 보존하는 더 똑똑한 방법이 있습니까? 맞춤 동작 방식을 선택해야합니까?

답변

5

마침내 RegistrySearch 접근법이 작동했습니다. 앞으로 이것이 다른 사람들에게 도움이되기를 바랍니다.

MSI 설명서를 확인했습니다. 레지스트리 테이블에는 실제로 type이라는 열이 없습니다. 대신 MSI가 어떤 유형의 레지스트리 값을 만들어야하는지 알 수 있도록 이상한 방식으로 값을 저장합니다. 필자의 경우 DWORD 형식의 레지스트리 값을 만들고 싶습니다. 숫자 값 1을 레지스트리 값에 넣으려는 경우 레지스트리 테이블에 값을 # 1로 저장해야합니다. 다음은 Registry table

에 대한 링크입니다. 그렇다면 왜 Wix RegistryValue에 필수 속성 유형이 있습니까? 윅스가 너에게 친절 해지기 위해서라고 생각한다. 유형을 int로 표시하면 값 속성에 "1"을 넣을 수 있습니다. "1"대신 "# 1"을 입력해야한다는 것을 기억할 필요는 없습니다. Wix 소스 코드를 컴파일하면 컴파일러가 더러운 작업을 수행하고 "1"을 "# 1"로 변환합니다.

마찬가지로 RegistrySearch는 MSI 데이터베이스 테이블 RegLocator에 직접 매핑됩니다. 내 레지스트리 값 유형이 DWORD이기 때문에 # 1을 반환합니다. 이번에 윅스가 나에게 번역을하지 않은 것은 너무 나쁘다. 다음 코드는 테이블의 원시 데이터를 나에게 반환한다. 그래서, 내 재산 LOG_LEVEL 여기 1.

<Property Id='LOG_LEVEL' Value='3'> 
    <RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/> 
</Property> 

대신 # 1을 저장하는 것은 속성에 레지스트리 값을 저장 RegistrySearch

내 코드에 대한 링크입니다. 그런 다음 다음 코드를 사용하여 다시 넣으려고했습니다.

<Component Id="RegistryKey"> 
    <RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'> 
    <RegistryValue Type='int' Name='LogLevel' Value='[LOG_LEVEL]'/> 
    </RegistryKey> 
</Component> 

내가 말했듯이, Wix는 "int"유형을 볼 때 #을 추가 할 것입니다. 이제 레지스트리 테이블의 값은 ## 1입니다. MSDN 문서를 확인하면 ## 1은 문자열 값 "# 1"로 해석됩니다. 따라서, 내 레지스트리 값이 문제를 해결하려면 새로운 유형의 SZ과 새로운 가치 "# 1"

으로 다시 만들어, 내가 유형 "문자열"을 지정 althought이

<Property Id='LOG_LEVEL' Value='#3'> 
    <RegistrySearch Id='LogLevelRegistry' Type='raw' Root='HKLM' Key='Software\Company\Product' Name='LogLevel' Win64='$(var.Win64)'/> 
</Property> 

<Component Id="RegistryKey"> 
    <RegistryKey Root='HKLM' Key='Software\Company\Product' Action='createAndRemoveOnUninstall'> 
    <RegistryValue Type='string' Name='LogLevel' Value='[LOG_LEVEL]'/> 
    </RegistryKey> 
</Component> 

주에 내 코드를 변경 여기에, 나는 여전히 나를 위해 생성 된 DWORD 타입의 레지스트리 값을 가지고있다. 이것이 MSI가 레지스트리 테이블의 값을 해석하는 방법이기 때문입니다. LogLevel 레지스트리 값이 존재하지 않으면 (새 설치) 기본값으로 # 3을 설정합니다. LogLevel 레지스트리 값이 존재하면 기존 LogLevel을 보존합니다.

또한이 방법은 Wix 3.0이 속성 값을 처리하지 않기 때문에 작동합니다. 속성에 저장된 값을 레지스트리 테이블에 직접 저장합니다. 호기심에서 벗어나 다음과 같은 시도도했습니다.

<RegistryValue Type='string' Name='LogLevel' Value='#1'/> 

이번에는 Wix가 # 문자를 올바르게 이스케이프 처리하고 ## 1을 레지스트리 테이블에 넣습니다. 나중에 Wix가 속성 값 내에서 # 문자를 벗어나기로 결정했다면, 여기에있는 나의 해결책은 작동하지 않을 것이다.

0

어쨌든 사용자 지정 작업이 필요합니다. This set of custom actions and extensions에는 이러한 종류의 조치가 있다고 주장됩니다. 기업에서 잘 테스트되고 사용되는 것으로 주장되기 때문에이를 사용하는 것이 좋습니다.

희망이 도움이됩니다.

+0

고마워요, 오늘 체크 아웃하겠습니다 –

+0

wixext를 다운로드하고 시도했습니다. 해당 SystemToolsMsi.wxs 샘플에서 사용합니다 레지스트리 백업을 수행하십시오. 분명히, 설치 롤백 때만 백업 레지스트리를 복원 할 수 있습니다. 설치가 커밋 될 때도 백업 레지스트리를 복원하고 싶습니다. 어쨌든, 이것은 나에게 좋은 힌트를 제공합니다. 사용자 지정 작업에 대해 더 잘 이해했습니다 –

+0

http://code.dblock.org/Source/msiext/1.2/Docs/class_wix_1_1_extensions_1_1_system_tools_1_1_registry_key_copy.html 이 링크는 RegistryKeyCopy가 작동하는 방식을 설명하며 현재 사용 사례는 포함하지 않습니다. 기대하고있다. C# 사용자 지정 작업을 작성하려고합니다. –

관련 문제