Search code examples
wixcustom-action

CustomActionData with semi-colon separated, causes string overflow - What are the common workaround to this solution?


There were few attempts of questions answerered in regards to ICE03 (String overflow) for CustomActionData, but I cannot seem to determine/conclude the correct (or accepted) practice of how to go around this issue.

My current resolution was to reduce the length of the key-value-pair by keeping both the key and property names short, i.e. from:

<CustomAction Id="MyCustomActionData"
  Property="MyCustomActionCA"
  Value="myKeyName1=[SOME_PROPERTY_NAME];myKeyName2=[SOME_DESCRIPTIVE_PROPNAME]"/>

to:

<CustomAction Id="MyCustomActionData"
  Property="MyCustomActionCA"
  Value="k1=[K1];k2=[K2]"/>

But I feel that I'm just sweeping the problem under the rug and sooner or later, I'll encounter again (also, this is based on assumptions of my additional question below).

The more obvious solution is the re-evaluate and re-design it so that least amount of data needs to be passed down to the C# CustomAction (the classic "why would you want to declare a function method to pass 20 parameters?" question by all code-reviewers). Obviously, for most languages today, we can easily redesign the API and pass an object (as a class, struct, etc - depends on languages) that self-contains what it needs, but how does one go about it for inter-process calls (I've seen JSON RPC messages with reasonably large data and I'd usually wonder if it was because somebody tried to fix some legacy code by adding more and more until it got bloated rather than sitting down and re-design, which is not possible on some "11th hour" deadline that just has to get fixed in shortest time allowed).

Perhaps the solution is to create an XML file and use expat ('util:XmlFile') to search and replace the key-value-pair before calling CustomAction, and pass the filename of the altered XML as CustomActionData for CustomAction to use, which then in C# CustomAction code, it just deserializes it and treats it as objects. But that too feels a little klunky (it may also confuse the next developer who takes over my task in the future), not to mention if it was passwords we'd want to not have it in an XML file and keep it as Property with Hidden="yes"...

So my question is, what are the clean/elegant solutions or pattern (or practices) to resolve this issue of passing CustomActionData that may exceed table column size?

If I may also ask an additional question which is somewhat related, I am assuming that the linker (light) warning LGHT1076 is based on the length of the value (i.e. "keyA=[A];keyB=[B]") being too long, and so if I chose very short property variable and key-names, it would most likely not trigger this warning. But from what I understand, the table column size is 255 characters (please correct me if I'm wrong) thus during the run-time, if property value is longer than column size, it can cause some issue (or truncated)?


Solution

  • The solution I use is to create multiple properties and then concatenate the properties at the end into a single property, this way:

    <CustomAction Id="SetSqlProperties"
                  Property="SqlProperties"
                  Value="SQL_LOGIN_ID=[SQL_LOGIN_ID];SQL_PASSWORD=[SQL_PASSWORD];
                         SQL_AUTH_TYPE=[SQL_AUTH_TYPE];SQL_SERVERS=[SQL_SERVERS]" />
    <CustomAction Id="SetServerProperties"
                  Property="ServerProperties"
                  Value="Domain=[DOMAIN];ComputerName=[COMPUTER_NAME];
                         FullServerName=[FULLCOMPUTERNAME];Version=[ProductVersion];
                         ServerType=[SERVER_TYPE];SrvMode=[SrvMode]" />
    
    <CustomAction Id="SetPropertiesConfigReplace"
                  Property="ConfigReplace"
                  Value="InstallFolder=[INSTALLFOLDER];[ServerProperties];[SqlProperties]" />
    

    In this example I would use the property [ConfigReplace] containing all values from SQL Server and local server.

    About the ICE03, in the documentation you can find this:

    The string's length is greater than the column width specified by the column definition. Note that the installer does not internally limit the column width to the specified value. See Column Definition Format. MSDN