views:

312

answers:

2

When a single property contains semicolons, MSBuild automatically parse the property into a list of properties when used within an itemgroup. Here's a snippet from my project:

 <PropertyGroup>
   <ConnectionString>workstation id=.;packet size=4096;Integrated Security=SSPI;data source=.;initial catalog=$(SqlDbName)</ConnectionString>
 </PropertyGroup>

 <ItemGroup>
   <InstallShieldProperties Include="
       CONNECTIONSTRING=$(ConnectionString);
       Another=$(value)"/>
 </ItemGroup>

When a task consumes the @(InstallShieldProperties) itemgroup, MSBuild will parse the ConnectionString property into a list of subset properties since it contains semicolons.

    foreach (string property in Properties)
    {
      // Properties array parsed to pieces
    }

I know I can change the delimiter of the itemgroup, but that won't make any difference. I'm trying to avoid manipulating the string[] array within the custom task.

+3  A: 

AFAICS, you can either escape the semicolon in the $(ConnectionString) property like:

<ConnectionString>workstation id=.%3Bpacket size=4096%3B.."</ConnectionString>

Or use some task to replace the ';' in the ConnectionString property to '%3B' and then use that property in InstallShieldProperties item.

The other way could be to change the property type in the custom task from string[] to string, and then split it yourself, the way you want it. You could use enclosing quotes to separate Connection string part from other key/value pairs.

Or if it makes sense for your custom task, then maybe connection string is a special enough property to have as a separate task property.

Ankit
Thank you.The escape chars made it.
KMoraz
Really helpful answer. :) Thanks.
Vasiliy Borovyak
+2  A: 

In MSBuild 4.0, there are now Property Functions. One thing these allow you to do is call .NET String instance methods directly on your properties as if they are strings (which they are).

In your example, instead of using:

$(ConnectionString)

You could use:

$(ConnectionString.Replace(';', '%3B'))

Which will call the String method Replace() to replace semicolons with %3B

Lance Fisher