Можно ли использовать данные, полученные при использовании RegistrySearch в RegistryValue


English version is here.


 


Вопрос:


Можно ли использовать данные, полученные при использовании RegistrySearch в RegistryValue? Нечто вроде этого:


 


<Property Id=”PROP1″>


    <RegistrySearch Id=”search1″


                    Root=”HKLM”


                    Key=”somekey”


                    Name=”somename”


                    Type=”raw” />


</Property>





<RegistryValue Type=”???” Name=”othervalue” Value=”PROP1″ />


 


Прежде всего, для того чтобы использовать свойство необходимо, чтобы атрибут элемента имел тип данных Formatted.  Документация по таблице Registry и элементу RegistryValue указывает, что как колонка Value, так и атрибут Value на самом деле являются Formatted.  Так что мы можем продолжить.  Единственное, что нам надо изменить, это значение атрибута Value:


<RegistryValue Type=”???” Name=”othervalue” Value=”[PROP1]” /> 


Теперь, как насчет атрибута Type?  Какое значение он должен иметь?


В документации по таблице Registry говорится о том, что обычно значение в колонке Value будет интерпретировано как строка (REG_SZ) при условии, что значение не имеет в начале строки один из специальных префиксов и не содержит тильда последовательностей [~]:


















Префикс Значение
#x Шестнадцатеричное число (REG_BINARY)
#% Расширяемая (еxpandable) строка (REG_EXPAND_SZ)
# Целое число (REG_DWORD)
Contains [~] Список строк разделенных друг от друга значением Null (REG_MULTI_SZ).

Это означает, что мы можем использовать Type=”string” при условии, что мы дадим правильный формат значениям.  Следующий фрагмент успешно доказывает это:


<SetProperty Id=STRINGPROPCONST After=AppSearch Value=QWERTY />


<SetProperty Id=DWORDPROPCONST After=AppSearch Value=#2 />


<SetProperty Id=EXPANDSZPROPCONST After=AppSearch Value=#%%SystemRoot%\System32\svchost.exe />


<SetProperty Id=BINARYPROPCONST After=AppSearch Value=#x0123456789ABCDEF />


<SetProperty Id=MULTISZPROPCONST After=AppSearch Value=a[~]b[~]c />


 


<Directory Id=TARGETDIR Name=SourceDir>


  <Directory Id=LocalAppDataFolder>


    <Directory Id=INSTALLLOCATION Name=SetRegistry1>


      <Component Id=ProductComponent


                 Guid=f4ca4e76-d04a-4b89-9a1a-7a666a42a635>


        <CreateFolder />


        <RemoveFolder Id=RemoveMe On=uninstall />


        <RegistryKey Id=TestValue


                     Root=HKCU


                     Key=ACME Corp


                     Action=createAndRemoveOnUninstall>



           <RegistryValue Id=StringValueConst


                          Type=string


                          Action=write


                          Name=StringPropertyConst


                          Value=[STRINGPROPCONST] />


           <RegistryValue Id=DWordValueConst


                          Type=string


                          Action=write


                          Name=DWordPropertyConst


                          Value=[DWORDPROPCONST] />


           <RegistryValue Id=ExpandSzValueConst


                          Type=string


                          Action=write


                          Name=ExpandPropertyConst


                          Value=[EXPANDSZPROPCONST] />


           <RegistryValue Id=BinaryValueConst


                          Type=string


                          Action=write


                          Name=BinaryPropertyConst


                          Value=[BINARYPROPCONST] />


           <RegistryValue Id=MultiSzValueConst


                          Type=string


                          Action=write


                          Name=MultiSzPropertyConst


                          Value=[MULTISZPROPCONST] />


        </RegistryKey>


      </Component>


    </Directory>


  </Directory>


</Directory>



Теперь, как нам отформатировать данные, прочитанные из реестра (registry) во время AppSearch?  В документации по таблице RegLocator говорится о том, что Windows Installer сам добавит префикс, соответствующий типу данных в реестре к значению из реестра.  Здорово.  Давайте проверим, так ли это на самом деле:


<Property Id=STRINGPROP>


  <RegistrySearch Id=Search1


                  Root=HKLM


                  Key=SYSTEM\CurrentControlSet\services\wscsvc


                  Name=ObjectName


                  Type=raw


                  Win64=no/>


</Property>


<Property Id=DWORDPROP>


  <RegistrySearch Id=Search2


                  Root=HKLM


                  Key=SYSTEM\CurrentControlSet\services\wscsvc


                  Name=Start


                  Type=raw


                  Win64=no/>


</Property>


<Property Id=EXPANDSZPROP>


  <RegistrySearch Id=Search3


                  Root=HKLM


                  Key=SYSTEM\CurrentControlSet\services\wscsvc


                  Name=ImagePath


                  Type=raw


                  Win64=no/>


</Property>


<Property Id=BINARYPROP>


  <RegistrySearch Id=Search4


                  Root=HKLM


                  Key=SYSTEM\CurrentControlSet\services\wscsvc


                  Name=FailureActions


                  Type=raw


                  Win64=no/>


