2015-02-13 3 views
0

Нам нужны наши MSI хранить пароль в реестре, так что пользователи могут использовать инсталлятор для изменения строки подключения и т.д.WiX CustomAction пожары в пользовательском интерфейсе, но не Execute Sequence

Мы нашли MsiExt для его криптографической DLL и пытаясь настроить пользовательские действия.

Наши пользователи должны будут иметь возможность устанавливать как через диалоговые окна пользовательского интерфейса, так и беззвучно - так что нам нужно выполнить их в обеих последовательностях.

Вот пример нашего Product.wxs

<Property Id="DB_PASSWORD" Secure="yes"/> 
    <Property Id="P.DB_PASSWORD"> 
     <RegistrySearch Id="S.DB_PASSWORD" Root="HKLM" Key="SOFTWARE\$(var.Manufacturer)\$(var.ProductName)" Name="DB_PASSWORD" Type="raw" Win64="$(var.Win64)"/> 
    </Property> 

    <Component Id="c.RegistryEntries" Guid="XXXXX-XXXXX-XXXXX-XXXXX" Directory="INSTALLDIR"> 
     <RegistryKey Root="HKLM" Key="SOFTWARE\$(var.Manufacturer)\$(var.ProductName)" Action="createAndRemoveOnUninstall"> 
     <RegistryValue Id="R.DB_PASSWORD" Name="DB_PASSWORD" Value="[ENCRYPTED_DBPASSWORD]" Type="string" /> 
     </RegistryKey> 
    </Component> 

    <!--For encrypting the database password on the way to the registry--> 
    <Binary Id="Cryptography" SourceFile="..\..\lib\msiext-1.4\CustomActions\Cryptography.dll"/> 

    <!--This property will receive the encrypted DB_PASSWORD that the user enters and will be encrypted--> 
    <Property Id="CRYPTPROTECT_DATA" Hidden="yes" /> 

    <Property Id="CRYPTPROTECT_FLAGS" Value="CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDDEN" /> 
    <CustomAction Id="EncryptPassword" BinaryKey="Cryptography" DllEntry="CryptProtectDataHex" Execute="immediate" /> 
    <CustomAction Id="SetDBUSERsPASSWORDForEncryption" Property="CRYPTPROTECT_DATA" Value="[DB_PASSWORD]" /> 
    <Property Id="ENCRYPTED_DBPASSWORD" Hidden="yes" /> 
    <SetProperty Id="ENCRYPTED_DBPASSWORD" Value="[CRYPTPROTECT_RESULT]" Sequence="execute" After="SetDBUSERsPASSWORDForEncryption" /> 

    <!--This is for decrypting the registry value--> 
    <Property Id="CRYPTUNPROTECT_DATA" Hidden="yes" /> 
    <Property Id="CRYPTUNPROTECT_FLAGS" Value="CRYPTPROTECT_LOCAL_MACHINE|CRYPTPROTECT_UI_FORBIDDEN" /> 
    <SetProperty Id="CRYPTUNPROTECT_DATA" Value="[P.DB_PASSWORD]" Before="DecryptPassword" >NOT(DB_PASSWORD)</SetProperty> 
    <CustomAction Id="DecryptPassword" BinaryKey="Cryptography" DllEntry="CryptUnprotectDataHex" Execute="firstSequence" /> 
    <CustomAction Id="SetDBUSERsDecryptedPASSWORD" Property="DB_PASSWORD" Value="[CRYPTUNPROTECT_RESULT]"/> 

    <CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" /> 
    <InstallUISequence> 
     <Custom Action="DecryptPassword" After="CostFinalize"><![CDATA[NOT(DB_PASSWORD)]]></Custom> 
     <Custom Action="SetDBUSERsDecryptedPASSWORD" After="DecryptPassword" ><![CDATA[NOT(DB_PASSWORD)]]></Custom> 
    </InstallUISequence> 
    <InstallExecuteSequence> 
     <Custom Action="SchedXmlConfig" After="InstallFiles"><![CDATA[(NOT REMOVE~="All")]]></Custom> 
     <Custom Action="SetDBUSERsPASSWORDForEncryption" Before="InstallInitialize" /> 
     <Custom Action="EncryptPassword" After="SetDBUSERsPASSWORDForEncryption" /> 

     <Custom Action="DecryptPassword" Before="InstallFiles"><![CDATA[CRYPTUNPROTECT_RESULT]]></Custom> 
     <Custom Action="SetDBUSERsDecryptedPASSWORD" After="DecryptPassword" ><![CDATA[CRYPTUNPROTECT_RESULT]]></Custom> 

    </InstallExecuteSequence> 

Установочный журнала показывает, что DecryptPassword стреляет во UISequence. Выполняется настраиваемое действие дешифрования, затем работает DecryptPassword.

