Search code examples
stringpropertieswixsubstitutiondtf

How to localize Error Messages for a Custom Action in wix and DTF?


I have written a custom action in DTF and would like to generate localized error messages for it. Until now, I have gone about this the following way: The custom action includes a method which displays a message that has been defined in the string table like this:

public static string getError(Session session, short errorNo)
    {
        Database db = session.Database;
        string errorMessage = (string)db.ExecuteScalar("SELECT `Message` FROM `Error` WHERE `Error` = {0}", errorNo);
        db.Close();
        return errorMessage;
    }

To make use of this error message, an Error element has to be created under the UI element like this:

<UI>
  <Error Id="42042">!(loc.Error42042)</Error>
</UI>

The actual error message can then be stored in the localization variable Error42042 like this:

<String Id="Error42042">My localized Error Message.</String>

This approach works quite well although it has one serious limitation: It won't replace properties in the strings. So the string

<String Id="Error42043">[MY_PROPERTY] is broken</String>

will be displayed verbatim as [MY_PROPERTY] is broken.

Am I required to extend my getError method to substitute properties manually (i.e. with the help of regular expressions or some other text substitution technique)?

Is there a predefined function in the wix source code I could use for property substitution?

Is this the wrong approach altogether?

I have seen strings in the form of

<String Id="Error2227">Param: [2]. Invalid param "[3]" in action: [4].</String>

in other installation packages. Being able to pass parameters to the String table like this would also be a feasible approach to tackle this problem, but I have not figured out how to pass parameters to the string table. Do you know how to do that?


Solution

  • Thanks to the comment by PhilDW I have found the DTF solution and it is amazingly simple. Using the Session.Format method, which is a DTF wrapper around MsiFormatRecord, one can simply replace properties in localized strings. Building on the example above, the getError method has to be extended into the following:

    public static string getError(Session session, short errorNo)
        {
            Database db = session.Database;
            string errorMessage = (string)db.ExecuteScalar("SELECT `Message` FROM `Error` WHERE `Error` = {0}", errorNo);
            db.Close();
            errorMessage = session.Format(errorMessage);
            return errorMessage;
        }
    

    Now, properties in the localized strings can be substituted by using the Formatted syntax like this:

    <String Id="Error42043">{[MY_PROPERTY]} is broken</String>