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>
Вот некоторые ресурсы:
- Как передать CustomActionData в CustomAction с помощью WiX?
- https://www.firegiant.com/wix/tutorial/events-and-actions/at-a-later-stage/
- Как получить доступ к свойствам установщика из отложенных пользовательских действий
- Доступ к свойствам установщика Windows или их настройка с помощью пользовательских действий с отложенным выполнением, фиксацией и откатом
- Получение CustomActionData в отложенном настраиваемом действии
Просто для отладки. И вы можете использовать: 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
"когда я хочу устранить все другие источники ошибок.