ОБНОВЛЕНИЕ : некоторые полезные ссылки.
Предполагаемые причины:
Здесь перечислены некоторые предложения вверху.
1
) Неправильная конфигурация кода настраиваемого действия C ++, часто забывая создать CA.def
файл для определения экспорта DLL.Я также всегда использую __stdcall
(MSI - старая девочка). 2
) Неправильный путь к пользовательским действиям dll вРазметка WiX (недопустимая DLL в MSI). 3)
Забыл включить проверку кодов ошибок в разметке WiX (* .WXS), после чего центр сертификации не завершает настройку.В вашем случае это выглядит правильно (Return='check')
. 4
) Забыл вставить пользовательское действие в последовательности установки. - Естьеще немного, не могу думать о них в данный момент.Можно добавить позже ... На ум приходят проблемы с битностью (x86 / 64) ...
- Файловые и временные зависимости - это классическая причина сбоя.
- Старайтесь статически связывать все, что можете.
- DLL-библиотеки развертывания должны быть минимальными зависимостями наверняка, так как они должны работать в любой системе, влюбой язык, в любом состоянии, в любой версии ОС и т. д. *
- Один из немногих случаев, когда статическое связывание действительно рекомендуется и всегда правильный выбор.
Heads-Up : избегать лицензирования при настройке?Я бы порекомендовал вам поставить проверку лицензии в вашем приложении вместо ваших настроек.Вот некоторые соображения по этому вопросу: Установщик с онлайн-регистрацией для приложения Windows ( рекомендуется прочитать ).
Технические проблемы:
FileName.def : Я не эксперт по C ++, но у вас есть файл FileName.def
в вашем проекте для объявления экспортированных функций дляDll?Если нет - добавьте один (шаги / процедура ниже).Убедитесь, что он в правильном формате (добавьте через Visual Studio, я думаю, что это UTF8 без спецификации).Скомпилируйте и проверьте с помощью Dependency Walker , если все операции экспорта верны:
Проверка DLL файла MSI : Вы должны проверить скомпилированный MSI, чтобы убедиться, что в нем есть правильная DLL-библиотека с правильным доступным экспортом.Следовательно,убедитесь, что DLL безопасно перешла в двоичную таблицу MSI:
- Откройте ваш скомпилированный MSI с Orca ( или эквивалентным ).
- Двоичная таблица , дважды щелкните по столбцу Данные для своей записи DLL.
- Выберите " Записать двоичный файл в имя файла "и сохраните на рабочем столе (или в другом месте).
- Используйте Зависимость Walker (зависимость.exe), чтобы убедиться, что у вас есть действительная DLL, как показанона изображении выше. Общая проблема заключается в том, что вы вообще не видите экспорта (
MyImmediateCA
, MyTestFail
, MyTestSuccess
, etc...
). - Проверьте файл - и версии продукта , а также в свойствах файла.
Обработка ошибок : можно настроить настраиваемое действие для подавления ошибок.Ваша разметка выглядит правильно с набором «атрибут возврата»: (Return='check')
.Ваш фрагмент:
<CustomAction Id='TestPassword' BinaryKey='TestPassword'
DllEntry='TestPassword' Execute='immediate' Return='check'/>
Секвенирование : Также убедитесь, что с секвенированием все в порядке.В целом вам нужно указать на DLL двоичной таблицы, объявить пользовательское действие, а затем также вставить его в правильную последовательность.Макет WiX разметки:
<!--<Binary Id="CustomActions" SourceFile="$(var.TestDll.TargetPath)" />-->
<Binary Id="CustomActions" SourceFile="C:\TestDll.dll" />
<CustomAction Id="MyTestFail" BinaryKey="CustomActions" DllEntry="MyTestFail"/>
<CustomAction Id="MyTestSuccess" BinaryKey="CustomActions" DllEntry="MyTestSuccess"/>
<InstallExecuteSequence>
<Custom Action="MyTestSuccess" After="CostFinalize" />
<Custom Action="MyTestFail" After="MyTestSuccess" />
</InstallExecuteSequence>
C ++ DLL : И собственно сама C ++ DLL (вспомните файл *.def
).Фрагмент в нижнем сегменте кода из Безопасность настраиваемых действий API MSI :
Предлагаемые действия для Visual Studio 2017 :
- Создание нового проекта VC + DLL - Dynamic-Link Library (DLL).
- Дамп кода ниже в основной файл
*.cpp
(я избегаю dllmain.cpp
). - Добавьте файл * .def!
Right Click Source Files
=> Add
=> New Item...
=> Code
=>Module-Definition File (.def)
=> Любое имя должно делать ... (разрешен только один файл def) - Добавить имена функций экспорта:
Макет:
LIBRARY
EXPORTS
MyTestFail
MyTestSuccess
MyImmediateCA
Закройте и снова откройте файл, чтобы проверить, есть ли какие-либо ошибки формата.Выберите исправление, если появится предупреждение. UTF8 без спецификации требуется, я думаю.
#include "stdafx.h"
#include <windows.h>
#include <Msiquery.h>
#pragma comment(lib, "msi.lib")
UINT __stdcall MyTestFail(MSIHANDLE hInstall)
{
MessageBox(NULL, L"MyTestFail", L"MyTestFail", MB_OK);
return ERROR_INSTALL_FAILURE;
}
UINT __stdcall MyTestSuccess(MSIHANDLE hInstall)
{
MessageBox(NULL, L"MyTestSuccess", L"MyTestSuccess", MB_OK);
return ERROR_SUCCESS;
}
// I will leave in the below snippet from the MSI API - section "Custom Action Security". Above two test methods will do though...
UINT __stdcall MyImmediateCA(MSIHANDLE hInstall)
{
MessageBox(NULL, L"Test", L"Test", MB_OK);
// set up information for deferred custom action called MyDeferredCA
const TCHAR szValue[] = TEXT("data");
UINT uiStat = ERROR_INSTALL_FAILURE;
if (ERROR_SUCCESS == MsiSetProperty(hInstall, TEXT("MyDeferredCA"), szValue))
{
uiStat = MsiDoAction(hInstall, TEXT("MyDeferredCA"));
// clear CustomActionData property
if (ERROR_SUCCESS != MsiSetProperty(hInstall, TEXT("MyDeferredCA"), TEXT("")))
return ERROR_INSTALL_FAILURE;
}
return (uiStat == ERROR_SUCCESS) ? uiStat : ERROR_INSTALL_FAILURE;
}
Минимальные зависимости : чтобы минимизировать зависимости, вы должны устранить визуальныеC / C ++ Зависимости времени выполнения и любые зависимости MFC (не используйте MFC, если вы можете помочь ему по размеру файла и соображениям производительности).Если вы используете MFC, установите для него статическое связывание - также для ATL.И, наконец, время выполнения C / C ++ см. Здесь: Удаление зависимостей MSVCR в Visual Studio 2010? (есть лучшие ссылки, но все, что я смог найти, на это у меня есть время - просто хочу получить это втам так не забыто).