2014-10-06 5 views
0

У меня есть пользовательское действие с использованием CAQuietExec, который не работает в определенных сценариях - в файле журнала появляются сообщения об ошибках, которые отлично подходят для меня как разработчика и бесполезны для конечного пользователя. Моя цель - поймать неудавшееся действие и предварительно установить стандартное сообщение об ошибке до откат установки.Wix CustomAction dll

Для этого, основываясь на моих исследованиях, я решил, что мне нужно будет написать собственное собственное dll для действия, поэтому я начал следовать за this tutorial. На этом этапе моя dll регистрирует только тестовое сообщение и пытается передать сообщение об ошибке обратно в диалоговые окна. Однако, когда я компилирую и запускаю msi, ничего не происходит вообще - ничего не регистрируется и сообщений об ошибках нет. Глядя на msi в Orca, это выглядит хорошо для меня, но, как вы можете видеть ниже, тестовая dll должна приводить к тому, что установка прерывается немедленно, если она действительно выполняется, а это не так.

Итак, мой вопрос: я собираюсь предоставить обратную связь пользователю наилучшим образом? И если да, то какие-то идеи, почему мое пользовательское действие не запускается?

Благодарности

CustomAction.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Microsoft.Deployment.WindowsInstaller; 
using System.Collections.ObjectModel; 
using System.Management.Automation; 

namespace MyCustomActions 
{ 
public class CustomActions 
{ 
    [CustomAction] 
    public static ActionResult CustomAction1(Session session) 
    { 
     session.Log("Begin CustomAction1"); 

     DisplayMSIError(session, "A test message"); 

     return ActionResult.Failure; 
    } 

    static void DisplayMSIError(Session session, String msg) 
    { 
     var r = new Record(); 
     r.SetString(0, msg); 
     session.Message(InstallMessage.Error, r); 
    } 
} 
} 

Product.wxs

<?xml version="1.0" encoding="UTF-8"?> 
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> 
<Product Id="*" Name="MyPackage" Language="1033" Version="0.0.0.1" Manufacturer="Acme" UpgradeCode="GUID"> 
<Package InstallerVersion="300" Compressed="yes" InstallScope="perMachine" /> 

<Binary Id="MyCustomActions.CA.dll" src="MyCustomActions\MyCustomActions.CA.dll" /> 

<CustomAction Id="MyCustomActionsTest" 
    Return="check" 
    Execute="immediate" 
    BinaryKey="MyCustomActions.CA.dll" 
    DllEntry="CustomAction1" /> 

<InstallExecuteSequence> 
    <Custom Action="MyCustomActionsTest" After="LaunchConditions" /> 
    ... 
</InstallExecuteSequence> 
</Product> 
</Wix> 

ответ

0

Тьфу, я впустую часов на это: но для тех, кто с той же проблемой я отправьте ответ на мою проблему с пользовательским действием - надеюсь, это сэкономит вам время и разочарование.

Я положил свое тестовое действие очень рано в последовательности, думая, что тогда я увижу диалоговое окно с сообщением об ошибке. Поэтому я фактически не пытался пройти установку - когда появился приветственный диалог, я предположил, что мое действие не было выполнено. Однако он должен быть запущен, потому что, когда вы на самом деле выбираете функцию и разрешаете ее выполнять, появляется сообщение об ошибке.

Тем не менее, если кто-то может дать некоторое представление о том, является ли это наилучшим способом дать некоторые отзывы пользователей от действия, которое в противном случае работает нормально с CAQuietExec, было бы признательно.

+1

Я думаю, что, может быть, вам просто нужно немного больше понимания о том, как свалка работает. Одной из больших идей является тот, с которым вы столкнулись: сначала запускается InstallUISequence, а затем последовательность выполнения, поэтому ваш CA находится после стандартных диалоговых окон пользовательского интерфейса. И нет ничего плохого в session.message, чтобы сообщить пользователю об ошибке. – PhilDW

0