</Property>


<Property Id=MULTISZPROP>


  <RegistrySearch Id=Search5


                  Root=HKLM


                  Key=SYSTEM\CurrentControlSet\services\wscsvc


                  Name=DependOnService


                  Type=raw


                  Win64=no/>


</Property>


 


<SetProperty Id=STRINGPROPRAW After=AppSearch Value=..[STRINGPROP] />


<SetProperty Id=DWORDPROPRAW After=AppSearch Value=..[DWORDPROP] />


<SetProperty Id=EXPANDSZPROPRAW After=AppSearch Value=..[EXPANDSZPROP] />


<SetProperty Id=BINARYPROPRAW After=AppSearch Value=..[BINARYPROP] />


<SetProperty Id=MULTISZPROPRAW After=AppSearch Value=..[MULTISZPROP] />


 


<Directory Id=TARGETDIR Name=SourceDir>


  <Directory Id=LocalAppDataFolder>


    <Directory Id=INSTALLLOCATION Name=SetRegistry1>


      <Component Id=ProductComponent


                 Guid=f4ca4e76-d04a-4b89-9a1a-7a666a42a635>


        <CreateFolder />


        <RemoveFolder Id=RemoveMe On=uninstall />


        <RegistryKey Id=TestValue


                     Root=HKCU


                     Key=ACME Corp


                     Action=createAndRemoveOnUninstall>


 


          <RegistryValue Id=StringValueRaw


                         Type=string


                         Action=write


                         Name=StringPropertyRaw


                         Value=[STRINGPROPRAW] />


          <RegistryValue Id=DWordValueRaw


                         Type=string


                         Action=write


                         Name=DWordPropertyRaw


                         Value=[DWORDPROPRAW] />


          <RegistryValue Id=ExpandSzValueRaw


                         Type=string


                         Action=write


                         Name=ExpandPropertyRaw


                         Value=[EXPANDSZPROPRAW] />


          <RegistryValue Id=BinaryValueRaw


                         Type=string


                         Action=write


                         Name=BinaryPropertyRaw


                         Value=[BINARYPROPRAW] />


          <RegistryValue Id=MultiSzValueRaw


                         Type=string


                         Action=write


                         Name=MultiSzPropertyRaw


                         Value=[MULTISZPROPRAW] />


        </RegistryKey>


      </Component>


    </Directory>


  </Directory>


</Directory>


Как Вы видите, я сохранил значения из реестра в свойствах во время исполнения AppSearch и затем использовал Custom Action Type 51 для того, чтобы скопировать их в другие свойства, но с добавлением двух точек в начале строки.  Я сделал это для того, чтобы позже сохранить эти значения в реестре именно как строки, а не как другие типы данных.


Нет ничего удивительного в том, что мульти-строковые (multi-string) значения записаны в реестр как мульти-строковые, поскольку их интерпретация зависит от наличия [~] в строке, а не от того, с какого префикса они начинаются.  Что удивительно, это то что расширенные (expanded) строки записаны в реестр как уже преобразованные в строку, а не непреобразованное значение с префиксом #%, хотя документация по таблице RegLocator ясно говорит о том, что именно это и должно быть результатом.


Так что, за исключением expanded строк, все что нам нужно, это сохранить считанные во время AppSearch данные в реестр без каких либо изменений:


<?xml version=1.0 encoding=UTF-8?>


