<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Il blog di Giulio Vian</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/giuliov/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/giuliov/feed.xml</link>
    <description>Notes and considerations of small consultant, lately on ALM</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:23:04 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>... and Thanks for All the Fish</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/and-thanks-for-all-the-fish</link>
      <pubDate>Fri, 27 Dec 2013 12:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2013/12/27/and-thanks-for-all-the-fish/</guid>
      <description><![CDATA[Goodbye all.
I am leaving Microsoft after 14 years: my last official day will be 27th of December....]]></description>
      <content:encoded><![CDATA[<p>Goodbye all.</p>
<p>I am leaving Microsoft after 14 years: my last official day will be 27th of December. I will continue to be part of ALM Rangers, and contribute to the community.</p>
<p>This blog moves to <a href="https://blog.casavian.eu/">https://blog.casavian.eu/</a>&nbsp;and you may contact me through <a href="https://it.linkedin.com/in/giuliovian">LinkedIn</a> or <a href="https://twitter.com/giulio_vian">Twitter</a>.</p>
<p>&nbsp;</p>
<p>A final note. Many loved my last e-mail, so here it is.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/1856.Last%20MS%20e-mail.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00/1856.Last-MS-e_2D00_mail.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/1856.Last%20MS%20e-mail.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00/1856.Last-MS-e_2D00_mail.png" alt="" border="0" /></a></p>
<p>Farewell and goodbye.</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Integrare XmlPreprocess nella build</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/integrare-xmlpreprocess-nella-build</link>
      <pubDate>Thu, 07 Feb 2013 10:15:00 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2013/02/07/integrare-xmlpreprocess-nella-build/</guid>
      <description><![CDATA[Questa breve nota descrive come integrare un tool quale XmlPreprocess nella build di Team Foundation...]]></description>
      <content:encoded><![CDATA[<p>Questa breve nota descrive come integrare un tool quale XmlPreprocess nella build di Team Foundation Server 2010 o 2012. L&rsquo;esempio in s&eacute; ha una sua utilit&agrave; spicciola &mdash; i file di configurazione nello share di Drop vengono predisposti per un ambiente target &mdash; ma illustra come, in generale, integrare il lancio di un tool eseguibile all&rsquo;interno del processo di build.</p>
<h3>Cos&rsquo;&egrave; XmlPreprocess</h3>
<p>Nelle parole dell&rsquo;autore &ldquo;<em>XmlPreprocess is a command-line utility that can modify annotated XML files much like a code preprocessor. It is useful for deploying configuration files to different environments making substitutions such as connection strings</em>&rdquo;. Si pu&ograve; scaricare, inclusi sorgenti e documentazione da <a href="https://xmlpreprocess.codeplex.com/">https://xmlpreprocess.codeplex.com/</a>.</p>
<p align="center"><img src="https://i3.codeplex.com/Download?ProjectName=xmlpreprocess&amp;DownloadId=48433" alt="" width="572" height="484" /></p>
<p align="center">&nbsp;</p>
<p align="center"><a name="_Ref347994616"></a>Figura 1 &ndash; Funzionamento di XmlPreprocess</p>
<p>Come si vede in Figura 1, il tool legge da un foglio Excel i valori di configurazione che sostituisce nel file che riceve in input.</p>
<p>In questo esempio utilizziamo il file Excel, ma il tool &egrave; in grado di usare altre fonti come, ad esempio, un database.</p>
<h3>Disegno della soluzione</h3>
<p>L&rsquo;esempio assume la presenza di due file essenziali: l&rsquo;eseguibile XmlPreprocess.exe e il file SettingsSpreadsheet.xml che contiene i valori da sostituire.</p>
<p>Il primo, l&rsquo;eseguibile, deve trovarsi nella stessa cartella del workflow di build (build process template).</p>
<p>Il secondo &egrave; opportuno venga conservato in una cartella speciale con ristretti permessi di sicurezza, in modo che possa accedervi solo il servizio di build e il personale che ha in gestione i sistemi e che ha quindi la responsabilit&agrave; delle configurazioni e delle password.</p>
<p>Il tool viene lanciato al termine della compilazione e dello unit test, quando tutti gli artefatti sono giunti nello share di Drop: in questo modo i file di configurazione ivi contenuti sono pronti per essere installati in un ambiente target senza ulteriori passaggi.</p>
<h3>Personalizzazione del workflow di build</h3>
<p>Il workflow personalizzato &egrave; un clone del Default template.</p>
<p>Abbiamo aggiunto due argomenti supplementari (v. Figura 2): il primo, <em>TargetEnvironment</em>, indica da quale ambiente, censito nel file Excel, prenderemo i valori per la sostituzione; il secondo, <em>SettingsSpreadsheetPath</em>, &egrave; il percorso completo del file Excel, espresso come version control path, ossia quelli che iniziano con <strong>$</strong>.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6012.GVTFS12_2013-02-07_00001_05762C39.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6012.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00001_5F00_05762C39.png"><img style="display: inline; background-image: none;" title="GVTFS12_2013-02-07_00001" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/0726.GVTFS12_2013-02-07_00001_thumb_7AF55818.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/0726.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00001_5F00_thumb_5F00_7AF55818.png" alt="GVTFS12_2013-02-07_00001" width="546" height="176" border="0" /></a>&nbsp; <br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/1768.GVTFS12_2013-02-07_00002_5DBF8A41.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/1768.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00002_5F00_5DBF8A41.png"><img style="display: inline; background-image: none;" title="GVTFS12_2013-02-07_00002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/8713.GVTFS12_2013-02-07_00002_thumb_6D7F1F45.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/8713.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00002_5F00_thumb_5F00_6D7F1F45.png" alt="GVTFS12_2013-02-07_00002" width="224" height="244" border="0" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/5670.GVTFS12_2013-02-07_00003_1157D0D3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/5670.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00003_5F00_1157D0D3.png"><img style="display: inline; background-image: none;" title="GVTFS12_2013-02-07_00003" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/3326.GVTFS12_2013-02-07_00003_thumb_0887C887.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/3326.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00003_5F00_thumb_5F00_0887C887.png" alt="GVTFS12_2013-02-07_00003" width="224" height="244" border="0" /></a></p>
<p align="center"><a name="_Ref347992220"></a><a name="_Ref347992223"></a>Figura 2 &ndash; Argomenti supplementari del workflow</p>
<p>&Egrave; stata aggiunta una sezione (<em>sequenceActivity</em>) nell&rsquo;ambito (<em>scope</em>) &ldquo;Run on Agent&rdquo; come ultimo passo, dopo che gli eseguibili sono stati prodotti nella cartella di Drop; la sezione si chiama &ldquo;*** Apply XmlPP&rdquo; (gli asterischi aiutano a identificare la personalizzazione.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/3513.XmlPreprocessWorkflow_0BD93A62.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/3513.XmlPreprocessWorkflow_5F00_0BD93A62.png"><img style="display: inline; background-image: none;" title="XmlPreprocessWorkflow" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/0755.XmlPreprocessWorkflow_thumb_47692355.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/0755.XmlPreprocessWorkflow_5F00_thumb_5F00_47692355.png" alt="XmlPreprocessWorkflow" width="560" height="365" border="0" /></a></p>
<p align="center">&nbsp;</p>
<p align="center">Figura 3 &ndash; Personalizzazione del workflow di build</p>
<p>La sequenza di azioni &egrave;:</p>
<ol>
<li>calcolo dove si trova l&rsquo;eseguibile di XmlPreprocess &mdash; la propriet&agrave; <em>ServerPath</em> ci fornisce il percorso, in termini di version control, del template di build che viene convertito in un percorso locale mediante <em>ConvertWorkspaceItem</em>; da questo si ricava la cartella contenente e quindi il percorso locale assoluto dell&rsquo;eseguibile</li>
<li>scarico dal version control il file Excel &mdash; con l&rsquo;activity DownloadFiles lo portiamo in locale nella stessa cartella dove si trova</li>
<li>cerco tutti i file .config</li>
<li>richiamo XmlPreprocess per ciascun file</li>
</ol>
<p>Il sorgente &egrave; riportato nel Listato 1.</p>
<table style="width: 402px; word-break: break-all;" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td style="word-break: break-all;" valign="top" width="400">
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Sequence</span> <span class="attr">DisplayName</span><span class="kwrd">="*** Apply XmlPP"</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Sequence.Variables</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Variable</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span> <span class="attr">Name</span><span class="kwrd">="localPathToXmlPP"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Variable</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="scg:IEnumerable(x:String)"</span> <span class="attr">Name</span><span class="kwrd">="configFiles"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Variable</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span> <span class="attr">Name</span><span class="kwrd">="localPathToSpreadsheet"</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Sequence.Variables</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">mtbwa:ConvertWorkspaceItem</span> <span class="attr">DisplayName</span><span class="kwrd">="Convert BuildTemplate path to local"</span> <span class="attr">Input</span><span class="kwrd">="[BuildDetail.BuildDefinition.Process.ServerPath]"</span> <span class="attr">Result</span><span class="kwrd">="[localBuildTemplatePath]"</span> <span class="attr">Workspace</span><span class="kwrd">="[Workspace]"</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Assign</span> <span class="attr">DisplayName</span><span class="kwrd">="Assign localPathToXmlPP"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">OutArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span><span class="kwrd">&gt;</span>[localPathToXmlPP]<span class="kwrd">&lt;/</span><span class="html">OutArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">InArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span> <span class="attr">xml:space</span><span class="kwrd">="preserve"</span><span class="kwrd">&gt;</span>[System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(localBuildTemplatePath),
"XmlPreprocess.exe")]<span class="kwrd">&lt;/</span><span class="html">InArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Assign</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Assign</span> <span class="attr">DisplayName</span><span class="kwrd">="Assign localPathToSpreadsheet"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">OutArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span><span class="kwrd">&gt;</span>[localPathToSpreadsheet]<span class="kwrd">&lt;/</span><span class="html">OutArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">InArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span> <span class="attr">xml:space</span><span class="kwrd">="preserve"</span><span class="kwrd">&gt;</span>[System.IO.Path.Combine(
  System.IO.Path.GetDirectoryName(localBuildTemplatePath),
  "SettingsSpreadsheet.xml")]<span class="kwrd">&lt;/</span><span class="html">InArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Assign</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">mtbwa:DownloadFiles</span> <span class="attr">DeletionId</span><span class="kwrd">="{x:Null}"</span> <span class="attr">DisplayName</span><span class="kwrd">="Download SettingsSpreadsheet.xml"</span> <span class="attr">LocalPath</span><span class="kwrd">="[localPathToSpreadsheet]"</span> <span class="attr">ServerPath</span><span class="kwrd">="[SettingsSpreadsheetPath]"</span> <span class="attr">mva:VisualBasic</span>.<span class="attr">Settings</span><span class="kwrd">="Assembly references and imported namespaces serialized as XML namespaces"</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">mtbwa:FindMatchingFiles</span> <span class="attr">DisplayName</span><span class="kwrd">="Find *.config Files"</span> <span class="attr">MatchPattern</span><span class="kwrd">="[String.Format(&amp;quot;{0}\**\*.config&amp;quot;, DropLocation)]"</span> <span class="attr">Result</span><span class="kwrd">="[configFiles]"</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">ParallelForEach</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span> <span class="attr">DisplayName</span><span class="kwrd">="Run XmlPP for Each .config"</span> <span class="attr">Values</span><span class="kwrd">="[configFiles]"</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">ActivityAction</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">ActivityAction.Argument</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">DelegateInArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span> <span class="attr">Name</span><span class="kwrd">="configFile"</span> <span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">ActivityAction.Argument</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">mtbwa:InvokeProcess</span> <span class="attr">Arguments</span><span class="kwrd">="[String.Format(&amp;quot;/input:{0} /spreadsheet:{1} /environment:{2}&amp;quot;, configFile, localPathToSpreadsheet, TargetEnvironment)]"</span> <span class="attr">DisplayName</span><span class="kwrd">="XmlPreprocess"</span> <span class="attr">FileName</span><span class="kwrd">="[localPathToXmlPP]"</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">mtbwa:InvokeProcess.ErrorDataReceived</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span><span class="html">ActivityAction</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">ActivityAction.Argument</span><span class="kwrd">&gt;</span>
              <span class="kwrd">&lt;</span><span class="html">DelegateInArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span> <span class="attr">Name</span><span class="kwrd">="errOutput"</span> <span class="kwrd">/&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">ActivityAction.Argument</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span><span class="html">ActivityAction</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">mtbwa:InvokeProcess.ErrorDataReceived</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">mtbwa:InvokeProcess.OutputDataReceived</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span><span class="html">ActivityAction</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span><span class="kwrd">&gt;</span>
            <span class="kwrd">&lt;</span><span class="html">ActivityAction.Argument</span><span class="kwrd">&gt;</span>
              <span class="kwrd">&lt;</span><span class="html">DelegateInArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span> <span class="attr">Name</span><span class="kwrd">="stdOutput"</span> <span class="kwrd">/&gt;</span>
            <span class="kwrd">&lt;/</span><span class="html">ActivityAction.Argument</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;/</span><span class="html">ActivityAction</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">mtbwa:InvokeProcess.OutputDataReceived</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">mtbwa:InvokeProcess</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">ActivityAction</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">ParallelForEach</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Sequence</span><span class="kwrd">&gt;</span></pre>
</td>
</tr>
</tbody>
</table>
<p align="center"><a name="_Ref347992879"></a>Listato 1 &ndash; XAML della personalizzazione</p>
<p>Per maggior sicurezza si pu&ograve; aggiungere un quinto passo per cancellare il file Excel dall&rsquo;area di lavoro della build.</p>
<p>Purtroppo non esiste una activity &lsquo;primitiva&rsquo; per la cancellazione, ma la soluzione &egrave; semplicissima.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/2806.GVTFS12_2013-02-07_00008_417E59EF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/2806.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00008_5F00_417E59EF.png"><img style="display: inline; background-image: none;" title="GVTFS12_2013-02-07_00008" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/5040.GVTFS12_2013-02-07_00008_thumb_71C52EA5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/5040.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00008_5F00_thumb_5F00_71C52EA5.png" alt="GVTFS12_2013-02-07_00008" width="182" height="244" border="0" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/1348.GVTFS12_2013-02-07_00007_4B16A258.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/1348.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00007_5F00_4B16A258.png"><img style="margin: 0px; display: inline; background-image: none;" title="GVTFS12_2013-02-07_00007" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/0830.GVTFS12_2013-02-07_00007_thumb_02E8E67C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/0830.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00007_5F00_thumb_5F00_02E8E67C.png" alt="GVTFS12_2013-02-07_00007" width="244" height="73" border="0" /></a></p>
<p align="center">Figura 4 &ndash; Aggiunta della cancellazione del file Excel</p>
<p>L&rsquo; azione &egrave; semplicemente:</p>
<blockquote>
<p>5. chiamo il metodo File.Delete per il file Excel</p>
</blockquote>
<p>Il sorgente &egrave; riportato nel Listato 2.</p>
<table style="width: 400px;" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="400">
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">InvokeMethod</span> <span class="attr">DisplayName</span><span class="kwrd">="Delete local Spreadsheet"</span> <span class="attr">MethodName</span><span class="kwrd">="Delete"</span> <span class="attr">TargetType</span><span class="kwrd">="si:File"</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">InArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">="x:String"</span><span class="kwrd">&gt;</span>[localPathToSpreadsheet]<span class="kwrd">&lt;/</span><span class="html">InArgument</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">InvokeMethod</span><span class="kwrd">&gt;</span></pre>
</td>
</tr>
</tbody>
</table>
<p align="center"><a name="_Ref347994234"></a>Listato 2 &ndash; XAML cancellazione finale</p>
<h3>Come deve esser fatta la definizione di una build</h3>
<p>La definizione per la build non &egrave; molto diversa dal quella di default.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/0456.GVTFS12_2013-02-07_00004_01A44D9D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/0456.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00004_5F00_01A44D9D.png"><img style="display: inline; background-image: none;" title="GVTFS12_2013-02-07_00004" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/4544.GVTFS12_2013-02-07_00004_thumb_77FBDF66.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/4544.GVTFS12_5F00_2013_2D00_02_2D00_07_5F00_00004_5F00_thumb_5F00_77FBDF66.png" alt="GVTFS12_2013-02-07_00004" width="556" height="284" border="0" /></a></p>
<p align="center"><a name="_Ref347994602"></a>Figura 5 &ndash; Definizione della build</p>
<p>I tre elementi da cambiare sono evidenziati in Figura 1: si sceglie il Build process template personalizzato e si inseriscono i valori desiderati per indicare il file Excel da usare per le sostituzioni e l&rsquo;ambiente destinatario.</p>
<p>&Egrave; importantissimo che il workspace comprenda la cartella con Build process template, come indicato in Figura 6.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/7356.GVTFS12_2013-01-31_00001_598178B0.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/7356.GVTFS12_5F00_2013_2D00_01_2D00_31_5F00_00001_5F00_598178B0.png"><img style="display: inline; background-image: none;" title="GVTFS12_2013-01-31_00001" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6685.GVTFS12_2013-01-31_00001_thumb_777F86A4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6685.GVTFS12_5F00_2013_2D00_01_2D00_31_5F00_00001_5F00_thumb_5F00_777F86A4.png" alt="GVTFS12_2013-01-31_00001" width="517" height="77" border="0" /></a></p>
<p align="center"><a name="_Ref347994935"></a>Figura 6 &ndash; Workspace che include il Build template</p>
<p>In caso contrario la build termina con un errore simile a questo</p>
<p><span style="font-family: Tahoma; font-size: xx-small;">1 error(s), 0 warning(s)</span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/4617.image_203AEBEE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/4617.image_5F00_203AEBEE.png"><span style="font-family: Tahoma; font-size: xx-small;"><img style="margin: 0px; display: inline; background-image: none;" title="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/3124.image_thumb_4C7772D2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/3124.image_5F00_thumb_5F00_4C7772D2.png" alt="image" width="20" height="20" border="0" /></span></a><span style="font-family: Tahoma; font-size: xx-small;">Exception Message: There is no working folder mapping for $/EsperimentiBuild/BuildProcessTemplates/XmlPreprocess/XmlPreprocessBuildProcessTemplate.xaml. (type ItemNotMappedException)Exception Stack Trace: at Microsoft.TeamFoundation.VersionControl.Client.Workspace.GetLocalItemForServerItem(String serverItem, Boolean detectImplicitCloak) at Microsoft.TeamFoundation.Build.Workflow.Activities.ConvertWorkspaceItem.Execute(CodeActivityContext context) at System.Activities.CodeActivity`1.InternalExecute(ActivityInstance instance, ActivityExecutor executor, BookmarkManager bookmarkManager) at System.Activities.Runtime.ActivityExecutor.ExecuteActivityWorkItem.ExecuteBody(ActivityExecutor executor, BookmarkManager bookmarkManager, Location resultLocation)</span></p>
<p>Una build che si conclude correttamente, avr&agrave; invece un log simile a quello in Figura 7.</p>
<p align="center"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/8836.GVTFS12_2013-02-06_00006_323709AE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/8836.GVTFS12_5F00_2013_2D00_02_2D00_06_5F00_00006_5F00_323709AE.png"><img style="display: inline; background-image: none;" title="GVTFS12_2013-02-06_00006" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/8306.GVTFS12_2013-02-06_00006_thumb_4E1818D9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/8306.GVTFS12_5F00_2013_2D00_02_2D00_06_5F00_00006_5F00_thumb_5F00_4E1818D9.png" alt="GVTFS12_2013-02-06_00006" width="549" height="444" border="0" /></a></p>
<p align="center"><a name="_Ref347994955"></a>Figura 7 &ndash; Build Log favorevole</p>
<p>In un log dettagliato potremo vedere una riga simile a questa</p>
<p><strong>X:\Builds\1\EsperimentiBuild\XmlPreprocess_Dev\src\BuildProcessTemplates\XmlPreprocess\XmlPreprocess.exe /input:\\gvtfs12\drops\XmlPreprocess_Dev\XmlPreprocess_Dev_20130131.6\ConsoleApplication1.exe.config /spreadsheet:X:\Builds\1\EsperimentiBuild\XmlPreprocess_Dev\src\BuildProcessTemplates\XmlPreprocess\SettingsSpreadsheet.xml /environment:Integration</strong></p>
<h3>Conclusioni</h3>
<p>L&rsquo;esempio pu&ograve; essere immediatamente usato al fine di predisporre i file di configurazione, che si trovano nello share di Drop, per uno specifico ambiente target. Con pi&ugrave; build definition preparo i pacchetti per ambienti differenti.</p>
<p>In generale, si son viste delle tecniche utili per integrare il lancio di un tool eseguibile all&rsquo;interno del processo di build: calcolo di dove si trova l&rsquo;eseguibile, messa in sicurezza di dati, individuazione di file da elaborare.</p>
<p>Il codice &egrave; applicabile sia a Team Foundation Server 2010 che 2012 che a Team Foundation Service.</p>]]></content:encoded>
    </item>
    <item>
      <title>Getting web services’ WSDL automatically during build</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/getting-web-services-wsdl-automatically-during-build</link>
      <pubDate>Thu, 13 Dec 2012 12:35:46 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2012/12/13/getting-web-services-wsdl-automatically-during-build/</guid>
      <description><![CDATA[A customer made me this request so I scratched my head to solve the issue. Let’s start with a bit of...]]></description>
      <content:encoded><![CDATA[<p>A customer made me this request so I scratched my head to solve the issue. Let’s start with a bit of context.</p>  <h4>Why WSDL?</h4>  <p>WSDL is the standard for describing a web service, it roots back to end of ‘90s; being a standard, it could be used to exchange contracts between teams. In .NET <a href="https://msdn.microsoft.com/en-us/library/aa347733.aspx">svcutil.exe</a> can be used to go both ways: generate WSDL from contract interfaces contained in an assembly or the proxy code from the WSDL.</p>  <p><em>But… </em>there are always exceptions: in .NET 4.0 you may expose a Windows Workflow (WF) as a WCF Service and the contract is dynamically generated. In such cases, when the contract is built on the fly, the WSDL can be obtained only querying the running service.</p>  <h4>IIS Express</h4>  <p>I opted to use <a href="https://www.microsoft.com/en-us/download/details.aspx?id=34679">this tool</a> as it is a good replica of IIS but you can avoid any kind of permanent registration and leave your build server clean. You can launch and configure it to host a web service from the command line (see <a title="https://www.iis.net/learn/extensions/using-iis-express/running-iis-express-from-the-command-line" href="https://www.iis.net/learn/extensions/using-iis-express/running-iis-express-from-the-command-line">https://www.iis.net/learn/extensions/using-iis-express/running-iis-express-from-the-command-line</a>). It has two modes of operation: the first mode is implies managing an applicationhost.config file, while the second mode requires only the path to the service’s folder. I opted for this latter with these options:</p>  <p><font face="Consolas">iisexpress /path:</font><em>path-to-the-service</em>&#160;<font face="Consolas">/port:</font><em>a-fixed-port-number-chose-by-the-build</em> <font face="Consolas">/clr:v4.0</font> <font face="Consolas">/systray:false</font></p>  <h4>Exporting the WSDL</h4>  <p>To export the WDSL, I implemented a couple of classes. The first class <em>IISExpress </em>is based on the ideas found <a href="https://stackoverflow.com/questions/4772092/starting-and-stopping-iis-express-programmatically">here</a>: using System.Diagnostics.Process class to launch IIS Express and using a Windows message to quit. The second class WsdlManager is the workhorse. It uses System.ServiceModel.Description.MetadataExchangeClient to get the <u>wsdl</u> from the service and it fix-up the URIs embedded in it so the cross-file references use relative URLs instead of absolute URLs. This way, the saved data will be correctly interpreted later.</p>  <h4>Wrapping the code in a task</h4>  <p>I put the two classes in an MSBuild task named <strong>ExportWSDL</strong> contained in <strong>AutoWSDL.dll</strong>. The main reason is to be able to run the code for each interesting project compiled during the build. But how can we identify the projects that contain a service? I looked up for 32f31d43-81cc-4c15-9de6-3fc5453562b6 (Workflow Foundation 4.0) or 3D9AD99F-2412-4246-B90B-4EAA41C64699 (Windows Communication Foundation) in the ProjectTypeGuids element for each project.</p>  <p>There is another issue: the task may receive a project or a solution: in this latter case we need to parse it. Annoyingly there is no documented way, but other people have already investigated for us (<a href="https://pascoal.net/2011/05/getting-visual-studio-version-of-a-solution-file/">here</a> and <a href="https://stackoverflow.com/questions/707107/library-for-parsing-visual-studio-solution-files">here</a>).</p>  <p>The body of the task follows.</p>  <pre class="csharpcode"><span class="kwrd">var</span> si = SolutionInfo.Parse(<span class="kwrd">this</span>.SolutionFileName);
<span class="kwrd">foreach</span> (var pi <span class="kwrd">in</span> si.Projects)
{
    <span class="kwrd">if</span> (pi.Types.Contains(ProjectTypes.WorkflowFoundation40)
        || pi.Types.Contains(ProjectTypes.WindowsCommunicationFoundation))
    {
        Log.LogMessage(MessageImportance.Low, <span class="str">&quot;Launching IIS Express for {0}&quot;</span>, pi.ProjectName);
        <span class="kwrd">using</span> (<span class="kwrd">var</span> iis = IISExpress.StartApplication(pi.ProjectRoot, <span class="kwrd">this</span>.Port, 4.0))
        {
            <span class="kwrd">var</span> wm = <span class="kwrd">new</span> WsdlManager(<span class="kwrd">this</span>.OutputFolder);
            <span class="kwrd">var</span> services = <span class="kwrd">new</span> List&lt;<span class="kwrd">string</span>&gt;();
            services.AddRange(pi.GetFilesOfInterest(<span class="str">&quot;.xamlx&quot;</span>));
            services.AddRange(pi.GetFilesOfInterest(<span class="str">&quot;.svc&quot;</span>));
            <span class="kwrd">foreach</span> (<span class="kwrd">var</span> service <span class="kwrd">in</span> services)
            {
                <span class="kwrd">string</span> wsdlUrl = <span class="kwrd">string</span>.Format(<span class="str">@&quot;https://localhost:{0}/{1}?wsdl&quot;</span>, <span class="kwrd">this</span>.Port, service);
                <span class="kwrd">var</span> serviceName = System.IO.Path.GetFileNameWithoutExtension(service);
                Log.LogMessage(MessageImportance.Low, <span class="str">&quot;Getting WSDL for {0}&quot;</span>, serviceName);
                wm.MaterializeWsdl(serviceName, <span class="kwrd">new</span> Uri(wsdlUrl));
            }<span class="rem">//for</span>
        }<span class="rem">//using</span>
    } <span class="kwrd">else</span> {
        Log.LogMessage(MessageImportance.Low, <span class="str">&quot;Project {0} is not a Web service&quot;</span>, pi.ProjectName);
    }<span class="rem">//if</span>
}<span class="rem">//for</span></pre>


<p>As you see, I adopted the simple heuristic that each Xamlx and Svc file exposes a web service.</p>

<p>This task takes three parameters</p>

<table cellspacing="0" cellpadding="2" width="400" border="1"><tbody>
    <tr>
      <td valign="top" width="100">Parameter</td>

      <td valign="top" width="300">Description</td>
    </tr>

    <tr>
      <td valign="top" width="100">SolutionFileName </td>

      <td valign="top" width="300">The full path to the solution file</td>
    </tr>

    <tr>
      <td valign="top" width="100">Port </td>

      <td valign="top" width="300">The TCP port number where IIS Express listen</td>
    </tr>

    <tr>
      <td valign="top" width="100">OutputFolder </td>

      <td valign="top" width="300">The folder where the WSDL files are written</td>
    </tr>
  </tbody></table>

<p>At this point we have an MSBuild task that given a project or solution file, analizes it and get the WSDL for each available service.</p>

<h4>Hooking the Visual Studio compile</h4>

<p>An elegant way to use this task is to extend the normal Visual Studio build process, in such a way that built the binaries we proceed to run them and get the WSDL metadata.</p>

<p>To trick to tie into the MSBuild architecture is the <font face="Consolas">CustomAfterMicrosoftCommonTargets</font> property: putting the path of an MSBuild file as its value, will trigger the parsing of such after the Microsoft.Common.targets which is at the core of all Visual Studio projects. In our case we use the PrepareForRunDependsOn target: at this point the DLLs are built and ready to execute.</p>

<p>Here is the content of the <strong>AutoWSDL.targets</strong> file to extend the VS build.</p>

<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Project</span> <span class="attr">xmlns</span><span class="kwrd">=&quot;https://schemas.microsoft.com/developer/msbuild/2003&quot;</span>
    <span class="attr">ToolsVersion</span><span class="kwrd">=&quot;4.0&quot;</span> <span class="kwrd">&gt;</span>
  <span class="rem">&lt;!-- hook end of compile --&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">PrepareForRunDependsOn</span><span class="kwrd">&gt;</span>$(PrepareForRunDependsOn);ExportWSDL<span class="kwrd">&lt;/</span><span class="html">PrepareForRunDependsOn</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">WsdlHostingPort</span> <span class="attr">Condition</span><span class="kwrd">=&quot;'$(WsdlHostingPort)'==''&quot;</span><span class="kwrd">&gt;</span>44444<span class="kwrd">&lt;/</span><span class="html">WsdlHostingPort</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">UsingTask</span> <span class="attr">TaskName</span><span class="kwrd">=&quot;ExportWSDL&quot;</span> <span class="attr">AssemblyFile</span><span class="kwrd">=&quot;AutoWSDL.dll&quot;</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Target</span> <span class="attr">Name</span><span class="kwrd">=&quot;ExportWSDL&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">WsdlOutputFolder</span><span class="kwrd">&gt;</span>$(OutDir)WSDL\$(MSBuildProjectName)\<span class="kwrd">&lt;/</span><span class="html">WsdlOutputFolder</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">MakeDir</span> <span class="attr">Condition</span><span class="kwrd">=&quot;!Exists($(WsdlOutputFolder))&quot;</span> <span class="attr">Directories</span><span class="kwrd">=&quot;$(WsdlOutputFolder)&quot;</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">ExportWSDL</span>
      <span class="attr">SolutionFileName</span><span class="kwrd">=&quot;$(MSBuildProjectFullPath)&quot;</span>
      <span class="attr">OutputFolder</span><span class="kwrd">=&quot;$(WsdlOutputFolder)&quot;</span>
      <span class="attr">Port</span><span class="kwrd">=&quot;$(WsdlHostingPort)&quot;</span>
      <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Target</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Project</span><span class="kwrd">&gt;</span></pre>


<p>If we put in the same folder the two files, AutoWSDL.targets and AutoWSDL.dll, we can test from a <em>Developer Command Prompt </em>by running:</p>

<p><font face="Consolas"><strong>MSBuild </strong></font>&lt;<em>path_to_a_WCF_project</em>&gt;<font face="Consolas"><strong>.csproj /p:CustomAfterMicrosoftCommonTargets=</strong></font>&lt;<em>path_to</em>&gt;<font face="Consolas"><strong>AutoWSDL.targets</strong></font></p>

<p>and find the exported WSDL files under the bin output folder.</p>

<p>Note that you may use this trick to extend in other ways the standard Visual Studio process.</p>

<h4>The complete solution</h4>

<p>The last logical step is to move from MSBuild to Team Foundation Server build, in order to have a single place for the WSDL contracts shared by the whole team. The nice part is to discover that all we have built before can be reused without changes.</p>

<p>The file <strong>AutoWSDLTemplate.xaml</strong> is a slightly modified version of the Default Template. It simply adds to the MSBuild Arguments the <font face="Consolas">CustomAfterMicrosoftCommonTargets</font> property.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/3808.image_6E629C8C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/3808.image_5F00_6E629C8C.png"><img title="image" style="margin: 0px; display: inline; background-image: none;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6116.image_thumb_340726AB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6116.image_5F00_thumb_5F00_340726AB.png" width="237" height="545" /></a>&#160;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6523.image_52716794.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6523.image_5F00_52716794.png"><img title="image" style="margin: 0px; display: inline; background-image: none;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/8838.image_thumb_7C7165BC.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/8838.image_5F00_thumb_5F00_7C7165BC.png" width="281" height="359" /></a></p>

<p>In XAML code</p>

<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">Sequence</span> <span class="attr">DisplayName</span><span class="kwrd">=&quot;*** Hook CustomAfterMicrosoftCommonTargets&quot;</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Sequence.Variables</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Variable</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span> <span class="attr">Name</span><span class="kwrd">=&quot;customAfterMicrosoftCommonTargets&quot;</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Variable</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span> <span class="attr">Name</span><span class="kwrd">=&quot;localBuildTemplatePath&quot;</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Sequence.Variables</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">sap:WorkflowViewStateService.ViewState</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">scg:Dictionary</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String, x:Object&quot;</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">x:Boolean</span> <span class="attr">x:Key</span><span class="kwrd">=&quot;IsExpanded&quot;</span><span class="kwrd">&gt;</span>True<span class="kwrd">&lt;/</span><span class="html">x:Boolean</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">scg:Dictionary</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">sap:WorkflowViewStateService.ViewState</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">mtbwa:ConvertWorkspaceItem</span> <span class="attr">Input</span><span class="kwrd">=&quot;[BuildDetail.BuildDefinition.Process.ServerPath]&quot;</span><br /><span class="attr">Result</span><span class="kwrd">=&quot;[localBuildTemplatePath]&quot;</span> <span class="attr">Workspace</span><span class="kwrd">=&quot;[Workspace]&quot;</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Assign</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">OutArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span><span class="kwrd">&gt;</span>[customAfterMicrosoftCommonTargets]<span class="kwrd">&lt;/</span><span class="html">OutArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">InArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span> <span class="attr">xml:space</span><span class="kwrd">=&quot;preserve&quot;</span><span class="kwrd">&gt;</span>[Path.Combine(
Path.GetDirectoryName(localBuildTemplatePath),
&quot;AutoWSDL.targets&quot;)]<span class="kwrd">&lt;/</span><span class="html">InArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Assign</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Assign</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">OutArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span><span class="kwrd">&gt;</span>[MSBuildArguments]<span class="kwrd">&lt;/</span><span class="html">OutArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">InArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span><span class="kwrd">&gt;</span>[String.Format(<br />&quot;{0} /p:CustomAfterMicrosoftCommonTargets={1} &quot;, MSBuildArguments,<br />customAfterMicrosoftCommonTargets)]<span class="kwrd">&lt;/</span><span class="html">InArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Assign</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Sequence</span><span class="kwrd">&gt;</span></pre>

<p>The first step is to get the Server path of the running build worklow, convert it to a local path using the <span class="html">ConvertWorkspaceItem</span> activity. Then assumes that the AutoWSDL.targets file resides in the same folder; finally adds the CustomAfterMicrosoftCommonTargets property to the list of MSBuild arguments.</p>

<p>This works as long as we have the three files in the same folder.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/2061.image_1B47D99B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/2061.image_5F00_1B47D99B.png"><img title="image" style="margin: 0px; display: inline; background-image: none;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6114.image_thumb_3A8A806E.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6114.image_5F00_thumb_5F00_3A8A806E.png" width="212" height="74" /></a></p>

<h4>Final words</h4>

<div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:443ee64f-5e08-4d16-92fa-2f73c12e0309" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline;"><p>I put a complete sample in <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/4201.AutoWSDL-Sample_5A53BA25.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/4201.AutoWSDL_2D00_Sample_5F00_5A53BA25.zip" target="_blank">this ZIP file</a></p></div>

<p>I think this is the kind of post that will tickle Mr. Fourie couriosity.</p>

<p><em>Giulio</em></p>]]></content:encoded>
    </item>
    <item>
      <title>Build incrementale e numeri di versione</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/build-incrementale-e-numeri-di-versione</link>
      <pubDate>Tue, 11 Dec 2012 09:40:44 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2012/12/11/build-incrementale-e-numeri-di-versione/</guid>
      <description><![CDATA[To my English followers: I will try to translate this post as I find the time to do it.  Temo di...]]></description>
      <content:encoded><![CDATA[<p><em>To my English followers: I will try to translate this post as I find the time to do it.</em></p>  <p>Temo di averlo ripetuto alla nausea: la build incrementale è una faccenda molto delicata ed è facile combinare pasticci se non si controlla costantemente. Perciò ne sconsiglio, in generale l’impiego. Recentemente ho messo però insieme una ricetta che limita alcuni degli inconvenienti associati ad essa ed è questo l’argomento del post.</p>  <p>In questo post mostrerò come preparare un template di build personalizzato che incrementi indipendentemente i numeri di versione dei singoli progetti Visual Studio e ci permetta però di rintracciare con facilità la team build che ha prodotto gli eseguibili, come illustrato in figura.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6560.2012-12-10_133228_4394C43F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6560.2012_2D00_12_2D00_10_5F00_133228_5F00_4394C43F.png"><img title="2012-12-10_133228" style="display: inline; background-image: none;" border="0" alt="2012-12-10_133228" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/7041.2012-12-10_133228_thumb_6192D233.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/7041.2012_2D00_12_2D00_10_5F00_133228_5F00_thumb_5F00_6192D233.png" width="355" height="484" /></a></p>  <h4>Estendere la build dei progetti</h4>  <p>Il primo tassello della soluzione è estendere la normale compilazione dei progetti Visual Studio (C#, VB o altro). Lavorare a livello MSBuild permette di conoscere se un determinato progetto è soggetto o meno a ricompilazione.</p>  <p>L’insieme dei file TARGETS che compone la compilazione .NET e Visual Studio prevede alcune utili proprietà, parzialmente documentate su <a title="https://msdn.microsoft.com/en-us/library/bb629394(v=vs.100).aspx" href="https://msdn.microsoft.com/en-us/library/bb629394(v=vs.100).aspx">Common MSBuild Project Properties</a>. Parzialmente perché quella che preferisco, e ci servirà, è <font face="Consolas">CustomAfterMicrosoftCommonTargets</font>. Impostando tale proprietà MSBuild al percorso di un file Targets, questo viene aggiunto dinamicamente e possiamo cambiare la definizione di target già definiti o di estenderne il comportamento. Bello e pericoloso!</p>  <p>Il secondo tassello è scegliere uno strumento per modificare i contenuti dei file AssemblyInfo. Poiché l’attività va condotta a livello MSBuild la scelta naturale è di utilizzare il task <a href="https://www.msbuildextensionpack.com/help/4.0.6.0/html/d6c3b5e8-00d4-c826-1a73-3cfe637f3827.htm">AssemblyInfo</a> da MSBuild Extension Pack (<a href="https://msbuildextensionpack.codeplex.com/">https://msbuildextensionpack.codeplex.com/</a>); il task è contenuto in MSBuild.ExtensionPack.dll che, a sua volta, richiede Ionic.Zip.dll. Questo task ha moltissimi argomenti, tanto che gli sviluppatori hanno fornito il file MSBuild.ExtensionPack.VersionNumber.targets pronto per l’impiego.</p>  <p>Se mettiamo in una stessa cartella questi tre file possiamo già provare il funzionamento di base digitando, da un <em>Developer Command Prompt</em>, qualcosa del tipo:</p>  <p><font face="Consolas"><strong>MSBuild </strong></font>&lt;<em>path ad un progetto</em>&gt;<font face="Consolas"><strong>.csproj /p:CustomAfterMicrosoftCommonTargets=</strong></font>&lt;<em>path_di</em>&gt;<font face="Consolas"><strong>MSBuild.ExtensionPack.VersionNumber.targets</strong></font></p>  <p>e vedere gli effetti di impostare valori diversi in MSBuild.ExtensionPack.VersionNumber.targets.</p> <strong></strong>  <table cellspacing="0" width="400" border="1"><tbody>     <tr>       <td valign="top" colspan="2" halign="center">         <p align="center">MSBuild.ExtensionPack.VersionNumber.targets</p>       </td>     </tr>      <tr>       <td valign="top" width="200">         <p align="center"><strong>Originale</strong></p>         <strong></strong></td>        <td valign="top" width="200"><strong></strong>          <p align="center"><strong>Modificato</strong></p>       </td>     </tr>      <tr>       <td valign="top" width="200">         <pre class="csharpcode"><font size="1"><span class="rem">&lt;!-- Properties for controlling the Assembly Version --&gt;</span>
<span class="kwrd">&lt;</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyMajorVersion</span><span class="kwrd">&gt;</span>1<span class="kwrd">&lt;/</span><span class="html">AssemblyMajorVersion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyMinorVersion</span><span class="kwrd">&gt;</span>0<span class="kwrd">&lt;/</span><span class="html">AssemblyMinorVersion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyBuildNumber</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyBuildNumber</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyRevision</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyRevision</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyBuildNumberType</span><span class="kwrd">&gt;</span>DateString<span class="kwrd">&lt;/</span><span class="html">AssemblyBuildNumberType</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyBuildNumberFormat</span><span class="kwrd">&gt;</span>MMdd<span class="kwrd">&lt;/</span><span class="html">AssemblyBuildNumberFormat</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyRevisionType</span><span class="kwrd">&gt;</span>AutoIncrement<span class="kwrd">&lt;/</span><span class="html">AssemblyRevisionType</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyRevisionFormat</span><span class="kwrd">&gt;</span>00<span class="kwrd">&lt;/</span><span class="html">AssemblyRevisionFormat</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span></font></pre>
        </td>

      <td valign="top" width="200">
        <pre class="csharpcode"><font size="1"><span class="rem">&lt;!-- Properties for controlling the Assembly Version --&gt;</span>
<span class="kwrd">&lt;</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyMajorVersion</span><span class="kwrd">&gt;</span>1<span class="kwrd">&lt;/</span><span class="html">AssemblyMajorVersion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyMinorVersion</span><span class="kwrd">&gt;</span>0<span class="kwrd">&lt;/</span><span class="html">AssemblyMinorVersion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyBuildNumber</span><span class="kwrd">&gt;</span>0<span class="kwrd">&lt;/</span><span class="html">AssemblyBuildNumber</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyRevision</span><span class="kwrd">&gt;</span>0<span class="kwrd">&lt;/</span><span class="html">AssemblyRevision</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span></font></pre>
        </td>
    </tr>

    <tr>
      <td valign="top" width="200"><font size="1" face="Consolas"></font>

        <pre class="csharpcode"><font size="1"><span class="rem">&lt;!-- Properties for controlling the Assembly File Version --&gt;</span>
<span class="kwrd">&lt;</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileMajorVersion</span><span class="kwrd">&gt;</span>1<span class="kwrd">&lt;/</span><span class="html">AssemblyFileMajorVersion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileMinorVersion</span><span class="kwrd">&gt;</span>0<span class="kwrd">&lt;/</span><span class="html">AssemblyFileMinorVersion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileBuildNumber</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyFileBuildNumber</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileRevision</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyFileRevision</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileBuildNumberType</span><span class="kwrd">&gt;</span>DateString<span class="kwrd">&lt;/</span><span class="html">AssemblyFileBuildNumberType</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileBuildNumberFormat</span><span class="kwrd">&gt;</span>MMdd<span class="kwrd">&lt;/</span><span class="html">AssemblyFileBuildNumberFormat</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileRevisionType</span><span class="kwrd">&gt;</span>AutoIncrement<span class="kwrd">&lt;/</span><span class="html">AssemblyFileRevisionType</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileRevisionFormat</span><span class="kwrd">&gt;</span>00<span class="kwrd">&lt;/</span><span class="html">AssemblyFileRevisionFormat</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span></font></pre>
        </td>

      <td valign="top" width="200">
        <pre class="csharpcode"><font size="1"><span class="rem">&lt;!-- Properties for controlling the Assembly File Version --&gt;</span>
<span class="kwrd">&lt;</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileMajorVersion</span><span class="kwrd">&gt;</span>1<span class="kwrd">&lt;/</span><span class="html">AssemblyFileMajorVersion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileMinorVersion</span><span class="kwrd">&gt;</span>0<span class="kwrd">&lt;/</span><span class="html">AssemblyFileMinorVersion</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileBuildNumber</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyFileBuildNumber</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileRevision</span><span class="kwrd">&gt;</span>0<span class="kwrd">&lt;/</span><span class="html">AssemblyFileRevision</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileBuildNumberType</span><span class="kwrd">&gt;</span><font style="background-color: rgb(255, 255, 0);">AutoIncrement</font><span class="kwrd">&lt;/</span><span class="html">AssemblyFileBuildNumberType</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyFileBuildNumberFormat</span><span class="kwrd">&gt;</span>000<span class="kwrd">&lt;/</span><span class="html">AssemblyFileBuildNumberFormat</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span></font></pre>
        </td>
    </tr>

    <tr>
      <td valign="top" width="200">
        <pre class="csharpcode"><font size="1"><span class="rem">&lt;!-- Propeties for controlling extended assembly attributes --&gt;</span>
<span class="kwrd">&lt;</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyCompany</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyCompany</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyConfiguration</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyConfiguration</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyCopyright</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyCopyright</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyCulture</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyCulture</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyDescription</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyDescription</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyProduct</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyProduct</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyTitle</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyTitle</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span></font></pre>
        </td>

      <td valign="top" width="200">
        <pre class="csharpcode"><font size="1"><span class="rem">&lt;!-- Propeties for controlling extended assembly attributes --&gt;</span>
<span class="kwrd">&lt;</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyCompany</span><span class="kwrd">&gt;</span>Fictious company<span class="kwrd">&lt;/</span><span class="html">AssemblyCompany</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyConfiguration</span><span class="kwrd">&gt;</span><font style="background-color: rgb(255, 255, 0);">$(ConfigurationName)</font><span class="kwrd">&lt;/</span><span class="html">AssemblyConfiguration</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyCopyright</span><span class="kwrd">&gt;</span>(c) Fictious company 2012<span class="kwrd">&lt;/</span><span class="html">AssemblyCopyright</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyCulture</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyCulture</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyDescription</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyDescription</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyProduct</span><span class="kwrd">&gt;</span>My product<span class="kwrd">&lt;/</span><span class="html">AssemblyProduct</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyTitle</span><span class="kwrd">&gt;&lt;/</span><span class="html">AssemblyTitle</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">AssemblyInformationalVersion</span><span class="kwrd">&gt;</span><font style="background-color: rgb(255, 255, 0);">$(TeamBuildNumber)</font><span class="kwrd">&lt;/</span><span class="html">AssemblyInformationalVersion</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">PropertyGroup</span><span class="kwrd">&gt;</span></font></pre>
        </td>
    </tr>
  </tbody></table>

<p>In breve la regola è di:</p>

<ul>
  <li>Non alterare l’AssemblyVersion</li>

  <li>Aggiornare l’AssemblyFileVersion con un numero progressivo rappresentante la build della singola componente</li>

  <li>Riportare nell’AssemblyInformationalVersion la proprietà $(TeamBuildNumber)</li>
</ul>

<p>In $(TeamBuildNumber) passeremo l’identificatore della team build che ha ricompilato il progetto. Per provare il meccanismo possiamo usare un comando come:</p>

<p><font face="Consolas"><strong>MSBuild </strong></font>&lt;<em>path ad un progetto</em>&gt;<font face="Consolas"><strong>.csproj /p:CustomAfterMicrosoftCommonTargets=</strong></font>&lt;<em>path_di</em>&gt;<font face="Consolas"><strong>MSBuild.ExtensionPack.VersionNumber.targets /p:TeamBuildNumber=</strong></font><em>pseudo-identificativo di build</em></p>

<h4>Un template di build</h4>

<p>Abbiamo visto a livello MSBuild come aggiornare automaticamente i file AssemblyInfo.cs (o .vb) dei progetti che vengono ricompilati senza modificare i file di progetto stessi (.csproj o .vbproj o simili); vediamo ora come inglobare queste modifiche in un template per la build di Team Foundation Server in modo che sia facilmente riutilizzabile.</p>

<p>L’intervento sul Default Template è minimo e non richiede custom activity ma è tutto a livello XAML, con il beneficio collaterale di non dover gestire il path degli assembly per le custom activities.</p>

<p>Anzitutto creiamo una cartella sotto BuildProcessTemplate del TeamProject e vi copiamo i tre file precedenti.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6567.GVTFS12_2012-12-11_00002---NO-TEMPLATE_346DBF98.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6567.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00002_2D002D002D00_NO_2D00_TEMPLATE_5F00_346DBF98.png"><img title="GVTFS12_2012-12-11_00002 - NO TEMPLATE" style="display: inline; background-image: none;" border="0" alt="GVTFS12_2012-12-11_00002 - NO TEMPLATE" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6052.GVTFS12_2012-12-11_00002---NO-TEMPLATE_thumb_7A7E7CAB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6052.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00002_2D002D002D00_NO_2D00_TEMPLATE_5F00_thumb_5F00_7A7E7CAB.png" width="595" height="108" /></a></p>

<p>Ricordiamo infatti che la cartella (e le sottocartelle) contenenti il template vengono scaricate automaticamente dall’agent di build.</p>

<p>Creiamo un clone del default template.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6052.GVTFS12_2012-12-11_00003_6E7C8C77.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6052.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00003_5F00_6E7C8C77.png"><img title="GVTFS12_2012-12-11_00003" style="display: inline; background-image: none;" border="0" alt="GVTFS12_2012-12-11_00003" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/7610.GVTFS12_2012-12-11_00003_thumb_4D1CE6DB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/7610.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00003_5F00_thumb_5F00_4D1CE6DB.png" width="796" height="213" /></a></p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/8105.GVTFS12_2012-12-11_00005_4FE29BCE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/8105.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00005_5F00_4FE29BCE.png"><img title="GVTFS12_2012-12-11_00005" style="display: inline; background-image: none;" border="0" alt="GVTFS12_2012-12-11_00005" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/2816.GVTFS12_2012-12-11_00005_thumb_0E67E975.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/2816.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00005_5F00_thumb_5F00_0E67E975.png" width="556" height="379" /></a></p>

<p>A questo punto abbiamo predisposto tutti i file che servono.</p>

<p>Aggiungiamo un parametro che l’utente inserirà nella <i>build definition</i>, come da figura.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/0257.GVTFS12_2012-12-10_00001_0CB71DA1.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/0257.GVTFS12_5F00_2012_2D00_12_2D00_10_5F00_00001_5F00_0CB71DA1.png"><img title="GVTFS12_2012-12-10_00001" style="margin: 0px; display: inline; background-image: none;" border="0" alt="GVTFS12_2012-12-10_00001" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/1643.GVTFS12_2012-12-10_00001_thumb_4A64055D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/1643.GVTFS12_5F00_2012_2D00_12_2D00_10_5F00_00001_5F00_thumb_5F00_4A64055D.png" width="717" height="313" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6014.GVTFS12_2012-12-10_00002_2B40E87D.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6014.GVTFS12_5F00_2012_2D00_12_2D00_10_5F00_00002_5F00_2B40E87D.png"><img title="GVTFS12_2012-12-10_00002" style="display: inline; background-image: none;" border="0" alt="GVTFS12_2012-12-10_00002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/8171.GVTFS12_2012-12-10_00002_thumb_5BF3F028.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/8171.GVTFS12_5F00_2012_2D00_12_2D00_10_5F00_00002_5F00_thumb_5F00_5BF3F028.png" width="477" height="413" /></a></p>

<p>Il parametro zzzVersionNumberTargetsFile indica il file Targets da usare: in questo modo possiamo usare diverse regole in build definition diverse.</p>

<p>La seguente figura illustra il punto del workflow da alterare.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/7585.2012-05-17_162944_135A0157.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/7585.2012_2D00_05_2D00_17_5F00_162944_5F00_135A0157.png"><img title="2012-05-17_162944" style="display: inline; background-image: none;" border="0" alt="2012-05-17_162944" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6014.2012-05-17_162944_thumb_601DC7ED.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6014.2012_2D00_05_2D00_17_5F00_162944_5F00_thumb_5F00_601DC7ED.png" width="243" height="561" /></a>&#160;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/2772.GVTFS12_2012-12-10_00003_49E7AC9B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/2772.GVTFS12_5F00_2012_2D00_12_2D00_10_5F00_00003_5F00_49E7AC9B.png"><img title="GVTFS12_2012-12-10_00003" style="display: inline; background-image: none;" border="0" alt="GVTFS12_2012-12-10_00003" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6082.GVTFS12_2012-12-10_00003_thumb_5D94962F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6082.GVTFS12_5F00_2012_2D00_12_2D00_10_5F00_00003_5F00_thumb_5F00_5D94962F.png" width="279" height="461" /></a></p>

<p>A livello di RunOnAgent aggiungiamo una Sequence che aggiunge dati alla variabile MSBuildArguments; il valore di questa è l’insieme di argomenti passati ad MSBuild al momento di compilare una solution od un project Visual Studio. Inoltre il file MSBuild.ExtensionPack.VersionNumber.targets viene cercato nella stessa cartella che contiene il template; la posizione della cartella viene determinata dalla activity ConvertWorkspaceItem.</p>

<p>Il codice XAML è abbastanza semplice da interpretare.</p>

<table cellspacing="0" cellpadding="2" width="602" border="1"><tbody>
    <tr>
      <td valign="top" width="600">
        <pre class="csharpcode"><font size="1"><span class="kwrd">&lt;</span><span class="html">Sequence</span> <span class="attr">DisplayName</span><span class="kwrd">=&quot;*** Hook CustomAfterMicrosoftCommonTargets&quot;</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Sequence.Variables</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Variable</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span> <span class="attr">Name</span><span class="kwrd">=&quot;customAfterMicrosoftCommonTargets&quot;</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Variable</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span> <span class="attr">Name</span><span class="kwrd">=&quot;localBuildTemplatePath&quot;</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Sequence.Variables</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">mtbwa:ConvertWorkspaceItem</span> <span class="attr">DisplayName</span><span class="kwrd">=&quot;Convert BuildTemplate path to local&quot;</span> <span class="attr">Input</span><span class="kwrd">=&quot;[BuildDetail.BuildDefinition.Process.ServerPath]&quot;</span> <span class="attr">Result</span><span class="kwrd">=&quot;[localBuildTemplatePath]&quot;</span> <span class="attr">Workspace</span><span class="kwrd">=&quot;[Workspace]&quot;</span> <span class="kwrd">/&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Assign</span> <span class="attr">DisplayName</span><span class="kwrd">=&quot;Assign customAfterMicrosoftCommonTargets&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">OutArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span><span class="kwrd">&gt;</span>[customAfterMicrosoftCommonTargets]<span class="kwrd">&lt;/</span><span class="html">OutArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">InArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span> <span class="attr">xml:space</span><span class="kwrd">=&quot;preserve&quot;</span><span class="kwrd">&gt;</span>[System.IO.Path.Combine(
System.IO.Path.GetDirectoryName(localBuildTemplatePath),
zzzVersionNumberTargetsFile)]<span class="kwrd">&lt;/</span><span class="html">InArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Assign</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Assign</span> <span class="attr">DisplayName</span><span class="kwrd">=&quot;Append CustomAfterMicrosoftCommonTargets to MSBuildArguments&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">OutArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span><span class="kwrd">&gt;</span>[MSBuildArguments]<span class="kwrd">&lt;/</span><span class="html">OutArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">InArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span><span class="kwrd">&gt;</span>[String.Format(&quot;{0} /p:CustomAfterMicrosoftCommonTargets={1} &quot;, MSBuildArguments, customAfterMicrosoftCommonTargets)]<span class="kwrd">&lt;/</span><span class="html">InArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Assign</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;</span><span class="html">Assign</span> <span class="attr">DisplayName</span><span class="kwrd">=&quot;Append TeamBuildNumber to MSBuildArguments&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">OutArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span><span class="kwrd">&gt;</span>[MSBuildArguments]<span class="kwrd">&lt;/</span><span class="html">OutArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.To</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">InArgument</span> <span class="attr">x:TypeArguments</span><span class="kwrd">=&quot;x:String&quot;</span><span class="kwrd">&gt;</span>[String.Format(&quot;{0} /p:TeamBuildNumber={1} &quot;, MSBuildArguments, BuildDetail.BuildNumber)]<span class="kwrd">&lt;/</span><span class="html">InArgument</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">Assign.Value</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">Assign</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">Sequence</span><span class="kwrd">&gt;</span></font> 
        </pre>
        </td>
    </tr>
  </tbody></table>

<p>La proprietà MSBuild TeamBuildNumber viene valorizzata con BuildDetail.BuildNumber, ossia l’identificativo della build in corso, come abbiamo visto in precedenza. </p>

<p>Salvando tutto nel version control siamo pronti a definire dei profili di build basati su questo template personalizzato.</p>

<h4>Definiamo le build</h4>

<p>A questo punto creare una nuova build definition richiede solo un paio di accortezze.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/7178.GVTFS12_2012-12-11_00001_754BCD95.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/7178.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00001_5F00_754BCD95.png"><img title="GVTFS12_2012-12-11_00001" style="display: inline; background-image: none;" border="0" alt="GVTFS12_2012-12-11_00001" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/3750.GVTFS12_2012-12-11_00001_thumb_3364E847.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/3750.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00001_5F00_thumb_5F00_3364E847.png" width="730" height="669" /></a></p>

<p>Come spiegato in <a href="https://msdn.microsoft.com/en-us/library/dd647547.aspx#parameters_basic">Define a Build Process that is Based on the Default Template</a>, le build incrementali si basano sul valore del parametro <em>Clean Workspace</em>. Nel nostro esempio lo poniamo a <b>None</b>, cosicché solamente i file aggiornati nel version control sono portati nell’area di build e quindi solo i progetti strettamente necessari vengono ricompilati. La ricompilazione aggancia automaticamente la modifica del file AssemblyInfo.CS (o .VB). È possibile che la build non trovi necessario ricompilare alcun progetto e di conseguenza i binari prodotti siano identici a quelli della precedente build.</p>

<p>Dobbiamo inoltre valorizzare il parametro <em>Targets File for Version Numbering</em> con il nome del file MSBuild.ExtensionPack.VersionNumber.targets da usare. La scelta di rendere parametrico (e obbligatorio) il nome del file con le regole di incremento della versione ci permette di usare regole differenti per build definition diverse. Ad esempio un build definition che rilascia hotfix incrementerà il numero <i>revision</i> invece del <i>build</i>.</p>

<h4>Finale</h4>

<p>Un comodo ritocco al nostro template custom è di porre a None il valore di default per <em>Clean Workspace</em>, così da non doverlo cambiare ad ogni nuova definizione.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/2043.GVTFS12_2012-12-11_00006_184C1939.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/2043.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00006_5F00_184C1939.png"><img title="GVTFS12_2012-12-11_00006" style="display: inline; background-image: none;" border="0" alt="GVTFS12_2012-12-11_00006" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/0841.GVTFS12_2012-12-11_00006_thumb_0DBB1F4C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/0841.GVTFS12_5F00_2012_2D00_12_2D00_11_5F00_00006_5F00_thumb_5F00_0DBB1F4C.png" width="733" height="528" /></a></p>

<p>Inoltre possiamo accorgerci se è stato modificato rispetto il nuovo default.</p>

<p>&#160;</p>

<p>Se dobbiamo verificare rapidamente i numeri di versione di molti file si può usare il seguente comando PowerShell</p>

<pre class="csharpcode">Get-ChildItem \\<em><font face="Segoe UI">path_to_build_outputs</font></em>\*.dll | <span class="kwrd">foreach</span> { $_.VersionInfo }</pre>


<p>&#160;</p>

<p>Infine il </p>

<div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:573674b1-4048-4303-b45a-b49e172a5301" class="wlWriterEditableSmartContent" style="margin: 0px; padding: 0px; float: none; display: inline;"><p> <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/1031.IncrementalVersionBuildProcess_0753FD24.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/1031.IncrementalVersionBuildProcess_5F00_0753FD24.zip" target="_blank">file ZIP</a></p></div>&#160;&#160;&#160;&#160; contiene tutto il sorgente dell’esempio descritto nel post. 

<p>Salute a tutti e alla prossima,</p>

<p><em>Giulio</em></p>]]></content:encoded>
    </item>
    <item>
      <title>Automatically execute Coded UI test on different Lab VMs</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/automatically-execute-coded-ui-test-on-different-lab-vms</link>
      <pubDate>Mon, 01 Aug 2011 07:47:31 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2011/08/01/automatically-execute-coded-ui-test-on-different-lab-vms/</guid>
      <description><![CDATA[Imagine this scenario: you are working in setting up the Lab Management features of TFS 2010. The...]]></description>
      <content:encoded><![CDATA[<p>Imagine this scenario: you are working in setting up the Lab Management features of TFS 2010. The main purpose is to execute automated tests. The customer asked to have a lab environment able to test different clients OS, namely Windows XP and Windows 7, each equipped with a number of browsers.</p>  <p>Sure, you could have multiple environments each with a single but different client, but this will require much more resources; the environment has already three servers: domain controller, SQL Server and a Web server. Two environments needs 2*(3+1)=8 VMs, while collapsing in one you have 3+2=5 VMs.</p>  <p>You are using the end-to-end workflow, i.e. <font size="2" face="Consolas">LabDefaultTemplate.xaml</font>, to deploy the application and test it. The template wizard has two combo boxes: one for Test Configuration and one for the Test Settings.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/0871.2011-05-31_134520_no_arrows_0F9DB999.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/0871.2011_2D00_05_2D00_31_5F00_134520_5F00_no_5F00_arrows_5F00_0F9DB999.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-05-31_134520_no_arrows" border="0" alt="2011-05-31_134520_no_arrows" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/2626.2011-05-31_134520_no_arrows_thumb_0FDA3CCE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/2626.2011_2D00_05_2D00_31_5F00_134520_5F00_no_5F00_arrows_5F00_thumb_5F00_0FDA3CCE.png" width="626" height="484" /></a></p>  <p>So you define a test setting, using the proposed defaults.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/0486.2011-05-30_140104_696833B5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/0486.2011_2D00_05_2D00_30_5F00_140104_5F00_696833B5.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-05-30_140104" border="0" alt="2011-05-30_140104" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6170.2011-05-30_140104_thumb_01E7AB39.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6170.2011_2D00_05_2D00_30_5F00_140104_5F00_thumb_5F00_01E7AB39.png" width="458" height="484" /></a></p>  <p>But then you realize that both client VMs are in the Web Client role: tests will be distributed among them!</p>  <p>The solution is to:</p>  <ul>   <li>using different roles for the two clients </li>    <li>create different Test Configurations for each client role </li> </ul>  <p>As you see below the role are editable</p>  <p>&#160;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/2860.2011-05-31_133811_46A3A9A0.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/2860.2011_2D00_05_2D00_31_5F00_133811_5F00_46A3A9A0.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="2011-05-31_133811" border="0" alt="2011-05-31_133811" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/0486.2011-05-31_133811_thumb_4F536652.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/0486.2011_2D00_05_2D00_31_5F00_133811_5F00_thumb_5F00_4F536652.png" width="526" height="484" /></a></p>  <p>In my case I gave distinct names to the client VMs, say “Web Client XP” and “Web Client 7”; then defined two Test Settings: in each setting, I selected a distinct VM where to run the test (see below picture).</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/7840.clip_image001_764DD9FA.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/7840.clip_5F00_image001_5F00_764DD9FA.jpg"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image001" border="0" alt="clip_image001" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/2477.clip_image001_thumb_43BA56BB.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/2477.clip_5F00_image001_5F00_thumb_5F00_43BA56BB.jpg" width="244" height="224" /></a></p>  <p>Finally, I define two builds based on the E2E template, each pointing to the proper (automated) test settings, and linked to the matching Test Configuration (see below).</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6170.clip_image002_48BC946A.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/6170.clip_5F00_image002_5F00_48BC946A.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image002" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/1805.clip_image002_thumb_5F2F32F1.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/1805.clip_5F00_image002_5F00_thumb_5F00_5F2F32F1.jpg" width="244" height="189" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/7268.clip_image003_0B6BB9D6.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/7268.clip_5F00_image003_5F00_0B6BB9D6.jpg"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="clip_image003" border="0" alt="clip_image003" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/5618.clip_image003_thumb_08E28818.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-41-00-metablogapi/5618.clip_5F00_image003_5F00_thumb_5F00_08E28818.jpg" width="244" height="190" /></a></p>  <p>So far so good, but having two build definitions is a bit inelegant. Later I found this blog post <a href="https://blogs.msdn.com/b/lab_management/archive/2011/05/26/configuration-matrix-testing-using-visual-studio-lab-management.aspx">https://blogs.msdn.com/b/lab_management/archive/2011/05/26/configuration-matrix-testing-using-visual-studio-lab-management.aspx</a>, that suggest how to add a second test run with different settings to the E2E workflow.</p>  <p>Happy building!</p>]]></content:encoded>
    </item>
    <item>
      <title>Build Guidance is out</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/build-guidance-is-out</link>
      <pubDate>Sat, 18 Jun 2011 09:47:10 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2011/06/18/build-guidance-is-out/</guid>
      <description><![CDATA[&#160;  The Rangers Build Customization Guide is public on Codeplex and I am happy this is over… for...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>The <a href="https://rabcg.codeplex.com/">Rangers Build Customization Guide</a> is public on Codeplex and I am happy this is over… for while. Willy and Bijan are very demanding on ALM Rangers and already started on new projects and team.</p>  <p>I do not like repeating, so get the details from <a href="https://blogs.msdn.com/b/willy-peter_schaub/archive/2011/06/18/we-have-shipped-visual-studio-build-customization-guidance.aspx">Willy’s blog</a>.</p>  <p>If you don’t like it, have suggestions on the existing content, or think that we should invest in some untouched scenario, just <a href="https://rabcg.codeplex.com/discussions">shout</a>: this is just the first edition.</p>  <p>Remember also: this work is done by volunteers on their extra time, so be patient and constructive on your comments.</p>]]></content:encoded>
    </item>
    <item>
      <title>Migrating to TFS 2010 from multiple TFS 200x servers</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/migrating-to-tfs-2010-from-multiple-tfs-200x-servers</link>
      <pubDate>Sat, 18 Jun 2011 09:21:52 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2011/06/18/migrating-to-tfs-2010-from-multiple-tfs-200x-servers/</guid>
      <description><![CDATA[&#160;  The other day a question came from a colleague, that sounded like this.  My client has been...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>The other day a question came from a colleague, that sounded like this.</p>  <p>My client has been using TFS for many years now and has a production deployment consisting of about 4 TFS 2008 servers containing about 50, 50, 25 &amp; 25 team projects respectively.</p>  <p>Now they are in the process of migrating to TFS 2010 and <font style="background-color: #ffff00"><font style="background-color: #ffffff">they want to understand the options: t</font></font>heir eventual goal is to move all the team projects to one very large TFS 2010 instance. </p>  <p>This is my response, as it could be useful to others.</p>  <p>In your customer scenario you have to choose between:</p>  <ul>   <li>A full-fidelity migration, mapping each TFS instance to a separate collection, or </li>    <li>A loose data migration, moving data around. </li> </ul>  <p>In the first case, you use the upgrade wizard for the first server, then repeat the process using <a href="https://msdn.microsoft.com/en-us/library/ff407080.aspx">tfsconfig import</a>.</p>  <p>In the latter case, you use the <a href="https://tfsintegration.codeplex.com/">Tfs Integration Platform</a>. Don’t be distracted by finding it on Codeplex: there is also a <a href="https://visualstudiogallery.msdn.microsoft.com/f854dd59-8eeb-4673-8d9a-ae012989bfa2">supported version in the VS Gallery</a> and is routinely used internally at Microsoft.</p>  <p>In my opinion, you should ask the customer what they really want to achieve and when. Here some possible approaches to the problem:</p>  <ul>   <li><strong>Piecemeal</strong>: you create a new instance of TFS 2010 and move a team (create an new Team Project and check-in the code) at their ease leaving history on the old server       <br /><em>Pros</em>: easy to implement; zero downtime       <br /><em>Cons</em>: slow and need more resources </li>    <li><strong>One</strong> Team Project Collection for all: use integration tools       <br /><em>Pros</em>: simplified view and management; less resources       <br /><em>Cons</em>: they lose some history; more work to implement </li>    <li><strong>Multiple</strong> Team Project Collections, one from each old server, <strong>plus</strong> a “consolidated wharehouse” Team Project Collection: an hybrid solution that uses the out-of-the-box upgrade/import feature, with the integration tool you consolidate the data in a new Team Project Collection for reporting and other consolidated views       <br /><em>Pros</em>: full-fidelity       <br /><em>Cons</em>: need more resources, e.g. one Controller per Team Project Collection </li> </ul>  <p>You can also think of a mix of these strategies, selecting the best approach for different teams.</p>]]></content:encoded>
    </item>
    <item>
      <title>BizTalk 2009 and TFS 2010</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/biztalk-2009-and-tfs-2010</link>
      <pubDate>Tue, 05 Oct 2010 23:45:48 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2010/10/05/biztalk-2009-and-tfs-2010/</guid>
      <description><![CDATA[&#160;  A very welcome news, today. The BizTalk team released to public an hotfix to let BizTalk...]]></description>
      <content:encoded><![CDATA[<p>&#160;</p>  <p>A very welcome news, today. The BizTalk team released to public an hotfix to let BizTalk projects (.btproj) to compile successfully under TeamBuild 2010 (<a title="https://support.microsoft.com/kb/2406405" href="https://support.microsoft.com/kb/2406405">https://support.microsoft.com/kb/2406405</a>).</p>  <p>I discovered the issues myself and worked with the team to find some workaround. I am already using this fix in our project and I have been able to remove my own hacks.</p>  <p>You can find more details on <a href="https://blogs.msdn.com/b/bharry/archive/2010/10/04/biztalk-2009-and-tfs-2010.aspx">bharry's blog</a>.</p>  <p><strong>Beware</strong>: this patch allows Team Foundation Server 2010 to build BizTalk 2009 projects. For developing you still need to use Visual Studio 2008 SP1 plus the <a href="https://www.microsoft.com/downloads/en/details.aspx?FamilyID=8406ef19-35a3-4c03-a145-08ba982f3cef">Update for Microsoft Visual Studio 2010 Lab Management</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>SettingsMerger on CodePlex</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/settingsmerger-on-codeplex</link>
      <pubDate>Fri, 01 Oct 2010 10:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2010/10/01/settingsmerger-on-codeplex/</guid>
      <description><![CDATA[Yesterday, I published Sprinkler on CodePlex and today I completed my efforts with another tool:...]]></description>
      <content:encoded><![CDATA[<p>Yesterday, I published <a href="https://sprinkler.codeplex.com/">Sprinkler</a> on CodePlex and today I completed my efforts with another tool: <a href="https://settingsmerger.codeplex.com/">SettingsMerger</a>.</p>
<p>This tool takes a number of Excel files, in the format required by <a href="https://xmlpreprocess.codeplex.com/">XmlPreprocess</a> / <a href="https://envsettingsmanager.codeplex.com/">EnvironmentSettingsExporter</a>, and outputs a single Excel file in the same format by removing duplicates, stopping in case of clashes, etc. <br /> </p>
<p>The idea is to leave each BizTalk application independent, with all the BTDF stuff, but also handle a single Excel file to operation; this also avoid contemption of having a single settings file for all application up front.</p>
<p>The resulting file will have a column for each distinct environment name and a row for each distinct setting. Here you have an example of two input files.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/8726.image11_56A5C57F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-41-00-metablogapi/8726.image11_5F00_56A5C57F.png"><img width="613" height="123" title="image11" style="display: inline; border: 0px;" alt="image11" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/6761.image11_thumb_5F461E0B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-41-00-metablogapi/6761.image11_5F00_thumb_5F00_5F461E0B.png" border="0" /></a></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/1376.image15_6B679832.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-41-00-metablogapi/1376.image15_5F00_6B679832.png"><img width="613" height="134" title="image15" style="display: inline; border: 0px;" alt="image15" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/1882.image15_thumb_1084E29F.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-41-00-metablogapi/1882.image15_5F00_thumb_5F00_1084E29F.png" border="0" /></a></p>
<p>The result of the merge has 6 rows and 5 columns (not counting the one with settings&rsquo; names).</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/1563.image14_40CBB755.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-41-00-metablogapi/1563.image14_5F00_40CBB755.png"><img width="613" height="162" title="image14" style="display: inline; border: 0px;" alt="image14" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/41/00/metablogapi/3036.image14_thumb_0CB71802.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-41-00-metablogapi/3036.image14_5F00_thumb_5F00_0CB71802.png" border="0" /></a></p>
<p>Feedback is more than welcome, and apologize for bugs and lack of documentation.</p>
<p><strong>UPDATE</strong>: This tool has been merged in <a href="https://envsettingsmanager.codeplex.com/">EnvironmentSettingsExporter</a>: it is not part of an official release, but you may download the code, compile and use it. Beware that the new version has a different syntax to support the expanded functionality.</p>]]></content:encoded>
    </item>
    <item>
      <title>Sprinkler on CodePlex</title>
      <link>https://docs.microsoft.com/archive/blogs/giuliov/sprinkler-on-codeplex</link>
      <pubDate>Wed, 29 Sep 2010 09:05:19 GMT</pubDate>
      <dc:creator><![CDATA[Giulio Vian]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/giuliov/2010/09/29/sprinkler-on-codeplex/</guid>
      <description><![CDATA[Today I published on CodePlex my first project, Sprinkler.  It is both a tool and a framework, based...]]></description>
      <content:encoded><![CDATA[<p>Today I published on CodePlex my first project, <a href="https://sprinkler.codeplex.com/">Sprinkler</a>.</p>  <p>It is both a tool and a framework, based on Powershell v2, aimed at simplifying deployment of applications, especially BizTalk-based. It stands on the shoulders of giants as it extends the <a href="https://biztalkdeployment.codeplex.com/">Deployment Framework for BizTalk</a>: this latter is focused on deploying a single BizTalk application, while Sprinkler manages multiple BizTalk applications and multiple servers.</p>  <p>Notable features are:</p>  <ul>   <li>Parallelization of execution — the tool must be run on all servers of the farm and will operate concurrently as much as possible, reducing deployment time window;</li>    <li>Can be run from a central location by leveraging Powershell v2 remoting;</li>    <li>Script based — requires Powershell v2, no additional component to install on any server; you can Zip everything and send it to a different site;</li>    <li>Flexible layout — keep all the files in a single share or spread them in different locations to keep sensitive information in a safe place or in a read-only folder;</li>    <li>Simple configuration — all parameters for execution are contained in just two files;</li>    <li>Interactive and unattended mode — an menu driven wizard helps choosing the script to run and its parameters;</li>    <li>Complete and centralized logging in plain text files;</li>    <li>Can execute sections of code in 32-bits for compatibility;</li>    <li>Rich library for operating BizTalk — stopping host instances, setting host adapters, starting and stopping applications in order, BRE rules managing;</li>    <li>Add new scripts and functions that leverage all above features.</li> </ul>  <p>Feedback is more than welcome, and apologize for bugs and lack of documentation.</p>]]></content:encoded>
    </item>
  </channel>
</rss>