Пользовательское действие в C#, используемое через WiX, завершается с ошибкой 1154
Я использую WiX 3.5.1930 в Visual Studio 2010, ориентируясь на.NET Framework 3.5. (Более поздние еженедельные сборки WiX, похоже, сильно повреждены по отношению к их шаблону настраиваемых действий, по крайней мере, на данный момент. 1930 - это самая последняя сборка, которая, кажется, создает C# CA с рабочими ссылками.)
У меня есть две сборки пользовательских действий, написанные на C#. Один из них работает нормально. Другой сбой со следующей ошибкой:
CustomActionnNameHere returned actual error code 1154 (note this may not be 100% accurate if translation happened inside sandbox)
Я сравнил файлы.csproj и.wixproj, и, насколько я могу судить, различия уместны (например, список включенных файлов.cs). Я изменил нерабочие.wxs так, чтобы они вызывали рабочее настраиваемое действие вместо нерабочего настраиваемого действия, и оно работает как ожидалось.
Что еще я могу посмотреть, чтобы заставить это работать?
Редактирование: просто для завершения 1154 ссылается на недопустимую DLL - net helpmsg переводит ее (на английском языке) в "Один из файлов библиотеки, необходимый для запуска этого приложения, поврежден".
Второе редактирование: запустил peverify против dll (вытащил копию из \windows\installer во время работы установщика), и он говорит, что в dll все нормально. В DLL есть только метод настраиваемого действия с "возвращаемым успехом", поэтому проверить его не так уж и много, но он подтверждает, что DLL не повреждена.
Третье редактирование: следующий код в нарушенном настраиваемом действии:
using Microsoft.Deployment.WindowsInstaller;
namespace Framework.Installer.Database {
public class CustomActions {
[CustomAction]
public static ActionResult RunMigration(Session session) {
return ActionResult.Success;
}
}
}
Не так много для этого. Соответствующие части.wxs следующие:
<InstallExecuteSequence>
<Custom Action="DotNetMigratorCustomActionPreviousUp" After="SetMigrationPropertiesPreviousUp"><![CDATA[(&Database = 3)]]></Custom>
</InstallExecuteSequence>
<Binary Id="DotNetMigratorCustomActionDll"
SourceFile="$(var.Framework.Installer.Database.CustomActions.TargetDir)\SoftwareAnswers.Framework.Installer.Database.CustomActions.dll" />
<CustomAction Id="DotNetMigratorCustomActionPreviousUp"
Return="check"
BinaryKey="DotNetMigratorCustomActionDll"
DllEntry="RunMigration"
Execute="deferred" />
7 ответов
Похоже, вы используете DTF. Если ты видишь:
using Microsoft.Deployment.WindowsInstaller;
тогда вы, конечно, есть. Обязательно прочитайте следующее, чтобы узнать, как все это работает:
Управляемые пользовательские действия (DTF) Deployment Tools Foundation (DTF)
Также вы найдете DTF help chm в меню "Пуск" под WiX.
По сути, мне кажется, что вы подключаете сборку.NET к установщику, а не к неуправляемой оболочке dll. Прочитайте вышеупомянутую статью для обзора того, как смотреть на это в Зависит и знать, чего ожидать. WiX | Проект C# Custom Action должен выводить Foo.dll и Foo.CA.dll. Вы хотите позже в вашем установщике.
Для людей, которые попадут на эту страницу в будущем (ответ изначально был для автора), есть целый список вещей, которые нужно проверить:
- Вы ссылаетесь на правильную DLL в двоичной таблице?
- Вы ссылаетесь на правильное имя экспортируемой функции?
- Ваш класс публичный?
- Ваш метод использует правильную подпись? Т.е. это:
- Помечен правильным атрибутом CustomAction
- Помечено как общедоступное?
- Помечен как статический?
- Вернуть ActionResult?
- Принимать сессию в качестве аргумента?
- Убедитесь, что вы используете тип проекта настраиваемого действия WiX C#, чтобы событие postbuild вызывалось для создания собственной оболочки DLL. (См. № 1)
Любой из них может вызвать ошибку 1154. По этой причине я написал исчерпывающую статью в блоге на эту тему и дал ссылку на нее в этом ответе. Важно полностью понимать, как управляемый код представляется неуправляемой службе установщика Windows, и знать, как использовать метод Зависит от проверки того, что открытый статический метод экспортируется как функция stdcall в результирующий файл.CA.dll, создаваемый WiX/DTF.
Если вы создаете свое настраиваемое действие в Visual Studio (Votive), убедитесь, что вы создали проект Wix Custon Action, а не библиотеку классов, в противном случае вам придется использовать инструмент MakeSfxCA для упаковки своего настраиваемого действия.
Я только что нашел ту же проблему (используя правильный файл.CA.dll), и в моем случае это было потому, что я не использовал статический метод. У меня было это:
public ActionResult MyMethod(Session session)
Вместо этого:
public static ActionResult MyMethod(Session session)
После смены метода все заработало.
Надеюсь, это поможет кому-то.
Я натолкнулся на еще одну очень простую (и глупую) причину ошибки 1154: неправильное написание имени записи DLL в элементе CustomAction...
Сравнивая различные причины, которые обнаружили другие люди, мне кажется, что ошибка 1154 в большинстве случаев означает "запись DLL не найдена".
Мой ответ не имеет прямого отношения к этому вопросу. Но в моем случае я застрял с тем же кодом ошибки 1154, потому что я создал еще одну функцию в том же классе, но не пометил эту функцию как[CustomAction]
Мой код выглядел так
namespace VerifyUserInfo {
public class CustomActions {
[CustomAction]
public static ActionResult TryToLogin(Session session) {
return ActionResult.Success;
}
public static ActionResult RegisterDevice(Session session) {
return ActionResult.Success;
}
}
}
Но потом я исправил [CustomAction]
добавлен чуть выше новой функции и проблема решена
namespace VerifyUserInfo {
public class CustomActions {
[CustomAction]
public static ActionResult TryToLogin(Session session) {
return ActionResult.Success;
}
[CustomAction]
public static ActionResult RegisterDevice(Session session) {
return ActionResult.Success;
}
}
}
Другая причина, по которой я увидел эту ошибку, заключалась в том, что я забыл добавить атрибут [CustomAction] к имени моей функции C#.
В моем случае это была длина имени функции. Это было 27 символов, и мы получили ошибку. Мы изменили имя функции на 24 символа, и это сработало.
Попробуйте ввести свой вызов
<InstallExecuteSequence/>
в надежде получить лучшее сообщение об ошибке. Я получил разные сообщения об ошибках в зависимости от того, как было вызвано действие. Также попробуйте использовать fuslogvw.exe. Это может также дать вам довольно хорошее сообщение об ошибке.