Action ended 17:52:43: CostFinalize. Return value 1. 
MSI (c) (CC:A8) [17:52:43:936]: Doing action: SetCRYPTUNPROTECT_DATA 
Action 17:52:43: SetCRYPTUNPROTECT_DATA. 
Action start 17:52:43: SetCRYPTUNPROTECT_DATA. 
MSI (c) (CC:A8) [17:52:43:937]: PROPERTY CHANGE: Adding CRYPTUNPROTECT_DATA property. Its value is '**********'. 
Action ended 17:52:43: SetCRYPTUNPROTECT_DATA. Return value 1. 
MSI (c) (CC:A8) [17:52:43:937]: Doing action: DecryptPassword 
Action 17:52:43: DecryptPassword. 
Action start 17:52:43: DecryptPassword. 
MSI (c) (CC:7C) [17:52:49:129]: Invoking remote custom action. DLL: C:\Users\kujotx\AppData\Local\Temp\MSI9904.tmp, Entrypoint: CryptUnprotectDataHex 
MSI (c) (CC:54) [17:52:49:130]: Cloaking enabled. 
MSI (c) (CC:54) [17:52:49:130]: Attempting to enable all disabled privileges before calling Install on Server 
MSI (c) (CC:54) [17:52:49:130]: Connected to service for CA interface. 
CryptUnprotectDataHex: MSI Extensions 1.4.1114.0 
MSI (c) (CC!94) [17:52:49:236]: PROPERTY CHANGE: Adding CRYPTUNPROTECT_RESULT property. Its value is 'password'. 
Action ended 17:52:49: DecryptPassword. Return value 1. 
MSI (c) (CC:A8) [17:52:49:238]: Doing action: SetDBUSERsDecryptedPASSWORD 
Action 17:52:49: SetDBUSERsDecryptedPASSWORD. 
Action start 17:52:49: SetDBUSERsDecryptedPASSWORD. 
MSI (c) (CC:A8) [17:52:49:239]: PROPERTY CHANGE: Adding DB_PASSWORD property. Its value is '**********'. 
Action ended 17:52:49: SetDBUSERsDecryptedPASSWORD. Return value 1. 

Моя проблема заключается в том, что SetCRYPTUNPROTECT_DATA не выполняется во время ExecuteSequence, так DecryptPassword не удается:

Action ended 17:53:47: AppSearch. Return value 1. 
MSI (s) (28:1C) [17:53:47:206]: Doing action: DecryptPassword 
Action 17:53:47: DecryptPassword. 
Action start 17:53:47: DecryptPassword. 
MSI (s) (28:98) [17:53:47:217]: Invoking remote custom action. DLL: C:\Windows\Installer\MSI9020.tmp, Entrypoint: CryptUnprotectDataHex 
CryptUnprotectDataHex: MSI Extensions 1.4.1114.0 
CryptUnprotectDataHex: [CryptUnprotectDataHex] std::exception: 0x80070057 - Error in CryptUnprotectData: The parameter is incorrect. 
MSI (s) (28!DC) [17:53:47:237]: PROPERTY CHANGE: Adding CA_ERROR property. Its value is '0x80070057 - Error in CryptUnprotectData: The parameter is incorrect.'. 
CustomAction DecryptPassword returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) 
Action ended 17:53:47: DecryptPassword. Return value 3. 
Action ended 17:53:47: INSTALL. Return value 3. 

Вы можете указать, как планировать свои собственные действия, чтобы получить это расшифровать правильно?

ответ

1

Ваша проблема, скорее всего, из-за один из следующих действий:

  1. <SetProperty> элемента, который устанавливает CRYPTUNPROTECT_DATA имущества условно выполнения на основе значения DB_PASSWORD не установлены, но мы не можем видеть из журналов, что это свойство действительно не задано. Действие свойства не будет выполняться, если это значение равно false.

  2. Значение по умолчанию для атрибута Sequence на элементе <SetProperty> работает неправильно. Попробуйте установить атрибут Sequence на first, который запланирует его запуск в первом из InstallUISequence или InstallExecuteSequence (будет первым в бесшумном режиме). Если это не работает, попробуйте установить его в both явно.

  3. Попробуйте изменить атрибут настраиваемого действия Before для DecryptPassword в InstallExecuteSequence к After="InstallInitialize", что гораздо раньше в последовательности установки, чем InstallFiles. Это приведет к поведению, которое похоже на работу с пользовательской последовательностью, которая вычисляет и изменяет ваши свойства и выполняет ваши действия до того, как что-либо действительно будет установлено.

См this page для предложенной последовательности (и увидеть относительный порядок событий)

+0

Per 1. Я снял условие полностью. Для 2., сначала назначаю Sequence. Он снова не удался, поэтому я изменил его на оба. Для 3., я установил его после InstallInitialize и все еще не удалось. Опять же, UI Sequence показывает, что SetCRYPTUNPROTECT_DATA имеет событие ИЗМЕНЕНИЕ НЕДВИЖИМОСТИ. Но в Execute Sequence отображается SetCRYPTUNPROTECT_DATA, но нет события ИЗМЕНЕНИЯ НЕДВИЖИМОСТИ внутри. –

+0

Что такое инструмент, как Orca, как последовательность событий сценария при создании MSI? Это позволит вам взглянуть на сам MSI и посмотреть, как он преобразует определение в последовательность действий скрипта. Я думаю, что 'SetProperty' - это настраиваемый тип действия 51 ...Вы можете просмотреть его, чтобы увидеть, будет ли даже четный _scheduled_ запущен в это время. Исходя из вашего синтаксиса, не должно быть причин, по которым он не запускается, если в одном из ваших действий нет чего-то, что заставляет его работать неправильно. Кроме того, еще одна вещь, которую нужно попробовать, - добавить 'execute =" немедленный "на ваши ЦС. –

+0

Orca показывает, что SetProperty сразу предшествует DecryptPassword, который потребляет его во всех последовательностях - там хорошо. Журнал показывает, что SetProperty срабатывает, но не сообщает об изменении свойства. Имя свойства - P.DB_PASSWORD и помечается как безопасное, и я могу увидеть запись в журнале с зашифрованным значением после начала последовательности Execute. Я также вижу, что DecryptPassword работает дважды в ExecuteSequence - поэтому мне нужно условие, чтобы он не запускался во время RemoveExistingProducts. Внесите эти изменения, чтобы увидеть, насколько я близок. (спасибо, Райан!) –

Смежные вопросы