Search code examples
wixwindows-installercustom-action

How to debug an MSI Custom Action that is implemented in Javascript?


I'm having difficulty figuring out why my Javascript Custom action is failing.

I thought I saw a topic in the WIX.chm file on debugging; now I cannot find it.

Q1
is there doc on how to debug Javascript or VBScript custom actions?

Q2
Is there a way to emit something into the MSI log from a custom action?


Addendum:
Some people think script is the wrong tool for writing CAs.
I don't agree. I think Javascript is a very good tool for the job.


Solution

  • For the doc, look for Session.Message.

    To emit messages into the MSI log from a Javascript Custom Action, follow this boilerplate code:

    //
    // CustomActions.js 
    // 
    // Template for WIX Custom Actions written in Javascript.
    // 
    // 
    // Mon, 23 Nov 2009  10:54
    // 
    // ===================================================================
    
    
    // http://msdn.microsoft.com/en-us/library/sfw6660x(VS.85).aspx
    var Buttons = {
            OkOnly           : 0,
            OkCancel         : 1,
            AbortRetryIgnore : 2,
            YesNoCancel      : 3
    };
    
    var Icons = {
            Critical         : 16,
            Question         : 32,
            Exclamation      : 48,
            Information      : 64
    };
    
    var MsgKind = {
            Error            : 0x01000000,
            Warning          : 0x02000000,
            User             : 0x03000000,
            Log              : 0x04000000
    };
    
    // http://msdn.microsoft.com/en-us/library/aa371254(VS.85).aspx
    var MsiActionStatus = {
            None             : 0,
            Ok               : 1, // success
            Cancel           : 2,
            Abort            : 3,
            Retry            : 4, // aka suspend?
            Ignore           : 5  // skip remaining actions; this is not an error.
    };
    
    
    function MyCustomActionInJavascript() {
        try {
            LogMessage("Hello from MyCustomActionInJavascript");
            // ...do work here...
            LogMessage("Goodbye from MyCustomActionInJavascript");
        }
        catch (exc1) {
            Session.Property("CA_EXCEPTION") = exc1.message ;
            LogException(exc1);
            return MsiActionStatus.Abort;
        }
        return MsiActionStatus.Ok;
    }
    
    // Pop a message box.  also spool a message into the MSI log, if it is enabled. 
    function LogException(exc) {
        var record = Session.Installer.CreateRecord(0);
        record.StringData(0) = "CustomAction: Exception: 0x" + decimalToHexString(exc.number) + " : " + exc.message;
        Session.Message(MsgKind.Error + Icons.Critical + Buttons.btnOkOnly, record);
    }
    
    
    // spool an informational message into the MSI log, if it is enabled. 
    function LogMessage(msg) {
        var record = Session.Installer.CreateRecord(0);
        record.StringData(0) = "CustomAction:: " + msg;
        Session.Message(MsgKind.Log, record);
    }
    
    
    // popup a msgbox
    function AlertUser(msg) {
        var record = Session.Installer.CreateRecord(0);
        record.StringData(0) = msg;
        Session.Message(MsgKind.User + Icons.Information + Buttons.btnOkOnly, record);
    }
    
    // Format a number as hex.  Quantities over 7ffffff will be displayed properly.
    function decimalToHexString(number) {
        if (number < 0)
            number = 0xFFFFFFFF + number + 1;
        return number.toString(16).toUpperCase();
    }