Wix Custom Action - сеанс пуст и ошибка при отложенном действии

Я использую Wix 3.11.1 с расширением VS2017. Я устанавливаю свойство из элемента управления в настраиваемом диалоге, а затем пытаюсь выполнить немедленное настраиваемое действие. Когда я пытаюсь прочитать сессию, она всегда пуста.

В соответствии с рекомендациями я изменил свое действие на другое выполнение и использовал немедленное действие для установки моего свойства. Когда я запускаю мой установщик, я получаю сообщение об ошибке: "ОТЛАДКА: Ошибка 2896: не удалось выполнить действие [ActionName]".

В CustomDialog.wxs

<Control Id="ConnId" Type="Edit" X="60" Y="110"  Height="17" Width="300" Property="CONN"/>

<Control Id="installButton" Type="PushButton" Text="Continue" Height="15" Width="60" X="240" Y="260">
      <Publish Event="DoAction" Value="RegistrationInfoCustomAction">1</Publish>
      <Publish Event="EndDialog" Value="Return">1</Publish>
    </Control>

<Fragment>
<Binary Id="CustomActionBinary" SourceFile="..\..\CustomActions\bin\Debug\CustomActions.CA.dll"/>
<CustomAction Id="SetPropertyForShowProperty" Property="RegistrationInfoCustomAction" Execute="immediate" Value="[CONN]" Return="check" />
<CustomAction Id="RegistrationInfoCustomAction" BinaryKey="CustomActionBinary" DllEntry="SaveUserInfo" Execute="deferred" Return="check" HideTarget="no"/>
</Fragment>

В Product.wxs

<InstallExecuteSequence>
<Custom Action="SetPropertyForShowProperty" After="InstallInitialize"/>
<Custom Action="RegistrationInfoCustomAction" Before="InstallFinalize"/>
</InstallExecuteSequence>

В CustomActions.cs

[CustomAction]
    public static ActionResult SaveUserInfo(Session session)
    {
        Debugger.Launch();
        CustomActionData data = session.CustomActionData;

        session.Log("Begin SaveUserInfo");
        var connectionString = data["CONN"];
        session.Log($"content: {connectionString}");

        session.Log("End SaveUserInfo");
        return ActionResult.Success;
    }

Настраиваемое действие работает, когда оно содержит только операторы регистрации, но добавление любого другого кода приводит к сбою. Также сессия всегда пуста.

В журнале установщика:

MSI (c) (88:34) [16: 30: 21: 255]: запуск удаленного настраиваемого действия. DLL: C:\Users\Andre\AppData\Local\Temp\MSIF1A3.tmp, точка входа: SaveUserInfo

MSI (c) (88: F8) [16: 30: 21: 256]: маскировка включена.

MSI (c) (88: F8) [16: 30: 21: 256]: попытка включить все отключенные привилегии перед вызовом Install on Server

MSI (c) (88: F8) [16: 30: 21: 256]: подключен к службе для интерфейса CA.

Действие завершено 16:30:41: RegistrationInfoCustomAction. Возвращаемое значение 3.

ОТЛАДКА: Ошибка 2896: Не удалось выполнить действие RegistrationInfoCustomAction.

Установщик обнаружил непредвиденную ошибку при установке этого пакета. Это может указывать на проблему с этим пакетом. Код ошибки: 2896. Аргументы: RegistrationInfoCustomAction, Действие завершено 16:30:41: SetupDialog. Возвращаемое значение 3. MSI (c) (88:8C) [16:30:41:911]: выполнение действия: FatalError

1 ответ

Решение

ОБНОВЛЕНИЕ: уже поздно, я не видел этого с первого взгляда, но только пользовательские действия в непосредственном режиме можно запускать из графического интерфейса установки. Создайте новое настраиваемое действие немедленного режима, чтобы задать значение для вашего свойства PUBLIC CONN, а затем задайте значение CONN с помощью настраиваемого действия типа 51, которое будет назначено для идентификатора настраиваемого действия отложенного режима - как описано ниже.


SecureCustomProperties: добавьте указанное свойство в SecureCustomProperties, установив атрибут Secure="yes":

<Property Id="MYPROPERTY" Secure="yes">Send this text to deferred mode</Property>

Соответствие имени: имя свойства, которому вы назначаете значение, должно соответствовать идентификатору настраиваемого действия отложенного режима. Выглядит нормально в вашем источнике.

Более технический: the Property attribute's value из type 51 action должен быть идентичен идентификатору пользовательского действия, которое потребляет CustomActionData:

<!-- Declare property with value -->
<Property Id="MYPROPERTY" Secure="yes">Send this text to deferred mode</Property>

<!-- Type 51 CA: Send value of MYPROPERTY to the deferred mode CA named MyAction -->
<CustomAction Id="MyAction.SetProperty" Return="check" Property="MyAction" Value="[MYPROPERTY]" />

<!-- The deferred mode custom action -->
<CustomAction Id="MyAction" Return="check" Execute="deferred" BinaryKey="CAs" DllEntry="MyAction" />

<!-- ... -->

<!-- Inserting the CAs in sequence -->
<InstallExecuteSequence>
    <Custom Action="MyAction.SetProperty" After="InstallInitialize" />
    <Custom Action="MyAction" Before="InstallFinalize" />
</InstallExecuteSequence>

Вот некоторые ресурсы:


Просто для отладки. И вы можете использовать: string data = session["CustomActionData"];


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

VBScript "Simple.vbs" (сохранить как файл):

MsgBox Session.Property("CustomActionData")

Изменение разметки WiX:

<Binary Id='Simple.vbs' SourceFile='Simple.vbs' />
<CustomAction Id="MyAction" Return="check" Execute="deferred" BinaryKey="Simple.vbs" VBScriptCall='' />

На всякий случай так проще. Рекомендуем использовать VBScript только для отладки. Мне нравится VBScript, чтобы получить " heartbeat "когда я хочу устранить все другие источники ошибок.

Другие вопросы по тегам