Пользовательские действия в WiX 3.8

У меня проблема с пользовательскими действиями в моем проекте. Некоторые работают, некоторые нет. У меня есть два проекта С# CustomAction Project и Setup Project в VS 2012. Мои пользовательские действия выглядят так. Два первых действия не вызывают проблемы. Не работает только третий.

[CustomAction]
public static ActionResult WriteToConfigStore(Session session)
{
    ...
}

[CustomAction]
public static ActionResult CleanConfigStore(Session session)
{
    ...
}

[CustomAction]
public static ActionResult CheckPrograms(Session session)
{
    string s = "";

    Process[] p = Process.GetProcesses();

    foreach (Process ps in p)
    {
        s += ps.ProcessName + ";";
    }

    MessageBox.Show(s);

    return ActionResult.Success;
}

Я определяю пользовательские действия следующим образом:

<Binary Id="CustomActionsId" SourceFile="$(var.ResourcesDir)\DriverCA.CA.dll" />
<CustomAction Id="ca_writeToConfigStoreId" BinaryKey="CustomActionsId" DllEntry="WriteToConfigStore" Execute="deferred" Return="check" />
<CustomAction Id="ca_cleanConfigStoreId" BinaryKey="CustomActionsId" DllEntry="CleanConfigStore" Execute="deferred" Return="check" />
<CustomAction Id="ca_setParameter" Return="check" Property="ca_writeToConfigStoreId" Value="param1=.;param2=;param3=;param4=;param5=IviDriver1.0, IviSwtch1.0" />
<CustomAction Id="ca_setCleanParameter" Return="check" Property="ca_cleanConfigStoreId" Value="param1=;" />
<CustomAction Id="ca_checkProgramsId" BinaryKey="CustomActionsId" DllEntry="CheckPrograms" Execute="deferred" Return="check" />

Моя последовательность установки выглядит так:

<InstallExecuteSequence>
  <Custom Action="ca_setParameter" Before="InstallFinalize" />
  <Custom Action="ca_setCleanParameter" Before="InstallFinalize" />
  <!--Call only when not uninstall (install, change, repair)--> 
  <Custom Action="ca_writeToConfigStoreId" After="ca_setParameter">NOT(REMOVE="ALL")</Custom>
  <!--Call only when uninstall or upgrade--> 
  <Custom Action="ca_cleanConfigStoreId" After="ca_setCleanParameter">REMOVE="ALL"</Custom>
  <!--Call only when not install--> 
  <Custom Action="ca_checkProgramsId" After="MsiUnpublishAssemblies">Installed</Custom>
</InstallExecuteSequence>

Когда я комментирую <Custom Action="ca_checkProgramsId" After="MsiUnpublishAssemblies">Installed</Custom>, все работает нормально. Но когда эта часть не закомментирована, то у меня при удалении программы вылетала ошибка There is problem with this Windows Installer package. A DLL required for this install to complete could not be run.. Я не вижу никакой ошибки. Каждое имя и идентификатор верны. Я не использую PInvoke или что-то в этом роде.

ОБНОВЛЕНИЕ: цель пользовательского действия — проверить, запущены ли какие-либо процессы, и в соответствии с этим прервать процесс удаления. Настройка выполняется для каждой системы, и у меня не было проблем с окнами сообщений в любых других настраиваемых действиях. Я решил это с другим проектом настраиваемого действия, в котором само по себе есть настраиваемое действие с проблемой, но в остальном я использую точно такие же методы и определения настройки (конечно, исключая другое определение dll). Все еще не знаю, в чем проблема.


person benderto    schedule 14.01.2015    source источник
comment
Это поможет понять, какова ваша конечная цель. Часто пользовательские действия не нужны.   -  person Christopher Painter    schedule 15.01.2015
comment
Мне нужно проверить, запущены ли некоторые процессы или нет, и в соответствии с этим прервать процесс удаления. Я обновил свой вопрос.   -  person benderto    schedule 15.01.2015


Ответы (2)


Несколько вещей, которые могут помочь:

Вам может потребоваться привилегия для перечисления процессов в системе - я не могу сказать, для какого пользователя (и, следовательно, без повышенных прав) или для каждой системы (и повышенного с помощью запроса на повышение).

Я не уверен, что вы можете сделать MessageBox.Show, если пользовательские действия повышены (и выполняются с системной учетной записью), потому что предоставление цикла сообщений Windows на рабочий стол является дырой в безопасности.

