Можно ли использовать данные, полученные при использовании 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)

Skip to main content