что вы думаете об этом решении:

 Record record = new Record(); 
     record.FormatString = string.Format("Something has gone wrong!"); 

     session.Message(
     InstallMessage.Error | (InstallMessage) (MessageBoxIcon.Error) | 
     (InstallMessage) MessageBoxButtons.OK, 
     record); 

из this answer

Другой способ - это создать свой собственный пользовательский интерфейс и показать любое сообщение, как вы хотите. Небольшой пример:

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

[CustomAction] 
    public static ActionResult CheckSqlSessionState(Session session) 
    { 
     try 
     { 
      session.SendMessage(InstallMessage.Info, "Check Sql Session State"); 

      return ActionResult.Success; 
     } 
     catch (Exception exception) 
     { 
      session.SendMessage(InstallMessage.Error, 
       string.Format("Error during the cheking sesssion state. {0}", exception.Message)); 
      return ActionResult.Failure; 
     } 
    } 

Регистрация:

<CustomAction Id="WiXSetup.CustomAction.CheckSqlSessionState" 
      BinaryKey="WiXSetup.CustomActions.dll" 
      DllEntry="CheckSqlSessionState" Execute="deferred" /> 

    <CustomAction Id="SetCheckSqlSessionStateDataValue" 
      Return="check" 
      Property="WiXSetup.CustomAction.CheckSqlSessionState" /> 

    <InstallExecuteSequence> 
     <Custom Action="SetCheckSqlSessionStateDataValue" Before="WiXSetup.CustomAction.CheckSqlSessionState">NOT Installed</Custom> 
     <Custom Action="WiXSetup.CustomAction.CheckSqlSessionState" After="WiXSetup.CustomAction.UpdateHomePageUrls">NOT Installed</Custom> 
    </InstallExecuteSequence> 

CSharp UI:

using Microsoft.Deployment.WindowsInstaller; 

    private ExternalUIRecordHandler recordHandler; 
    // ... 

    IntPtr parent = IntPtr.Zero; 

    recordHandler = RecordHandler; 

    private MessageResult RecordHandler(InstallMessage messageType, Record messageRecord, MessageButtons buttons, MessageIcon icon, MessageDefaultButton defaultButton) 
    { 
     switch (messageType) 
     { 
      case InstallMessage.Info: 
       log.Info(message); 
       return MessageResult.OK; 
      case InstallMessage.Initialize: 
       log.Debug(message); 
       return MessageResult.OK; 
      case InstallMessage.ActionData: 
       log.Debug(message); 
       return MessageResult.OK; 
      case InstallMessage.ActionStart: 
       log.Debug(message); 
       return MessageResult.OK; 
      case InstallMessage.CommonData: 
       return MessageResult.OK; 
      case InstallMessage.Error: 
       log.Error(message); 
       return MessageResult.OK; 
      case InstallMessage.FatalExit: 
       log.Fatal(message); 
       return MessageResult.OK; 
      case InstallMessage.FilesInUse: 
       return MessageResult.No; 
      case InstallMessage.OutOfDiskSpace: 
       break; 
      case InstallMessage.Progress: 
       return MessageResult.OK; 
      case InstallMessage.ResolveSource: 
       return MessageResult.No; 
      case InstallMessage.ShowDialog: 
       return MessageResult.OK; 
      case InstallMessage.Terminate: 
       return MessageResult.OK; 
      case InstallMessage.User: 
       return MessageResult.OK; 
      case InstallMessage.Warning: 
       log.Warn(message); 
       return MessageResult.OK; 
     } 

     return MessageResult.No; 
    } 
+0

Я полагаю, что моя забота - это то, что кажется, что полный избыток должен воссоздать действие как dll только потому, что я не могу понять, как дать хорошее сообщение об ошибке, если действие CAQuietExec не удалось. Поскольку моя установка в настоящее время стоит - если действие не выполняется, пользователь просто видит общее сообщение «что-то не так», предоставленное установщиком. Я полностью согласен с общим сообщением, но хочу указать свою собственную строку, потому что я могу дать пользователю лучшее представление о том, где проблема. –

Смежные вопросы