Как вы думаете, какая проблема решается после MsiPublishAssemblies? Мне непонятно, почему вы думаете, что это помогает. Я не думаю, что это связано с проблемой, если ваш код на самом деле не зависит от сборки в GAC, потому что он не будет установлен до InstallFinalize (что действительно важно, а не публикация сборок).

person PhilDW    schedule 14.01.2015
comment
MsiPublishAssemblies запускается на этапе фиксации, поэтому планирование «после» на самом деле, вероятно, будет «до», поскольку все отложенные операции выполняются до фиксации. - person Christopher Painter; 15.01.2015
comment
Настройка выполняется для каждой системы, и у меня не было проблем с окнами сообщений в любых других настраиваемых действиях. Я обновил свой вопрос. - person benderto; 15.01.2015
comment
Проблема по-прежнему в том, что это ваш код дает сбой, поэтому вам нужно отладить фактическую точку сбоя в коде, строку, которая дает сбой. Я бы все еще подозревал MessageBox из-за того, что я сказал, поэтому я бы не отмахивался от него так быстро. Если это для каждой системы, она поднимается? Если ваши вызовы MessageBox действительно работают, то самый простой способ обнаружить сбой — это вызвать MessageBox после каждой строки кода в этом методе и посмотреть, что произойдет. Кроме того, лично я бы НЕ использовал строку: я бы использовал StringBuilder. - person PhilDW; 15.01.2015
comment
Дело в том, что метод никогда не вызывается из установки. Установка просто не может его найти. И я знаю, что это там, я посмотрел. Я решил это, как я описал в конце вопроса, но я до сих пор не могу понять, почему он не работает с одной dll. - person benderto; 18.01.2015
comment
В исходном сообщении говорится, что вы получаете сообщение об ошибке, сообщающее о проблеме — Dll не может быть запущен. Таким образом, он вызывается или, по крайней мере, предпринимается попытка вызова. Это сообщение обычно не означает, что он не может его найти, потому что двоичный файл означает, что он находится в файле MSI. Либо он не может загрузиться (из-за отсутствия зависимостей), либо загружается и вылетает. - person PhilDW; 19.01.2015

Не настоящий ответ, но, надеюсь, больше, чем комментарий.

Отлаживать сложнее:

  1. Упростите свое CustomAction CheckPrograms, просто установив фиктивное свойство и вернув ActionResult.Success. Затем запустите msiexec с подробным ведением журнала, чтобы увидеть, достигли ли вы кода, устанавливающего свойство.
  2. Если 1) показывает настройку фиктивного свойства, добавьте либо а) отображение MessageBox со статической строкой, либо б) перечисление процессов (возможно, на следующем мини-шаге), помещая некоторую информацию об этих перечисленных процессах в фиктивное свойство, чтобы увидеть, получаете ли вы ожидаемые значения.
  3. Если 1) не показывает настройку фиктивного свойства, попробуйте интегрировать упрощенное CustomAction в другой момент (или что-нибудь еще, что вы придумаете).

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

Предоставьте дополнительную информацию:

  1. Вы упростили свой вопрос, чтобы проиллюстрировать проблему? Если да, эта упрощенная версия по-прежнему воспроизводит ошибку? (Например, очень важный момент: вы пропустили некоторые CustomActions?)
  2. В крайнем случае придумайте минималистичный пример, вызывающий ошибку, и сделайте его где-нибудь доступным. Может кто-то смотрит.
person Hille    schedule 28.01.2015
comment
Как я уже говорил в другом комментарии: Дело в том, что пользовательское действие никогда не вызывается из установки. Установка просто не может его найти. И я знаю, что это там, я посмотрел. Я решил это, как я описал в конце вопроса, но я до сих пор не могу понять, почему он не работает с одной dll. - Я попытался упростить это только до одного пользовательского действия. Это не сработало. Помогло создание нового проекта для пользовательских действий. - person benderto; 28.01.2015
comment
При написании я попытался упростить это только до того, что вы только исключили CA в конфигурации wix (т.е. удалили xml) или вы также удалили его из списка экспортируемых функций в DriverCA.CA.dll (например, удалив атрибут [CustomAction] )? Я спрашиваю из-за проблемы WiX 4502; для получения более подробной информации см. этот ответ SO. Если вы изначально пропустили некоторые из своих CA для простоты, а теперь решили проблему, переместив некоторый код в другую CA-dll, это может быть она. - person Hille; 28.01.2015
comment
Да, я удалил атрибут [CustomAction], а также весь этот метод. - person benderto; 28.01.2015