<Wix xmlns=http://schemas.microsoft.com/wix/2006/wi>


  <Product Id=30eb65de-f04a-4a79-a153-4542687b7515


           Name=SetRegistry1


           Language=1033


           Version=1.0.0.0


           Manufacturer=SetRegistry1


           UpgradeCode=da268df3-4a01-41de-8c09-a8c11abee160>


  <Package InstallerVersion=200 Compressed=yes InstallScope=perUser />


 


  <Media Id=1 Cabinet=media1.cab EmbedCab=yes />


 


    <Property Id=STRINGPROP>


      <RegistrySearch Id=Search1


                      Root=HKLM


                      Key=SYSTEM\CurrentControlSet\services\wscsvc


                      Name=ObjectName


                      Type=raw


                      Win64=no/>


    </Property>


    <Property Id=DWORDPROP>


      <RegistrySearch Id=Search2


                      Root=HKLM


                      Key=SYSTEM\CurrentControlSet\services\wscsvc


                      Name=Start


                      Type=raw


                      Win64=no/>


    </Property>


    <Property Id=EXPANDSZPROP>


      <RegistrySearch Id=Search3


                      Root=HKLM


                      Key=SYSTEM\CurrentControlSet\services\wscsvc


                      Name=ImagePath


                      Type=raw


                      Win64=no/>


    </Property>


    <Property Id=BINARYPROP>


      <RegistrySearch Id=Search4


                      Root=HKLM


                      Key=SYSTEM\CurrentControlSet\services\wscsvc


                      Name=FailureActions


                      Type=raw


                      Win64=no/>


    </Property>


    <Property Id=MULTISZPROP>


      <RegistrySearch Id=Search5


                      Root=HKLM


                      Key=SYSTEM\CurrentControlSet\services\wscsvc


                      Name=DependOnService


                      Type=raw


                      Win64=no/>


    </Property>


 


    <SetProperty Id=STRINGPROPCONST After=AppSearch Value=QWERTY />


    <SetProperty Id=DWORDPROPCONST After=AppSearch Value=#2 />


    <SetProperty Id=EXPANDSZPROPCONST After=AppSearch Value=#%%SystemRoot%\System32\svchost.exe />


    <SetProperty Id=BINARYPROPCONST After=AppSearch Value=#x0123456789ABCDEF />


    <SetProperty Id=MULTISZPROPCONST After=AppSearch Value=a[~]b[~]c />


 


    <SetProperty Id=STRINGPROPRAW After=AppSearch Value=..[STRINGPROP] />


    <SetProperty Id=DWORDPROPRAW After=AppSearch Value=..[DWORDPROP] />


    <SetProperty Id=EXPANDSZPROPRAW After=AppSearch Value=..[EXPANDSZPROP] />


    <SetProperty Id=BINARYPROPRAW After=AppSearch Value=..[BINARYPROP] />


    <SetProperty Id=MULTISZPROPRAW After=AppSearch Value=..[MULTISZPROP] />


 


    <Directory Id=TARGETDIR Name=SourceDir>


      <Directory Id=LocalAppDataFolder>


        <Directory Id=INSTALLLOCATION Name=SetRegistry1>


          <Component Id=ProductComponent


                     Guid=f4ca4e76-d04a-4b89-9a1a-7a666a42a635>


            <CreateFolder />


            <RemoveFolder Id=RemoveMe On=uninstall />


            <RegistryKey Id=TestValue


                         Root=HKCU


                         Key=ACME Corp


                         Action=createAndRemoveOnUninstall>


 


              <RegistryValue Id=StringValueConst


                             Type=string


                             Action=write


                             Name=StringPropertyConst


                             Value=[STRINGPROPCONST] />


              <RegistryValue Id=DWordValueConst


                             Type=string


                             Action=write


                             Name=DWordPropertyConst


                             Value=[DWORDPROPCONST] />


              <RegistryValue Id=ExpandSzValueConst


                             Type=string


                             Action=write


                             Name=ExpandPropertyConst


                             Value=[EXPANDSZPROPCONST] />


              <RegistryValue Id=BinaryValueConst


                             Type=string


                             Action=write


                             Name=BinaryPropertyConst


                             Value=[BINARYPROPCONST] />


              <RegistryValue Id=MultiSzValueConst


                             Type=string


                             Action=write


                             Name=MultiSzPropertyConst


                             Value=[MULTISZPROPCONST] />


 


              <RegistryValue Id=StringValueRaw


                             Type=string


                             Action=write


                             Name=StringPropertyRaw


                             Value=[STRINGPROPRAW] />


              <RegistryValue Id=DWordValueRaw


                             Type=string


                             Action=write


                             Name=DWordPropertyRaw


                             Value=[DWORDPROPRAW] />


              <RegistryValue Id=ExpandSzValueRaw


                             Type=string


                             Action=write


                             Name=ExpandPropertyRaw


                             Value=[EXPANDSZPROPRAW] />


              <RegistryValue Id=BinaryValueRaw


                             Type=string


                             Action=write


                             Name=BinaryPropertyRaw


                             Value=[BINARYPROPRAW] />


              <RegistryValue Id=MultiSzValueRaw


                             Type=string


                             Action=write


                             Name=MultiSzPropertyRaw


                             Value=[MULTISZPROPRAW] />


 


              <RegistryValue Id=StringValue


                             Type=string


                             Action=write


                             Name=StringProperty


                             Value=[STRINGPROP] />


              <RegistryValue Id=DWordValue


                             Type=string


                             Action=write


                             Name=DWordProperty


                             Value=[DWORDPROP] />


              <RegistryValue Id=ExpandSzValue


                             Type=string


                             Action=write


                             Name=ExpandProperty


                             Value=[EXPANDSZPROP] />


              <RegistryValue Id=BinaryValue


                             Type=string


                             Action=write


                             Name=BinaryProperty


                             Value=[BINARYPROP] />


              <RegistryValue Id=MultiSzValue


                             Type=string


                             Action=write


                             Name=MultiSzProperty


                             Value=[MULTISZPROP] />


            </RegistryKey>


          </Component>


        </Directory>


      </Directory>


    </Directory>


 


    <Feature Id=ProductFeature Title=SetRegistry1 Level=1>


      <ComponentRef Id=ProductComponent />


    </Feature>


 


  </Product>


</Wix>



Итак, ответ на первоначальный вопрос – Да, если только мы не собираемся сохранять expandable строки.


 


Исходный код в attachement.

SetRegistry1.zip

Comments (0)