Loren Halvorson's Blog

If your only tool is a hammer...

MSBuild trick for making <Exec> calls more maintainable

One of my pet peeves with MSBuild’s <Exec> task is how long the lines get when you have lots of arguments.

I ran across a trick yesterday in a blog comment made by someone named Romain and thought it was a very nice solution to this problem. When you expand items using this form @(items, ‘DELIMITER’), it allows you to specify a delimiter to use between the items. In the case of a command line, you use a space. Thanks Romain.

<ItemGroup>
  <XmlPreprocessArgs Include="/nologo"/>
  <XmlPreprocessArgs Include="/v"/>
  <XmlPreprocessArgs Include="/x:&quot;$(InstallDir)\Environments\$(ApplicationName).EnvironmentSettings.xml&quot;"/>
  <XmlPreprocessArgs Include="/i:&quot;$(InstallDir)\UI.Shell.exe.config%3B$(InstallDir)\ClientLogging.config&quot;"/>
  <XmlPreprocessArgs Include="/e:&quot;$(Environment)&quot;"/>
</ItemGroup>

<Exec Command="&quot;$(InstallDir)\Environments\XmlPreprocess.exe&quot; @(XmlPreprocessArgs,' ')"
      WorkingDirectory="$(InstallDir)\Environments" />

Posted: Dec 11 2008, 01:52 PM by lorenh | with 6 comment(s)
Filed under: ,

Comments

Sayed Ibrahim Hashimi said:

I would personally prefer using a property instead of an item. For example:

 <PropertyGroup>

   <XmlPreprocessArgs>/nologo</XmlPreprocessArgs>

   <XmlPreprocessArgs>$(XmlPreprocessArgs) /v</XmlPreprocessArgs>

   <XmlPreprocessArgs>$(XmlPreprocessArgs) /x:&quot;$(InstallDir)\Environments\$(ApplicationName).EnvironmentSettings.xml&quot;</XmlPreprocessArgs>

   <XmlPreprocessArgs>$(XmlPreprocessArgs) /i:&quot;$(InstallDir)\UI.Shell.exe.config%3B$(InstallDir)\ClientLogging.config&quot;</XmlPreprocessArgs>

   <XmlPreprocessArgs>$(XmlPreprocessArgs) /e:&quot;$(Environment)&quot;</XmlPreprocessArgs>

 </PropertyGroup>

<Target Name="Demo">

   <Exec Command="$(XmlPreprocessArgs)"/>

 </Target>

Sayed Ibrahim Hashimi

# December 12, 2008 1:32 PM

lorenh said:

Yes, I agree, a property is a good solution, and it's only slightly more verbose. The nice thing about MSBuild is that it's flexible enough to have choices.  Although in my opinion the NAnt syntax for exec still beats both solutions. NAnt has a nested <arg> element.

<exec program="XmlPreprocess.exe">

 <arg value="/nologo" />

 <arg value="/v" />

etc...

</exec>

I just had to post this because when I saw it, it made me smile to see the items with delimiter expansion used that way. I had never made that connection and thought it was very clever.

# December 12, 2008 1:46 PM

MSBuild trick for making <Exec> calls more maintainable | Tech Trend Watching said:

Pingback from  MSBuild trick for making &lt;Exec&gt; calls more maintainable | Tech Trend Watching

# December 12, 2008 9:35 PM

Jason Williams said:

You can make it more readable by avoiding use of &quot; in your commands. Enclose the attributes in single quotes instead of double quotes and then you can use double quotes safely inside them:

 <Exec Command= "&quot;my.exe&quot; param" />

becomes

 <Exec Command= ' "my.exe" param' />

# May 20, 2009 4:14 AM

todd said:

Thanks for the tip. I have a series of blogs on msbuild that might helpful. I also have a recipe that uses your technique for invoking soapui commandline testrunner.

Thanks

@Sayed Ibrahim Hashimi: agreed it is nicer as such but not idiomatic! (I struggle with staying with the idioms)

# January 19, 2010 8:28 PM

the tar pit : MsBuild execution of SoapUI testrunner said:

Pingback from  the tar pit : MsBuild execution of SoapUI testrunner

# January 19, 2010 8:36 PM