2014-10-06 88 views
0

我有一个使用CAQuietExec的自定义操作,在某些情况下失败 - 唯一的错误消息出现在日志文件中,这对开发人员来说是非常好的,对最终用户无用。我的目标是在回滚安装之前捕获失败的操作并预设标准错误消息。Wix CustomAction dll

要做到这一点,基于我的研究,我决定我需要编写自己的自定义动作DLL,所以我开始关注this tutorial。在这个阶段,我的dll只记录一条测试消息并尝试将错误消息传回对话屏幕。但是,当我编译并运行msi时,根本没有任何反应 - 没有记录,也没有任何错误消息。看看Orca中的msi,它对我来说看起来不错 - 但正如你可以在下面看到的那样,测试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在标准的UI对话框之后。 session.message没有错误告诉用户错误。 – PhilDW 2014-10-06 17:10:29

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

另一种方式 - 是创建自己的UI,当你想要显示的任何消息。 小例子:

自定义操作:

[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操作失败如何给出一个很好的错误消息。正如我目前的安装 - 如果操作失败,用户只能看到安装程序提供的通用“出错的信息”。我对通用消息完全没问题,但是我想指定我自己的字符串,因为我可以让用户更好地了解问题所在。 – 2014-10-06 20:03:47

相关问题