<?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>James Schaffer - All Things .NET</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/jschaffe/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/jschaffe/feed.xml</link>
    <description>Senior Consultant with Microsoft Consulting Services.  This content is provided “AS IS” with no warranties and confers no rights.</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:16:07 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Undoing WiX Custom Actions During Uninstall</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/undoing-wix-custom-actions-during-uninstall</link>
      <pubDate>Sun, 28 Oct 2012 17:13:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2012/10/28/undoing-wix-custom-actions-during-uninstall/</guid>
      <description><![CDATA[In my previous post about creating Custom Actions with WiX, I showed how to create a custom action...]]></description>
      <content:encoded><![CDATA[<p>In my <a href="https://blogs.msdn.com/b/jschaffe/archive/2012/10/23/creating-wix-custom-actions-in-c-and-passing-parameters.aspx" target="_blank">previous post</a> about creating Custom Actions with WiX, I showed how to create a custom action project and invoke the custom action from a setup project.&nbsp; In my particular case, the custom action was making several edits to an existing web.config file to incorporate a new HTTP module that was being installed.&nbsp; Since these edits to the web.config are not automatically removed during uninstall of the HTTP module, I need a compensating custom action to perform this task.</p>
<p>Since I already have a custom action project and the associated CustomActions class from the previous post, the easiest thing to do is to incorporate the custom action for the uninstall into the same class (Remember, a custom action is represented as a static method annotated with the CustomAction attribute that ultimately gets generated into a DLL entry point that is callable by the MSI engine).&nbsp; So to add the new custom action, I simply need to add another method to my CustomActions class.&nbsp; The original custom action to make the web.config edits and the new custom action to remove the edits on uninstall are shown below.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 800px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> CustomActions</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span> {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span>     [CustomAction]</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> ActionResult ConfigurEwsFilter(Session session)</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>     {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span>         <span style="color: #0000ff;">try</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span>         {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span>             session.Log(<span style="color: #006080;">"Begin Configure EWS Filter Custom Action"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span>             <span style="color: #008000;">// TODO: Make changes to config file</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum12" style="color: #606060;"> 12:</span>             session.Log(<span style="color: #006080;">"End Configure EWS Filter Custom Action"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum13" style="color: #606060;"> 13:</span>         }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum14" style="color: #606060;"> 14:</span>         <span style="color: #0000ff;">catch</span> (Exception ex)</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum15" style="color: #606060;"> 15:</span>         {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum16" style="color: #606060;"> 16:</span>             session.Log(<span style="color: #006080;">"ERROR in custom action ConfigureEwsFilter {0}"</span>, </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum17" style="color: #606060;"> 17:</span>                         ex.ToString());</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum18" style="color: #606060;"> 18:</span>             <span style="color: #0000ff;">return</span> ActionResult.Failure;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum19" style="color: #606060;"> 19:</span>         }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum20" style="color: #606060;"> 20:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum21" style="color: #606060;"> 21:</span>         <span style="color: #0000ff;">return</span> ActionResult.Success;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum22" style="color: #606060;"> 22:</span>     }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum23" style="color: #606060;"> 23:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum24" style="color: #606060;"> 24:</span>     [CustomAction]</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum25" style="color: #606060;"> 25:</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> ActionResult RemoveEwsFilterConfig(Session session)</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum26" style="color: #606060;"> 26:</span>     {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum27" style="color: #606060;"> 27:</span>         <span style="color: #0000ff;">try</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum28" style="color: #606060;"> 28:</span>         {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum29" style="color: #606060;"> 29:</span>             session.Log(<span style="color: #006080;">"Begin Remove EWS Filter Configuration Custom Action"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum30" style="color: #606060;"> 30:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum31" style="color: #606060;"> 31:</span>             <span style="color: #008000;">// TODO: Remove changes to config file</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum32" style="color: #606060;"> 32:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum33" style="color: #606060;"> 33:</span>             session.Log(<span style="color: #006080;">"End Remove EWS Filter Configuration Custom Action"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum34" style="color: #606060;"> 34:</span>         }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum35" style="color: #606060;"> 35:</span>         <span style="color: #0000ff;">catch</span> (Exception ex)</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum36" style="color: #606060;"> 36:</span>         {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum37" style="color: #606060;"> 37:</span>             session.Log(<span style="color: #006080;">"ERROR in custom action RemoveEwsFilterConfig {0}"</span>, </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum38" style="color: #606060;"> 38:</span>                         ex.ToString());</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum39" style="color: #606060;"> 39:</span>             <span style="color: #0000ff;">return</span> ActionResult.Failure;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum40" style="color: #606060;"> 40:</span>         }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum41" style="color: #606060;"> 41:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum42" style="color: #606060;"> 42:</span>         <span style="color: #0000ff;">return</span> ActionResult.Success;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum43" style="color: #606060;"> 43:</span>     }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum44" style="color: #606060;"> 44:</span> }</pre>
<!--CRLF--></div>
</div>
<p>As with the original custom action, I need a reference to the new custom action in the *.wxs file.&nbsp; The original Binary element and CustomAction element are shown along with the new CustomAction element (lines 8-12) to remove the configuration changes.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> &lt;Binary Id=<span style="color: #006080;">"EwsAction.CA.dll"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span>         src=<span style="color: #006080;">"..\EwsAction\bin\$(var.Configuration)\EwsAction.CA.dll"</span> /&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> &lt;CustomAction Id=<span style="color: #006080;">"ConfigurEwsFilter"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span>               Return=<span style="color: #006080;">"check"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>               Execute=<span style="color: #006080;">"immediate"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span>               BinaryKey=<span style="color: #006080;">"EwsAction.CA.dll"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span>               DllEntry=<span style="color: #006080;">"ConfigurEwsFilter"</span> /&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span> &lt;CustomAction Id=<span style="color: #006080;">"RemoveEwsFilterConfig"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span>               Return=<span style="color: #006080;">"check"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span>               Execute=<span style="color: #006080;">"immediate"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span>               BinaryKey=<span style="color: #006080;">"EwsAction.CA.dll"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum12" style="color: #606060;"> 12:</span>               DllEntry=<span style="color: #006080;">"RemoveEwsFilterConfig"</span> /&gt;</pre>
<!--CRLF--></div>
</div>
<p>The only differences between the two CustomAction elements are the Id and DllEntry attributes, where the DllEntry attribute indicates the CustomAction method to invoke.</p>
<p>Up to this point, the process of adding the compensating CustomAction is exactly the same as adding the original CustomAction.&nbsp; However, I only want the new custom action to run during uninstall of the HTTP module.&nbsp; I can control that with a condition on the custom action&rsquo;s entry in the InstallExecuteSequence.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> &lt;InstallExecuteSequence&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span>   &lt;Custom Action=<span style="color: #006080;">"AssignConfigFile"</span> After=<span style="color: #006080;">"CostFinalize"</span> /&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span>   &lt;Custom Action=<span style="color: #006080;">"ConfigurEwsFilter"</span> Before=<span style="color: #006080;">"InstallFinalize"</span>&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span>     NOT Installed</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>   &lt;/Custom&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span>   &lt;Custom Action=<span style="color: #006080;">"RemoveEwsFilterConfig"</span> Before=<span style="color: #006080;">"InstallFinalize"</span>&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span>     Installed AND NOT UPGRADINGPRODUCTCODE</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span>   &lt;/Custom&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span> &lt;/InstallExecuteSequence&gt;</pre>
<!--CRLF--></div>
</div>
<p>The entry for the new custom action is shown on lines 6-8 above.&nbsp; Line 7 provides the condition when the custom action should be run.&nbsp; In this case it references the <a href="https://msdn.microsoft.com/en-us/library/aa369297(v=vs.85).aspx" target="_blank">Installed</a> and <a href="https://msdn.microsoft.com/en-us/library/aa372380(v=vs.85).aspx" target="_blank">UPGRADINGPRODUCTCODE</a> properties, indicating that the product should already be installed and an upgrade to the product is not being performed (i.e. during uninstall).&nbsp;</p>
<p>You&rsquo;ll also notice the condition <strong>NOT Installed</strong> added to the original custom action performing the configuration edits.&nbsp; That&rsquo;s because I want it to only run during install, not during uninstall, otherwise I&rsquo;ll get my edits added back into the web.config file.</p>]]></content:encoded>
    </item>
    <item>
      <title>Creating WiX Custom Actions in C# and Passing Parameters</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/creating-wix-custom-actions-in-c-and-passing-parameters</link>
      <pubDate>Tue, 23 Oct 2012 18:29:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2012/10/23/creating-wix-custom-actions-in-c-and-passing-parameters/</guid>
      <description><![CDATA[I&rsquo;m currently working on a project where I&rsquo;m creating a custom HTTP module for a...]]></description>
      <content:encoded><![CDATA[<p>I&rsquo;m currently working on a project where I&rsquo;m creating a custom HTTP module for a customer.&nbsp; The module is to be used with an existing commercial product.&nbsp; Since the custom HTTP module is working with an existing product, the process of installing it would need to make significant changes to the web.config file of the existing product, plus be able to remove those changes during a subsequent uninstall.</p>
<p>I hadn&rsquo;t worked with <a href="https://wixtoolset.org/" target="_blank">Windows Installer XML (WiX)</a> projects before so this was a perfect opportunity to get up to speed.&nbsp;</p>
<p><strong><span style="font-size: x-small;" size="2">Creating a Setup Project and C# Custom Action Project</span></strong></p>
<p>Once you install the <a href="https://wix.codeplex.com/releases/view/93929" target="_blank">WiX toolset</a> you&rsquo;ll be able to create a new Setup Project from Visual Studio as shown below.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/7723.image_0ED26EF9.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/7723.image_5F00_0ED26EF9.png"><img width="580" height="402" title="image" style="display: inline; background-image: none;" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/1447.image_thumb_17069490.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/1447.image_5F00_thumb_5F00_17069490.png" border="0" /></a></p>
<p>After creating the setup project you&rsquo;ll have a Product.<a href="https://wix.sourceforge.net/manual-wix2/wxs.htm" target="_blank">wxs</a> file that defines your setup.&nbsp; I won&rsquo;t go into details about the general process of authoring this file as this is covered in detail in the online <a href="https://wix.tramontana.co.hu/tutorial" target="_blank">WiX tutorial</a>.&nbsp; Once we&rsquo;ve created our setup project, we&rsquo;ll need to add a C# Custom Action Project to our solution (you can see this project template option in the above screenshot as well).&nbsp; Within the custom action project you&rsquo;ll have a new CustomActions class that looks like the following:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span> CustomActions</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span> {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span>     [CustomAction]</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> ActionResult CustomAction1(Session session)</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>     {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span>         session.Log(<span style="color: #006080;">"Begin CustomAction1"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span>         <span style="color: #0000ff;">return</span> ActionResult.Success;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span>     }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span> }</pre>
<!--CRLF--></div>
</div>
<p>This is where you&rsquo;ll write the code that you want to be executed when the custom action method is called.&nbsp; Any method that you want to expose to the setup project must be a public static method that is annotated with the CustomAction attribute and has the following method signature.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> ActionResult ActionMethod(Session session)</pre>
<!--CRLF--></div>
</div>
<p>The Session parameter passed to the method is the object that controls the installation process.&nbsp; Among other things, the Session object allows you to write output to the installation log file and gives you access to global properties for passing data (we&rsquo;ll use this later).</p>
<p>So in my particular instance I needed to write a custom action that would perform various updates to the existing product&rsquo;s web.config file as part of the install.&nbsp; WiX provides what&rsquo;s referred to as a Standard Custom Action library for <a href="https://wix.sourceforge.net/manual-wix3/util_xsd_xmlfile.htm" target="_blank">manipulating XML files</a> as part of an installation.&nbsp; However, after reviewing the on-line content and some examples this proved to be far too cumbersome for my needs.</p>
<p>So my custom action method ultimately looked similar to the following:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 400px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> [CustomAction]</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> ActionResult ConfigurEwsFilter(Session session)</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span>     <span style="color: #0000ff;">try</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>     {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span>         session.Log(<span style="color: #006080;">"Begin Configure EWS Filter Custom Action"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span>         <span style="color: #008000;">// TODO: Make changes to config file</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span>         session.Log(<span style="color: #006080;">"End Configure EWS Filter Custom Action"</span>);</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span>     }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum12" style="color: #606060;"> 12:</span>     <span style="color: #0000ff;">catch</span> (Exception ex)</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum13" style="color: #606060;"> 13:</span>     {</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum14" style="color: #606060;"> 14:</span>         session.Log(<span style="color: #006080;">"ERROR in custom action ConfigureEwsFilter {0}"</span>, </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum15" style="color: #606060;"> 15:</span>                     ex.ToString());</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum16" style="color: #606060;"> 16:</span>         <span style="color: #0000ff;">return</span> ActionResult.Failure;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum17" style="color: #606060;"> 17:</span>     }</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum18" style="color: #606060;"> 18:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum19" style="color: #606060;"> 19:</span>     <span style="color: #0000ff;">return</span> ActionResult.Success;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum20" style="color: #606060;"> 20:</span> }</pre>
<!--CRLF--></div>
</div>
<p>The code snippet shows what could be argued as a standard boilerplate approach for custom actions.&nbsp; Logging the entry and exit of the custom action, performing the configuration step necessary and handling an unhandled exceptions to make sure they are logged to the output correctly.</p>
<p>Compiling the custom action project will generate two DLLs.&nbsp; The additional DLL, <strong>$(TargetName).CA.dll, </strong>provides a format that is callable from the MSI engine.&nbsp; Therefore, this is the DLL that we want to reference from the *.wxs file in the setup project.&nbsp; To do that, we add a <a href="https://wix.sourceforge.net/manual-wix2/wix_xsd_binary.htm" target="_blank">Binary</a> element within the Product element that was generated in the *.wxs when the setup project was created.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> &lt;Product Id=<span style="color: #006080;">"*"</span> Name=<span style="color: #006080;">"SetupProject1"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span>          Language=<span style="color: #006080;">"1033"</span> Version=<span style="color: #006080;">"1.0.0.0"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span>          Manufacturer=<span style="color: #006080;">""</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span>          UpgradeCode=<span style="color: #006080;">"d206ba77-ddbe-41a3-893f-324f55242bef"</span>&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span>   &lt;Binary Id=<span style="color: #006080;">"EwsAction.CA.dll"</span></pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span>           src=<span style="color: #006080;">"..\EwsAction\bin\$(var.Configuration)\EwsAction.CA.dll"</span> /&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span> &lt;/Product&gt;</pre>
<!--CRLF--></div>
</div>
<p>In the snippet above, I&rsquo;m referencing the *.CA.dll relative to the setup project (which is in the same solution).&nbsp; I&rsquo;m also indicating that I want to base the version of the *.CA.dll on the current build configuration of the setup project using the $(var.Configuration) syntax.&nbsp; That way, if I build a debug version of the setup project I get a debug version of the custom action and a similar result for a release build.</p>
<p>Along with the Binary element, we&rsquo;ll also need to add a <a href="https://wix.sourceforge.net/manual-wix2/wix_xsd_customaction.htm" target="_blank">CustomAction</a> element to reference the Binary element&rsquo;s Id and indicate the entry point that we want to execute.&nbsp; This should look similar to the following:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> &lt;CustomAction Id=<span style="color: #006080;">"ConfigurEwsFilter"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span>               Return=<span style="color: #006080;">"check"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span>               Execute=<span style="color: #006080;">"immediate"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span>               BinaryKey=<span style="color: #006080;">"EwsAction.CA.dll"</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>               DllEntry=<span style="color: #006080;">"ConfigurEwsFilter"</span> /&gt;</pre>
<!--CRLF--></div>
</div>
<p>In the above example, notice that the BinaryKey attribute matches the Id attribute of the Binary element we previously added.&nbsp; Also note that the DllEntry attribute references the method name that was decorated with the CustomAction attribute in the C# code.</p>
<p>Adding the Binary and CustomAction elements by themselves however still does not result in the custom action actually being executed.&nbsp; To include the custom action in the installation process we need to add an entry to the InstallExecuteSequence as shown.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> &lt;InstallExecuteSequence&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span>   &lt;Custom Action=<span style="color: #006080;">"ConfigurEwsFilter"</span> Before=<span style="color: #006080;">"InstallFinalize"</span>  /&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span> &lt;/InstallExecuteSequence&gt;</pre>
<!--CRLF--></div>
</div>
<p>Note here that we&rsquo;re referencing the Id attribute of the CustomAction element while indicating that we want this action to execute prior to the standard InstallFinalize action of the installation.</p>
<p><strong><span style="font-size: x-small;" size="2">Passing Parameters</span></strong></p>
<p>The last issue we need to resolve is retrieving the location of the existing product&rsquo;s web.config file and passing it to the custom action.&nbsp; In my case I can use a standard <a href="https://wix.sourceforge.net/manual-wix2/wix_xsd_registrysearch.htm" target="_blank">RegistrySearch</a> action to read the install path of the existing product from the registry.&nbsp; The web.config should exist within a well known folder path within the install path.&nbsp; Since the RegistrySearch action will store the root install path to a property, I need a separate CustomAction to build out the full path to the web.config file.&nbsp; As a consequence, I&rsquo;ll also need another entry in the InstallExecuteSequence to execute this new custom action.&nbsp; These 3 additions are shown below.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 300px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> &lt;Property Id=<span style="color: #006080;">"PRODUCTINSTALLFOLDER"</span>&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span>   &lt;RegistrySearch Id=<span style="color: #006080;">'ProductInstallDir'</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum3" style="color: #606060;"> 3:</span>                   Type=<span style="color: #006080;">'raw'</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum4" style="color: #606060;"> 4:</span>                   Root=<span style="color: #006080;">'HKLM'</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum5" style="color: #606060;"> 5:</span>                   Key=<span style="color: #006080;">'SOFTWARE\Manufacturer\ExistingProduct\Setup'</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum6" style="color: #606060;"> 6:</span>                   Name=<span style="color: #006080;">'MsiInstallPath'</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum7" style="color: #606060;"> 7:</span>                   Win64=<span style="color: #006080;">'yes'</span>/&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum8" style="color: #606060;"> 8:</span> &lt;/Property&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum9" style="color: #606060;"> 9:</span> &lt;CustomAction Id=<span style="color: #006080;">'AssignConfigFile'</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum10" style="color: #606060;"> 10:</span>               Property=<span style="color: #006080;">'CONFIGFILE'</span> </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum11" style="color: #606060;"> 11:</span>               Value=<span style="color: #006080;">'[PRODUCTINSTALLFOLDER]pathtoconfigfile\web.config'</span> /&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum12" style="color: #606060;"> 12:</span> &lt;InstallExecuteSequence&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum13" style="color: #606060;"> 13:</span>   &lt;Custom Action=<span style="color: #006080;">"AssignConfigFile"</span> After=<span style="color: #006080;">"CostFinalize"</span> /&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum14" style="color: #606060;"> 14:</span>   &lt;Custom Action=<span style="color: #006080;">"ConfigurEwsFilter"</span> Before=<span style="color: #006080;">"InstallFinalize"</span>  /&gt;</pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum15" style="color: #606060;"> 15:</span> &lt;/InstallExecuteSequence&gt;</pre>
<!--CRLF--></div>
</div>
<p>The result of the above is that the web.config file&rsquo;s path should now be in the global property named CONFIGFILE.&nbsp; With the Session object discussed earlier, I can now access this path from within my custom action code using syntax similar to the following:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: 'Courier New', courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: #f4f4f4;">
<div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span id="lnum1" style="color: #606060;"> 1:</span> session.Log(<span style="color: #006080;">"Session value for CONFIGFILE = '{0}'"</span>, </pre>
<!--CRLF-->
<pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: 'Courier New', courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><span id="lnum2" style="color: #606060;"> 2:</span>             session[<span style="color: #006080;">"CONFIGFILE"</span>]);</pre>
<!--CRLF--></div>
</div>
<p>Now within my custom action method I can open the web.config file and make the necessary edits for my custom HTTP module.</p>
<p>Since the web.config edits are performed by a custom action, they won&rsquo;t automatically be removed during an uninstall.&nbsp; In my <a href="https://blogs.msdn.com/b/jschaffe/archive/2012/10/28/undoing-wix-custom-actions-during-uninstall.aspx">next blog post</a> I&rsquo;ll discuss creating a separate custom action to remove the web.config edits and have it run only during the uninstall of the module.</p>]]></content:encoded>
    </item>
    <item>
      <title>Upgrading Team Projects After Migrating From TFS 2008 to TFS 2012</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/upgrading-team-projects-after-migrating-from-tfs-2008-to-tfs-2012</link>
      <pubDate>Wed, 17 Oct 2012 17:43:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2012/10/17/upgrading-team-projects-after-migrating-from-tfs-2008-to-tfs-2012/</guid>
      <description><![CDATA[UPDATE: The content of this post was originally a gap in the on-line MSDN documentation which has...]]></description>
      <content:encoded><![CDATA[<p><strong>UPDATE</strong>: The content of this post was originally a gap in the on-line MSDN documentation which has since been filled.&nbsp; The official MSDN documentation can now&nbsp;be found <a title="here" href="https://msdn.microsoft.com/en-us/library/ff452591.aspx">here</a>.</p>
<p>I recently worked with a customer that was upgrading from Team Foundation Server (TFS) 2008 to TFS 2012.&nbsp; After the upgrade, all of the existing Team Projects were available within the new project collection as expected.&nbsp; However, one thing the upgrade process doesn't do for you is upgrade the team projects themselves.&nbsp; That means that the Team Projects were still operating off of the MSF for Agile Software Development 4.2 process template rather than the new 6.0 version of the same template.&nbsp; Since the customer wanted to take advantage of all the new functionality and work item types added since 2008, we needed to upgrade each of their existing Team Projects to add these features.</p>
<p>While there is documentation on TechNet for <a href="https://technet.microsoft.com/en-us/subscriptions/hh500409(v=vs.110).aspx">Adding Features Using a Manual Update Process</a>, this focuses on upgrading from TFS 2010 to TFS 2012.&nbsp; That didn't quite fit the bill for our scenario since there were a great deal of changes between TFS 2008 and TFS 2010 that weren&rsquo;t accounted for.&nbsp; I also found documentation on MSDN regarding <a href="https://msdn.microsoft.com/en-us/library/ff452591(v=VS.100).aspx">Enabling Interfacing with Microsoft Test Manager for Upgraded Team Projects</a>.&nbsp; Since the customer was interested in using MTM, that sounded promising, but this guidance focused on an upgrade from TFS 2008 to TFS 2010.&nbsp; So I had information for upgrading from 2008 to 2010 and from 2010 to 2012, but nothing to go directly from 2008 to 2012.&nbsp; So we took the approach of combining the two separate pieces of guidance into one concise approach as outlined below.</p>
<ol>
<li>First we need to export the MSF for Agile Software Development 6.0 Process Template as parts of this will be used in subsequent steps.</li>
<li>Using <a href="https://msdn.microsoft.com/en-us/library/dd236914.aspx">witadmin.exe</a>, import the following work item type definitions from the 6.0 template into each of your team projects that need upgraded.<ol>
<li><strong>UserStory</strong></li>
<li><strong>TestCase</strong>- This required slight modification to the following system field names to remove spaces that were added since 2008 but that still exist based on the 2008 template.<ol>
<li>External Link Count --&gt; ExternalLinkCount</li>
<li>Related Link Count --&gt; RelatedLinkCount</li>
<li>HyperLink Count --&gt; HyperLinkCount</li>
<li>Attached File Count --&gt; AttachedFilecount</li>
<li>Area ID --&gt; AreaID</li>
</ol></li>
<li><strong>SharedStep</strong>- This required slight modification to the following system field names to remove spaces that were added since 2008 but that still exist based on the 2008 template<ol>
<li>Iteration ID --&gt; IterationID</li>
<li>External Link count --&gt; ExternalLinkCount</li>
<li>Related Link Count --&gt; RelatedLinkCount</li>
<li>HyperLink Count --&gt; HyperLinkCount</li>
<li>Attached File Count --&gt; AttachedFilecount</li>
<li>Area ID --&gt; AreaID</li>
</ol></li>
<li><strong>Task</strong> - Required because there are necessary fields (StartWork, StopWork) missing in the 4.2 version</li>
</ol></li>
<li>Using witadmin.exe, import the following Linked Types - <strong><span style="color: #ff0000;">NOTE</span></strong>: This is a one time operation for the Team Project Collection and does not need to be run for each Team Project.<ol>
<li><strong>TestedBy</strong></li>
<li><strong>SharedStep</strong></li>
</ol></li>
<li>Using witadmin.exe, import categories for each Team Project being upgraded.<ol>
<li>We first had to comment out references to all new 6.0 WITs (e.g. Code Review Request/Response) since they do not yet exist.&nbsp; These will be updated during the Configure operation in Step #5.</li>
</ol></li>
<li>Run Configure from the Admin site for each Team Project<ol><ol>
<li>After performing the above steps for a given Team Project you then need to navigate to the Admin site for the project.&nbsp; You can do this by clicking Web Access for the Team Project from Team Explorer as shown.</li>
</ol></ol>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/8446.clip_image002_2B747776.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/8446.clip_5F00_image002_5F00_2B747776.jpg"><img style="display: inline; background-image: none;" title="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/1588.clip_image002_thumb_237CD514.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/1588.clip_5F00_image002_5F00_thumb_5F00_237CD514.jpg" alt="clip_image002" width="151" height="244" border="0" /></a>&nbsp;</p>
</blockquote>
<ol><ol>
<li>Then click on the Administrative icon <a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/3323.clip_image0024_56D89870.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/3323.clip_5F00_image0024_5F00_56D89870.jpg"><img style="display: inline; background-image: none;" title="clip_image002[4]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/4214.clip_image0024_thumb_365158BE.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/4214.clip_5F00_image0024_5F00_thumb_5F00_365158BE.jpg" alt="clip_image002[4]" width="36" height="37" border="0" /></a> in the upper right corner of the page.</li>
<li>From the Administrative page you should see an option similar to the following indicating that you have features for this Team Project that are not configured.&nbsp; Click the Configure Features link.</li>
</ol></ol>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/6036.clip_image0026_39EF739B.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/6036.clip_5F00_image0026_5F00_39EF739B.jpg"><img style="display: inline; background-image: none;" title="clip_image002[6]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/8422.clip_image0026_thumb_14F1B322.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/8422.clip_5F00_image0026_5F00_thumb_5F00_14F1B322.jpg" alt="clip_image002[6]" width="244" height="104" border="0" /></a></p>
</blockquote>
<ol><ol>
<li>This should result in a dialog similar to the following indicating the process template that your Team Project will be upgraded to.</li>
</ol></ol>
<blockquote>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/5850.clip_image0028_383EA7C7.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/5850.clip_5F00_image0028_5F00_383EA7C7.jpg"><img style="display: inline; background-image: none;" title="clip_image002[8]" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/4784.clip_image0028_thumb_44CC54E3.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/4784.clip_5F00_image0028_5F00_thumb_5F00_44CC54E3.jpg" alt="clip_image002[8]" width="646" height="373" border="0" /></a></p>
</blockquote>
<ol>
<li>Click on the Configure button and the Team Project should be upgraded to the new process template.</li>
</ol></li>
<li>Finally, we need to copy the new Work Item Queries to each Team Project.&nbsp;</li>
<ol>
<li>Create a test project based on the MSF for Agile Software Development 6.0 Process Template to copy the Work Item Queries from.</li>
<li>Use <a href="https://wiqadmin.codeplex.com/">WiqAdmin</a> to copy updated queries from the test project to the migrated projects</li>
<ol>
<li>NOTE: WiqAdmin currently only supports Team Explorer 2008/2010.&nbsp; The 2010 version must be run from a machine with TE 2010 installed to bind to the correct assemblies.</li>
<li>Syntax for the copy operation should be similar to the following to copy all queries recursively without overwriting any existing queries:<ol>
<li>wiqadmin copy /collectionFrom:&lt;collectionUrl&gt; /collectionTo:&lt;collectionUrl&gt; <br /> /projectFrom:&lt;test project&gt; /projectTo:&lt;migrate project&gt; <br /> /ondup:S /folder:"Shared Queries" /recursive&nbsp;</li>
<li>Replace the collectionUrl and project name parameters above for your environment</li>
</ol></li>
</ol></ol></ol>
<p>Since we had to perform the above operation for multiple team projects (upwards of 50) we tried to automate the process as much as possible to creating some simple command line files to accommodate this.</p>
<p><strong><span style="color: #ff0000;">NOTE</span></strong>: The above outline is specific to the MSF for Agile Software Development process template but should be similar for other process templates.</p>
<p>The command files and the updated process template files required for the steps listed above are included in the zip file below for reference.</p>
<div id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:ca4f75ed-73c4-4440-9917-fd066f1df4f4" 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/01/43/38/metablogapi/5270.Upgrade-Team-Projects_7B868FD3.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/5270.Upgrade_2D00_Team_2D00_Projects_5F00_7B868FD3.zip" target="_blank">Upgrade Scripts and Modified WIT Files</a></p>
</div>]]></content:encoded>
    </item>
    <item>
      <title>A Re-Usable Button Control for TFS Work Item Definitions</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/a-re-usable-button-control-for-tfs-work-item-definitions</link>
      <pubDate>Fri, 04 May 2012 11:31:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2012/05/04/a-re-usable-button-control-for-tfs-work-item-definitions/</guid>
      <description><![CDATA[There&rsquo;s plenty of documentation available on MSDN and from other sources that discusses how to...]]></description>
      <content:encoded><![CDATA[<p>There&rsquo;s plenty of documentation available on <a href="https://blogs.msdn.com/b/greggboer/archive/2010/03/30/work-item-tracking-custom-controls.aspx" target="_blank">MSDN</a> and from other sources that discusses how to create custom controls to be used by TFS Work Item Type (WIT) definitions.&nbsp; I was working with a customer recently and I needed to customize a work item to show a button that would launch a custom user interface.&nbsp; The custom UI would create an associated Code Review work item and a shelveset from the user&rsquo;s current pending changes.&nbsp; I thought there might be an existing implementation of a custom WIT button control but alas, after scouring the web and other resources I couldn&rsquo;t find any.&nbsp; So I started down the path of writing my own.</p>
<p>As mentioned above there is already a wealth of documentation detailing how to create custom controls, so I won&rsquo;t get into most of those details.&nbsp; Instead I&rsquo;ll focus on the code for the button control and how you can re-use the control to add similar functionality to your work item types.</p>
<p>The implementation turns out to be pretty straight forward.&nbsp; I create a new control library and add a new control that derives from UserControl and implements the <a href="https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.workitemtracking.controls.iworkitemcontrol(v=vs.90).aspx" target="_blank">IWorkItemControl</a> interface.&nbsp; The IWorkItemControl interface implementation is shown below.</p>
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;" id="codeSnippetWrapper">
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum1"> 1:</span> <span style="color: #0000ff;">protected</span> IServiceProvider _serviceProvider;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum2"> 2:</span> <span style="color: #0000ff;">void</span> IWorkItemControl.SetSite(IServiceProvider serviceProvider)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum3"> 3:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum4"> 4:</span>     _serviceProvider = serviceProvider;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum5"> 5:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum6"> 6:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum7"> 7:</span> <span style="color: #0000ff;">protected</span> WorkItem _workItem;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum8"> 8:</span> <span style="color: #0000ff;">object</span> IWorkItemControl.WorkItemDatasource</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum9"> 9:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum10"> 10:</span>     get { <span style="color: #0000ff;">return</span> _workItem; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum11"> 11:</span>     set { _workItem = (WorkItem)<span style="color: #0000ff;">value</span>; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum12"> 12:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum13"> 13:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum14"> 14:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> EventHandler AfterUpdateDatasource;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum15"> 15:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum16"> 16:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> EventHandler BeforeUpdateDatasource;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum17"> 17:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum18"> 18:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> Clear()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum19"> 19:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum20"> 20:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum21"> 21:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum22"> 22:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> FlushToDatasource()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum23"> 23:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum24"> 24:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum25"> 25:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum26"> 26:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> InvalidateDatasource()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum27"> 27:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum28"> 28:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum29"> 29:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum30"> 30:</span> <span style="color: #0000ff;">public</span> System.Collections.Specialized.StringDictionary Properties</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum31"> 31:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum32"> 32:</span>     get { <span style="color: #0000ff;">return</span> _properties; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum33"> 33:</span>     set { _properties = <span style="color: #0000ff;">value</span>; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum34"> 34:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum35"> 35:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum36"> 36:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">bool</span> ReadOnly</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum37"> 37:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum38"> 38:</span>     get { <span style="color: #0000ff;">return</span> _readonly; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum39"> 39:</span>     set { _readonly = <span style="color: #0000ff;">value</span>; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum40"> 40:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum41"> 41:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum42"> 42:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> WorkItemFieldName</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum43"> 43:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum44"> 44:</span>     get { <span style="color: #0000ff;">return</span> _fieldName; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum45"> 45:</span>     set { _fieldName = <span style="color: #0000ff;">value</span>; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum46"> 46:</span> }</pre>
<!--CRLF--></div>
</div>
<p>With the interface implemented, I then simply add a new button control to the custom control with some default settings as shown.</p>
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;" id="codeSnippetWrapper">
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum1"> 1:</span> <span style="color: #0000ff;">private</span> Button _button;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum2"> 2:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum3"> 3:</span> <span style="color: #0000ff;">public</span> WitButton()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum4"> 4:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum5"> 5:</span>     InitializeComponent();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum6"> 6:</span>     InitControl();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum7"> 7:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum8"> 8:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum9"> 9:</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> InitControl()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum10"> 10:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum11"> 11:</span>     <span style="color: #0000ff;">if</span> (_button != <span style="color: #0000ff;">null</span>)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum12"> 12:</span>         <span style="color: #0000ff;">return</span>;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum13"> 13:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum14"> 14:</span>     _button = <span style="color: #0000ff;">new</span> Button();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum15"> 15:</span>     _button.Text = <span style="color: #006080;">"Default Text"</span>;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum16"> 16:</span>     _button.Width = 125;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum17"> 17:</span>     _button.Top = 10;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum18"> 18:</span>     _button.Click += <span style="color: #0000ff;">new</span> EventHandler(_button_Click);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum19"> 19:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum20"> 20:</span>     <span style="color: #0000ff;">base</span>.Controls.Clear();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum21"> 21:</span>     <span style="color: #0000ff;">base</span>.Controls.Add(_button);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum22"> 22:</span> }</pre>
<!--CRLF--></div>
</div>
<p>Finally, I expose the Text and Width properties of the internal button control so that they can be set by any derived controls.&nbsp; I also expose an event that is fired when the button is clicked.</p>
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;" id="codeSnippetWrapper">
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum1"> 1:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> ButtonText</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum2"> 2:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum3"> 3:</span>     get { <span style="color: #0000ff;">return</span> _button.Text; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum4"> 4:</span>     set { _button.Text = <span style="color: #0000ff;">value</span>; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum5"> 5:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum6"> 6:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum7"> 7:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">int</span> ButtonWidth</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum8"> 8:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum9"> 9:</span>     get { <span style="color: #0000ff;">return</span> _button.Width; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum10"> 10:</span>     set { _button.Width = <span style="color: #0000ff;">value</span>; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum11"> 11:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum12"> 12:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum13"> 13:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">delegate</span> <span style="color: #0000ff;">void</span> ButtonClickHandler(<span style="color: #0000ff;">object</span> sender, EventArgs args);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum14"> 14:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">event</span> ButtonClickHandler ButtonClick;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum15"> 15:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum16"> 16:</span> <span style="color: #0000ff;">void</span> _button_Click(<span style="color: #0000ff;">object</span> sender, EventArgs e)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum17"> 17:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum18"> 18:</span>     <span style="color: #0000ff;">if</span> (ButtonClick != <span style="color: #0000ff;">null</span>)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum19"> 19:</span>         ButtonClick(sender, e);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum20"> 20:</span> }</pre>
<!--CRLF--></div>
</div>
<p>That&rsquo;s it for the base control, which by itself won&rsquo;t do much, so there is no *.wicc file necessary at this point.</p>
<p>Now I need to create a derived control that will set the base control&rsquo;s button text and width accordingly and handle the ButtonClick event to actually perform some work when the user clicks the button.&nbsp; A simple example of this is shown in the next snippet.</p>
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;" id="codeSnippetWrapper">
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum1"> 1:</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">partial</span> <span style="color: #0000ff;">class</span> MyButton : WitButton</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum2"> 2:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum3"> 3:</span>     <span style="color: #0000ff;">public</span> MyButton()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum4"> 4:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum5"> 5:</span>         InitializeComponent();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum6"> 6:</span>         <span style="color: #0000ff;">this</span>.ButtonText = <span style="color: #006080;">"Do Something"</span>;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum7"> 7:</span>         <span style="color: #0000ff;">this</span>.ButtonWidth = 150;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum8"> 8:</span>         <span style="color: #0000ff;">this</span>.ButtonClick += <span style="color: #0000ff;">new</span> ButtonClickHandler(MyButton_ButtonClick);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum9"> 9:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum10"> 10:</span>  </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum11"> 11:</span>     <span style="color: #0000ff;">void</span> MyButton_ButtonClick(<span style="color: #0000ff;">object</span> sender, EventArgs args)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum12"> 12:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum13"> 13:</span>         MessageBox.Show(<span style="color: #006080;">"Button was clicked"</span>);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum14"> 14:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum15"> 15:</span> }</pre>
<!--CRLF--></div>
</div>
<p>With the code in place I create a *.wicc file named MyCustomWitButton and deploy it along with the binaries for my custom control and the base control to Environment.SpecialFolder.CommonApplicationData\Microsoft\Team Foundation\Work Item Tracking\Custom Controls\10.0\ (there are multiple folders which are probed to locate custom WIT controls as explained <a href="https://blogs.msdn.com/b/greggboer/archive/2010/03/30/work-item-tracking-custom-controls.aspx" target="_blank">here</a>).&nbsp; Now I can add the derived button to my Bug work item type definition (no field name or label is required for the button control).</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/5126.image_601DBA96.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/5126.image_5F00_601DBA96.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/2664.image_thumb_3DAD15AB.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/2664.image_5F00_thumb_5F00_3DAD15AB.png" width="634" height="234" /></a></p>
<p>After saving the work item type definition I can now create a new Bug within the team project and I should get the following result.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/6864.image_0E7B2A14.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/6864.image_5F00_0E7B2A14.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/0842.image_thumb_74A6F3E4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/0842.image_5F00_thumb_5F00_74A6F3E4.png" width="513" height="303" /></a></p>
<p>Finally I can get to the original problem I was trying to solve, which was using a button from the work item form to launch a custom UI to create an associated Code Review work item and shelveset.&nbsp; I created a WPF application and launch it on the ButtonClick event.&nbsp; I am also leveraging the protected _workitem and _serviceProvider members from the base control to access the associated Bug work item and the TFS work item DocumentService respectively.&nbsp; The results are shown below.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/5710.image_4889F6F3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/5710.image_5F00_4889F6F3.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/6215.image_thumb_47455E14.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-38-metablogapi/6215.image_5F00_thumb_5F00_47455E14.png" width="534" height="492" /></a></p>
<p>I&rsquo;ve created a <a title="project" href="https://tfsbuttoncontrol.codeplex.com">project</a> on CodePlex where you can download the source for the base control and a sample derived control.</p>]]></content:encoded>
    </item>
    <item>
      <title>Windows Server AppFabric Cache – Referencing the Correct Assemblies</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/windows-server-appfabric-cache-referencing-the-correct-assemblies</link>
      <pubDate>Sat, 28 Jan 2012 14:03:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2012/01/28/windows-server-appfabric-cache-referencing-the-correct-assemblies/</guid>
      <description><![CDATA[&nbsp;I was recently putting together a distributed application cache proof of concept for a...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;I was recently putting together a distributed application cache proof of concept for a customer that leveraged the <a href="https://msdn.microsoft.com/en-us/library/ff383731.aspx" target="_blank">Windows Server AppFabric Cache</a>.&nbsp; In order to take advantage of this functionality, my project needed to reference the following assemblies:</p>
<ul>
<li>Microsoft.ApplicationServer.Caching.Client</li>
<li>Microsoft.ApplicationServer.Caching.Core</li>
</ul>
<p>Normally this would be easy enough.&nbsp; Assuming these are system level assemblies I&rsquo;d just reference them from the GAC - and sure enough I was able to find them there.&nbsp; Unfortunately, that was a mistake.&nbsp; It turns out that I also had the Windows Azure SDK installed on my development machine.&nbsp; Windows Azure also supports the <a href="https://msdn.microsoft.com/en-us/magazine/gg983488.aspx" target="_blank">AppFabric Cache</a>, but with a different version of these same named assemblies which are installed in the GAC.&nbsp; So when I ran my code and attempted to create my <a href="https://msdn.microsoft.com/en-us/library/microsoft.applicationserver.caching.datacachefactory(v=WS.10).aspx" target="_blank">DataCacheFactory</a>, I ended up with the following exception stack:</p>
<ul>
<li>{"'The invocation of the constructor on type 'SampleCache.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'."}</li>
</ul>
<ul>
<li>{"The type initializer for 'Microsoft.ApplicationServer.Caching.DataCacheFactoryConfiguration' threw an exception."}</li>
</ul>
<ul>
<li>{"[A]Microsoft.ApplicationServer.Caching.DataCacheClientSection cannot be cast to [B]Microsoft.ApplicationServer.Caching.DataCacheClientSection. Type A originates from 'Microsoft.ApplicationServer.Caching.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' in the context 'Default' at location 'C:\\Windows\\assembly\\GAC_MSIL\\Microsoft.ApplicationServer.Caching.Core\\1.0.0.0__31bf3856ad364e35\\Microsoft.ApplicationServer.Caching.Core.dll'. Type B originates from 'Microsoft.ApplicationServer.Caching.Core, Version=101.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' in the context 'Default' at location 'C:\\Users\\jschaffe\\Documents\\Visual Studio 2010\\Projects\\AppFabric\\Caching\\SampleCache\\SampleCache\\bin\\Debug\\Microsoft.ApplicationServer.Caching.Core.dll'."}</li>
</ul>
<p>The final exception in the stack indicates the problem.</p>
<p>{"[A]Microsoft.ApplicationServer.Caching.DataCacheClientSection cannot be cast to [B]Microsoft.ApplicationServer.Caching.DataCacheClientSection. Type A originates from 'Microsoft.ApplicationServer.Caching.Core, <span style="background-color: #ffff00;">Version=1.0.0.0</span>, Culture=neutral, PublicKeyToken=31bf3856ad364e35' in the context 'Default' at location 'C:\\Windows\\assembly\\GAC_MSIL\\Microsoft.ApplicationServer.Caching.Core\\1.0.0.0__31bf3856ad364e35\\Microsoft.ApplicationServer.Caching.Core.dll'. Type B originates from 'Microsoft.ApplicationServer.Caching.Core, <span style="background-color: #ffff00;">Version=101.0.0.0</span>, Culture=neutral, PublicKeyToken=31bf3856ad364e35' in the context 'Default' at location 'C:\\Users\\jschaffe\\Documents\\Visual Studio 2010\\Projects\\AppFabric\\Caching\\SampleCache\\SampleCache\\bin\\Debug\\Microsoft.ApplicationServer.Caching.Core.dll'."}</p>
<p>Notice the difference in the Version numbers.&nbsp; One is 1.0.0.0 (Windows Server AppFabric Cache) while the other is 101.0.0.0 (Windows Azure AppFabric Cache).&nbsp; The incompatibility derives from the combination of the configuration section in my app.config (shown below) that I need in order to utilize the Windows Server AppFabric Cache and my reference to the Windows Azure AppFabric Cache assemblies that I referenced earlier.</p>
<p>&nbsp;&nbsp;&nbsp; &lt;section name="dataCacheClient"&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="Microsoft.ApplicationServer.Caching.DataCacheClientSection,&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft.ApplicationServer.Caching.Core,&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="background-color: #ffff00;">Version=1.0.0.0</span>, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; allowLocation="true"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; allowDefinition="Everywhere"/&gt;</p>
<p>So the root problem is that I&rsquo;m trying to assign an instance of the <a href="https://msdn.microsoft.com/en-us/library/ee790816.aspx" target="_blank">DataCacheClientSection</a> from the Windows Azure AppFabric Cache assembly to an instance of the same type from the Windows Server AppFabric Cache assembly.&nbsp;</p>
<p>To correct the problem I need to reference the proper version of the assemblies.&nbsp; Depending on whether I&rsquo;m developing for 32-bit or 64-bit, I reference the assemblies from the following directories:</p>
<ul>
<li>32-bit systems - .\Windows\System32\AppFabric directory</li>
<li>64-bit systems - On 64-bit operating systems, the AppFabric directory will not be directly visible. To work around this problem, replace the System32 directory name with the name SysNative. This results in navigating to the C:\Windows\SysNative\AppFabric directory in this step</li>
</ul>
<p>Once the references are updated, the application runs without error.</p>]]></content:encoded>
    </item>
    <item>
      <title>Copying a TFS Build Definition</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/copying-a-tfs-build-definition</link>
      <pubDate>Tue, 06 Sep 2011 16:52:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2011/09/06/copying-a-tfs-build-definition/</guid>
      <description><![CDATA[I found myself in a situation recently where I needed the ability to copy a build definition in TFS...]]></description>
      <content:encoded><![CDATA[<p>I found myself in a situation recently where I needed the ability to copy a build definition in TFS on a fairly consistent basis.&nbsp; While this is a feature that has been requested before, unfortunately it hasn&rsquo;t yet made it into the product.&nbsp; So I thought I would see if I could create a Visual Studio extension that would provide this functionality in reasonably short order.</p>
<p>I started off researching how I might use the TFS API to perform the copy.&nbsp; Of course, I couldn&rsquo;t find much about how to create the copy, other than the various posts asking about or requesting this functionality.&nbsp; What I did find though was a <a href="https://geekswithblogs.net/jakob/archive/2010/04/26/creating-a-build-definition-using-the-tfs-2010-api.aspx" target="_blank">blog post</a> by Jakob Ehn on creating a build definition programmatically, which served as the basis for how I would perform the copy.</p>
<p>You start by getting a reference to the build server via a call to the <a href="https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.client.tfsteamprojectcollection.getservice.aspx" target="_blank">GetService</a> method on the <a href="https://msdn.microsoft.com/en-us/library/ff732550.aspx" target="_blank">TfsTeamProjectCollection</a> instance as shown in the code snippet below.&nbsp; Once we have the build server reference we can then load the build definition that we&rsquo;re making a copy of.&nbsp; The key to copying the build definition is making sure that you pick up all the original build attributes.&nbsp; That means iterating over all of the workspace mappings and process parameters, among the other build definition settings, as shown.&nbsp; Once we&rsquo;re done creating the copy, simply call Save() on the new build definition to commit the changes to TFS.</p>
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 825; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;" id="codeSnippetWrapper">
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum1"> 1:</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span> CopyBuildDefinition(<span style="color: #0000ff;">string</span> teamProject, <span style="color: #0000ff;">string</span> buildDefinitionName)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum2"> 2:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum3"> 3:</span>     <span style="color: #008000;">// Get a reference to the build service</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum4"> 4:</span>     IBuildServer buildServer = (IBuildServer)_tfsServer.GetService(<span style="color: #0000ff;">typeof</span>(IBuildServer));</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum5"> 5:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum6"> 6:</span>     <span style="color: #008000;">// Load the build definition to be copied</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum7"> 7:</span>     var buildDefinitionToCopy = buildServer.GetBuildDefinition(teamProject, buildDefinitionName);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum8"> 8:</span>     <span style="color: #0000ff;">if</span> (buildDefinitionToCopy != <span style="color: #0000ff;">null</span>)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum9"> 9:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum10"> 10:</span>         <span style="color: #008000;">// Copy General Info</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum11"> 11:</span>         var newBuildDefinition = buildServer.CreateBuildDefinition(teamProject);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum12"> 12:</span>         newBuildDefinition.Name = GetNewBuildName(buildServer, teamProject, buildDefinitionName);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum13"> 13:</span>         newBuildDefinition.Description = buildDefinitionToCopy.Description;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum14"> 14:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum15"> 15:</span>         <span style="color: #008000;">// Copy Triggers</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum16"> 16:</span>         newBuildDefinition.ContinuousIntegrationType = buildDefinitionToCopy.ContinuousIntegrationType;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum17"> 17:</span>         newBuildDefinition.ContinuousIntegrationQuietPeriod = buildDefinitionToCopy.ContinuousIntegrationQuietPeriod;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum18"> 18:</span>         newBuildDefinition.Schedules.AddRange(buildDefinitionToCopy.Schedules);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum19"> 19:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum20"> 20:</span>         <span style="color: #008000;">// Copy Workspace mappings</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum21"> 21:</span>         <span style="color: #0000ff;">foreach</span> (IWorkspaceMapping mapping <span style="color: #0000ff;">in</span> buildDefinitionToCopy.Workspace.Mappings)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum22"> 22:</span>         {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum23"> 23:</span>             newBuildDefinition.Workspace.AddMapping(mapping.ServerItem, mapping.LocalItem, mapping.MappingType, mapping.Depth);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum24"> 24:</span>         }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum25"> 25:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum26"> 26:</span>         <span style="color: #008000;">// Copy Build defaults</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum27"> 27:</span>         newBuildDefinition.BuildController = buildDefinitionToCopy.BuildController;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum28"> 28:</span>         newBuildDefinition.DefaultDropLocation = buildDefinitionToCopy.DefaultDropLocation;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum29"> 29:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum30"> 30:</span>         <span style="color: #008000;">// Copy Process parameters</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum31"> 31:</span>         newBuildDefinition.Process = buildDefinitionToCopy.Process;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum32"> 32:</span>         var processParams = WorkflowHelpers.DeserializeProcessParameters(buildDefinitionToCopy.ProcessParameters);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum33"> 33:</span>         var copyProcessParams = WorkflowHelpers.DeserializeProcessParameters(newBuildDefinition.ProcessParameters);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum34"> 34:</span>         <span style="color: #0000ff;">foreach</span> (KeyValuePair&lt;<span style="color: #0000ff;">string</span>, <span style="color: #0000ff;">object</span>&gt; entry <span style="color: #0000ff;">in</span> processParams)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum35"> 35:</span>         {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum36"> 36:</span>             copyProcessParams.Add(entry.Key.ToString(), entry.Value);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum37"> 37:</span>         }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum38"> 38:</span>         newBuildDefinition.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(copyProcessParams);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum39"> 39:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum40"> 40:</span>         <span style="color: #008000;">// Copy Retention policies</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum41"> 41:</span>         newBuildDefinition.RetentionPolicyList.Clear();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum42"> 42:</span>         newBuildDefinition.RetentionPolicyList.AddRange(buildDefinitionToCopy.RetentionPolicyList);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum43"> 43:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum44"> 44:</span>         <span style="color: #008000;">// Save copy</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum45"> 45:</span>         newBuildDefinition.Save();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum46"> 46:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum47"> 47:</span> }</pre>
<!--CRLF--></div>
</div>
<p>One of the tricks of creating the copy is coming up with a meaningful name for the new build definition.&nbsp; You&rsquo;ll see in the code snippet above at line 12 a call to GetNewBuildName().&nbsp; I decided to take an approach similar to how Visual Studio creates copies of files within a project.&nbsp; That is, I look at the name of the build definition being copied and create the new build definition with a name of &ldquo;Copy (<em>n</em>) of <em>buildDefinitionName</em>&rdquo;.&nbsp; The implementation of this&nbsp;approach is shown in the following code snippet.</p>
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 540px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;" id="codeSnippetWrapper">
<div style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;" id="codeSnippet">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum1"> 1:</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">string</span> GetNewBuildName(IBuildServer buildServer, <span style="color: #0000ff;">string</span> teamProject, <span style="color: #0000ff;">string</span> buildDefinitionName)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum2"> 2:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum3"> 3:</span>     <span style="color: #0000ff;">string</span> newBuildName = DEFAULT_PREFIX + buildDefinitionName;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum4"> 4:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum5"> 5:</span>     IBuildDefinitionSpec buildDefinitionSpec = buildServer.CreateBuildDefinitionSpec(teamProject);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum6"> 6:</span>     buildDefinitionSpec.Name = <span style="color: #006080;">"Copy*of "</span> + buildDefinitionName;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum7"> 7:</span>     IBuildDefinitionQueryResult results = buildServer.QueryBuildDefinitions(buildDefinitionSpec);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum8"> 8:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum9"> 9:</span>     <span style="color: #0000ff;">if</span> (results.Definitions.Length &gt;= 1)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum10"> 10:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum11"> 11:</span>         var buildNames = from buildDef <span style="color: #0000ff;">in</span> results.Definitions</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum12"> 12:</span>                          orderby buildDef.Name</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum13"> 13:</span>                          select buildDef.Name;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum14"> 14:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum15"> 15:</span>         <span style="color: #0000ff;">if</span> (buildNames.Contains(newBuildName))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum16"> 16:</span>         {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum17"> 17:</span>             <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> inx = 2; inx &lt; 50; inx++)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum18"> 18:</span>             {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum19"> 19:</span>                 newBuildName = String.Format(<span style="color: #006080;">"Copy ({0}) of {1}"</span>, inx, buildDefinitionName);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum20"> 20:</span>                 <span style="color: #0000ff;">if</span> ( !buildNames.Contains( newBuildName ) )</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum21"> 21:</span>                     <span style="color: #0000ff;">break</span>;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum22"> 22:</span>             }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum23"> 23:</span>         }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum24"> 24:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum25"> 25:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum26"> 26:</span>     <span style="color: #0000ff;">return</span> newBuildName;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span style="color: #606060;" id="lnum27"> 27:</span> }</pre>
<!--CRLF--></div>
</div>
<p>That&rsquo;s all there is to it.&nbsp; The completed Visual Studio extension is available for install from the Extension Manager in Visual Studio (search for "copy build" in the online gallery) or you can download it directly from the <a href="https://visualstudiogallery.msdn.microsoft.com/39a17bfd-d382-4580-a7e5-5a52eab6fbc1" target="_blank">Visual Studio Gallery</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Task Parallelism in .NET 4.0 (a practical example)</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/task-parallelism-in-net-4-0-a-practical-example</link>
      <pubDate>Tue, 31 May 2011 18:38:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2011/05/31/task-parallelism-in-net-4-0-a-practical-example/</guid>
      <description><![CDATA[I recently needed to develop some code that would read diagnostic information from a group of...]]></description>
      <content:encoded><![CDATA[<p>I recently needed to develop some code that would read diagnostic information from a group of servers for a production application.&nbsp; This included reading a count of event log entries, reading performance counter values and also performing database queries to retrieve exception log information for the application.&nbsp; The idea was to provide a high level snapshot of the overall health of the application so at a glance support personnel could see if any issues were arising with the application (yes, I know, some home grown health monitoring).</p>
<p>In order to make the data retrieval efficient I wanted to take as many of the readings in parallel as possible .&nbsp; Prior to .NET 4.0 I would have looked at using the ThreadPool for this functionality and queueing separate user work items for each request.&nbsp; With .NET 4.0 however we now have use of the <a target="_blank" href="https://msdn.microsoft.com/en-us/library/dd537609.aspx">Task Parallel Library (TPL)</a> which allows for more efficient use of system resources and also provides better programmatic control than is typically available when working directly with the thread pool.</p>
<p>In my particular scenario I have a group of servers that each have one or more of the above readings (event log count, performance counter or database query) that need to be retrieved.&nbsp; The result of each reading returns a similar output (numeric in this case &ndash; either integer or double).&nbsp; Since I want to execute these tasks in a concurrent manner, that&rsquo;s where the TPL and the new <a target="_blank" href="https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.aspx">Task</a> class come into play.&nbsp; The Task class allows me to easily execute an asynchronous operation and return a result.&nbsp; </p>
<p>In my case I effectively want the retrieval of each data reading to be executed as a separate Task.&nbsp; I can also have each task return a result by instantiating a Task&lt;TResult&gt; (see <a target="_blank" href="https://msdn.microsoft.com/en-us/library/dd537613.aspx">How to: Return a Value from a Task</a> for more details).&nbsp; I want each Task to return the value for the reading, along with the server name and reading name (this is used to group/correlate the readings after all tasks have executed, which I&rsquo;ll explain shortly).&nbsp; The output of each task is therefore defined by the DataResult class shown below.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060;">   1:</span> <span style="color: #008000;">/// &lt;summary&gt;</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060;">   2:</span> <span style="color: #008000;">/// Class used to return results from the executing thread (task)</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060;">   3:</span> <span style="color: #008000;">/// &lt;/summary&gt;</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060;">   4:</span> <span style="color: #0000ff;">class</span> DataResult</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060;">   5:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060;">   6:</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> ServerName { get; set; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060;">   7:</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">string</span> MeasureName { get; set; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060;">   8:</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">double</span> MeasureValue { get; set; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060;">   9:</span> }</pre>
<!--CRLF--></div>
</div>
<p>Since I know the number of tasks I need to execute based on my inputs (the number of servers and the number of readings) I simply create a array of tasks of type DataResult.&nbsp; I then iterate through the readings and servers, executing the appropriate method for each Task based on the type of reading being obtained.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 640px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060;">   1:</span> <span style="color: #008000;">// Create a separate task/thread for each measurement to be taken</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060;">   2:</span> Task&lt;DataResult&gt;[] tasks = <span style="color: #0000ff;">new</span> Task&lt;DataResult&gt;[measureList.Count() * serverList.Count()];</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060;">   3:</span> <span style="color: #0000ff;">int</span> inx = 0;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060;">   4:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060;">   5:</span> <span style="color: #008000;">// Retrieve the data</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060;">   6:</span> <span style="color: #0000ff;">foreach</span> (DataModel.Measure measure <span style="color: #0000ff;">in</span> measureList)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060;">   7:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060;">   8:</span>     DataReading reading = <span style="color: #0000ff;">new</span> DataReading();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060;">   9:</span>     reading.DisplayName = measure.DisplayName;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum10" style="color: #606060;">  10:</span>     reading.ServerValues = <span style="color: #0000ff;">new</span> Dictionary&lt;<span style="color: #0000ff;">string</span>, ServerValue&gt;();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum11" style="color: #606060;">  11:</span>     data.Readings.Add(reading);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum12" style="color: #606060;">  12:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum13" style="color: #606060;">  13:</span>     <span style="color: #0000ff;">foreach</span> (DataModel.Server server <span style="color: #0000ff;">in</span> serverList)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum14" style="color: #606060;">  14:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum15" style="color: #606060;">  15:</span>         ServerValue serverData = <span style="color: #0000ff;">new</span> ServerValue();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum16" style="color: #606060;">  16:</span>         serverData.ServerName = server.HostName;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum17" style="color: #606060;">  17:</span>         serverData.ServerType = server.ServerType.Type;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum18" style="color: #606060;">  18:</span>         serverData.ServerId = server.Id;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum19" style="color: #606060;">  19:</span>         reading.ServerValues.Add(serverData.ServerName, serverData);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum20" style="color: #606060;">  20:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum21" style="color: #606060;">  21:</span>         MeasureInfo measureInfo = <span style="color: #0000ff;">new</span> MeasureInfo(env, server, measure);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum22" style="color: #606060;">  22:</span>         <span style="color: #0000ff;">switch</span> (measure.Type)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum23" style="color: #606060;">  23:</span>         {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum24" style="color: #606060;">  24:</span>             <span style="color: #0000ff;">case</span> (<span style="color: #0000ff;">int</span>)MeasureTypes.PerfCounter:</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum25" style="color: #606060;">  25:</span>                 tasks[inx] = <span style="color: #0000ff;">new</span> Task&lt;DataResult&gt;(GetPerfCounterValue, measureInfo);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum26" style="color: #606060;">  26:</span>                 <span style="color: #0000ff;">break</span>;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum27" style="color: #606060;">  27:</span>             <span style="color: #0000ff;">case</span> (<span style="color: #0000ff;">int</span>)MeasureTypes.EventLog:</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum28" style="color: #606060;">  28:</span>                 tasks[inx] = <span style="color: #0000ff;">new</span> Task&lt;DataResult&gt;(GetLogEntries, measureInfo);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum29" style="color: #606060;">  29:</span>                 <span style="color: #0000ff;">break</span>;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum30" style="color: #606060;">  30:</span>             <span style="color: #0000ff;">case</span> (<span style="color: #0000ff;">int</span>)MeasureTypes.DBErrors:</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum31" style="color: #606060;">  31:</span>                 tasks[inx] = <span style="color: #0000ff;">new</span> Task&lt;DataResult&gt;(GetDbErrors, measureInfo);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum32" style="color: #606060;">  32:</span>                 <span style="color: #0000ff;">break</span>;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum33" style="color: #606060;">  33:</span>         }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum34" style="color: #606060;">  34:</span>         tasks[inx].Start();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum35" style="color: #606060;">  35:</span>         inx++;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum36" style="color: #606060;">  36:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum37" style="color: #606060;">  37:</span> }</pre>
<!--CRLF--></div>
</div>
<p>Of primary concern above is the looping construct and the switch statement that instantiates each Task instance with the appropriate method target depending on the type of reading.&nbsp; The other code is primarily concerned with passing the appropriate input to the target method and setting things up for the correlation.&nbsp; The target methods for each type of reading take the measureInfo as input, containing information on the data to be retrieved, and return an instance of the DataResult class.&nbsp; The methods for both the event log and performance counter operations are shown below.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 840px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060;">   1:</span> <span style="color: #0000ff;">private</span> DataResult GetLogEntries(<span style="color: #0000ff;">object</span> data)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060;">   2:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060;">   3:</span>     MeasureInfo measureInfo = data <span style="color: #0000ff;">as</span> MeasureInfo;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060;">   4:</span>     DataResult result = <span style="color: #0000ff;">new</span> DataResult()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060;">   5:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060;">   6:</span>         MeasureName = measureInfo.Measure.DisplayName,</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060;">   7:</span>         ServerName = GetServerName(measureInfo),</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060;">   8:</span>         MeasureValue = -1</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060;">   9:</span>     };</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum10" style="color: #606060;">  10:</span>     DateTime startTime = DateTime.Now;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum11" style="color: #606060;">  11:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum12" style="color: #606060;">  12:</span>     <span style="color: #0000ff;">string</span> dateTimeFilter = _queryTimeConstraint.ToString(<span style="color: #006080;">"yyyyMMddHHmmss.000000+000"</span>);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum13" style="color: #606060;">  13:</span>     measureInfo.Measure.Data = <span style="color: #0000ff;">string</span>.Format(measureInfo.Measure.Data, dateTimeFilter);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum14" style="color: #606060;">  14:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum15" style="color: #606060;">  15:</span>     ManagementObjectSearcher mos = <span style="color: #0000ff;">new</span> ManagementObjectSearcher(String.Format(<span style="color: #006080;">@"\\{0}\root\cimv2"</span>, measureInfo.Server.HostName), measureInfo.Measure.Data);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum16" style="color: #606060;">  16:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum17" style="color: #606060;">  17:</span>     result.MeasureValue = mos.Get().Count;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum18" style="color: #606060;">  18:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum19" style="color: #606060;">  19:</span>     <span style="color: #0000ff;">return</span> result;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum20" style="color: #606060;">  20:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum21" style="color: #606060;">  21:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum22" style="color: #606060;">  22:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum23" style="color: #606060;">  23:</span> <span style="color: #0000ff;">private</span> DataResult GetPerfCounterValue(<span style="color: #0000ff;">object</span> data)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum24" style="color: #606060;">  24:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum25" style="color: #606060;">  25:</span>     MeasureInfo measureInfo = data <span style="color: #0000ff;">as</span> MeasureInfo;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum26" style="color: #606060;">  26:</span>     DataResult result = <span style="color: #0000ff;">new</span> DataResult()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum27" style="color: #606060;">  27:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum28" style="color: #606060;">  28:</span>         MeasureName = measureInfo.Measure.DisplayName,</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum29" style="color: #606060;">  29:</span>         ServerName = GetServerName(measureInfo),</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum30" style="color: #606060;">  30:</span>         MeasureValue = -1</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum31" style="color: #606060;">  31:</span>     };</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum32" style="color: #606060;">  32:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum33" style="color: #606060;">  33:</span>     <span style="color: #0000ff;">string</span>[] perfInfo = measureInfo.Measure.Data.Split(<span style="color: #006080;">';'</span>);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum34" style="color: #606060;">  34:</span>     PerformanceCounter perfCounter = <span style="color: #0000ff;">new</span> System.Diagnostics.PerformanceCounter();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum35" style="color: #606060;">  35:</span>     perfCounter.CategoryName = perfInfo[0];</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum36" style="color: #606060;">  36:</span>     perfCounter.CounterName = perfInfo[1];</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum37" style="color: #606060;">  37:</span>     <span style="color: #0000ff;">if</span> (perfInfo.Length &gt; 2)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum38" style="color: #606060;">  38:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum39" style="color: #606060;">  39:</span>         perfCounter.InstanceName = perfInfo[2];</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum40" style="color: #606060;">  40:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum41" style="color: #606060;">  41:</span>     perfCounter.MachineName = measureInfo.Server.HostName;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum42" style="color: #606060;">  42:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum43" style="color: #606060;">  43:</span>     result.MeasureValue = perfCounter.NextValue();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum44" style="color: #606060;">  44:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum45" style="color: #606060;">  45:</span>     <span style="color: #0000ff;">return</span> result;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum46" style="color: #606060;">  46:</span> }</pre>
<!--CRLF--></div>
</div>
<p>The returned DataResult instance ends up in the task&rsquo;s Result property.&nbsp; Since I need to do some correlation once all the tasks have finished executing, I can simply do a <a target="_blank" href="https://msdn.microsoft.com/en-us/library/dd270695.aspx">Task.WaitAll</a> on the array of tasks (NOTE: Accessing the Result property on the task instance will also block the calling thread until the task finishes).&nbsp; Once they&rsquo;ve finished I can then loop through the tasks and perform my correlation using the Result property as shown.&nbsp; </p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 290px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060;">   1:</span> <span style="color: #008000;">// Wait for all tasks to complete and then copy the result to the appropriate reading</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060;">   2:</span> Task.WaitAll(tasks);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060;">   3:</span> <span style="color: #0000ff;">foreach</span> (Task&lt;DataResult&gt; task <span style="color: #0000ff;">in</span> tasks)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060;">   4:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060;">   5:</span>     DataReading result = data.Readings.Find(<span style="color: #0000ff;">delegate</span>(DataReading reading)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060;">   6:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060;">   7:</span>         <span style="color: #0000ff;">return</span> reading.DisplayName == task.Result.MeasureName;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060;">   8:</span>     });</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060;">   9:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum10" style="color: #606060;">  10:</span>     <span style="color: #0000ff;">if</span> (result != <span style="color: #0000ff;">null</span>)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum11" style="color: #606060;">  11:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum12" style="color: #606060;">  12:</span>         ServerValue serverValue = result.ServerValues[task.Result.ServerName];</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum13" style="color: #606060;">  13:</span>         serverValue.Value = task.Result.MeasureValue;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum14" style="color: #606060;">  14:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum15" style="color: #606060;">  15:</span> }</pre>
<!--CRLF--></div>
</div>
<p>That&rsquo;s it.&nbsp; Multi-threaded functionality added to my app with only a few lines of code and much greater programmatic control by using Tasks, especially the ability to return a complex data type as the result of the execution of each task.&nbsp; This example just scratches the surface of the TPL and using it for Task Parallelism.&nbsp; For additional topics please see <a target="_blank" href="https://msdn.microsoft.com/en-us/library/dd460693.aspx">Parallel Programming in the .NET Framework</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>A UI Wrapper for TFS Rollback Using a Visual Studio Package</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/a-ui-wrapper-for-tfs-rollback-using-a-visual-studio-package</link>
      <pubDate>Sun, 24 Apr 2011 18:24:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2011/04/24/a-ui-wrapper-for-tfs-rollback-using-a-visual-studio-package/</guid>
      <description><![CDATA[&nbsp;I&rsquo;ve been using Team Foundation Server since the initial release of TFS 2005.&nbsp; TFS...]]></description>
      <content:encoded><![CDATA[<p>&nbsp;I&rsquo;ve been using Team Foundation Server since the initial release of TFS 2005.&nbsp; TFS provides a great set of tools that make the process of Application Lifecycle Management much easier.&nbsp; However, one piece of functionality that was initially non-existent and still cumbersome to use at best is the process of rolling back a changeset in TFS version control.&nbsp; </p>
<p>Rollback functionality was initially provided via a separate install of the Team Foundation Power Tools.&nbsp; With the release of TFS 2010, rollback functionality is now available out of the box as an operation of the tf.exe command line tool.&nbsp; In both cases though the functionality is performed via the command line and requires that you enter a version control path, changeset number and possibly a local file path (in the case of TFS 2008) as arguments.&nbsp; If you&rsquo;ve had to perform more than a couple of rollbacks using this approach, you know it is very clumsy and obviously prone to error.&nbsp; </p>
<p>Wouldn&rsquo;t it be nice if we had a user interface for performing rollbacks that was integrated directly with the Visual Studio IDE?&nbsp; The UI would allow you to easily browse TFS for the version control path and changeset, thereby making the entire process a little more straightforward.&nbsp; Well, that&rsquo;s what I&rsquo;ve attempted to do with the result of this post.&nbsp; I wanted to build something that integrated directly into Visual Studio 2010, so the natural result was to create an extension for Visual Studio via a <a target="_blank" href="https://msdn.microsoft.com/en-us/library/bb166424.aspx">Visual Studio Package</a> provided with the <a target="_blank" href="https://www.microsoft.com/downloads/en/details.aspx?FamilyID=47305cf4-2bea-43c0-91cd-1b853602dcc5&amp;displaylang=en">Visual Studio 2010 SDK</a>.&nbsp; </p>
<p>Before we delve into the extension, let me start by saying that my objective is not to re-write the rollback functionality provided by the command line utilities.&nbsp; The folks in the product group have provided a tool that does that job quite adequately and I&rsquo;m certain is not trivial in nature to implement.&nbsp; My goal is simply to provide a UI wrapper around the rollback functionality and make things a little more user friendly in the process.</p>
<p>Now let&rsquo;s get into the details of the extension.&nbsp; The output of any Visual Studio Package project is a VSIX file which you can run to install the package and make it available in Visual Studio 2010 (NOTE: If Visual Studio 2010 is running during the install you&rsquo;ll need to restart it to see the changes).&nbsp; Installation of the TFS Rollback VSIX will add a new option to the Tools menu as shown.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/6177.image_0C84E7C2.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/6177.image_5F00_0C84E7C2.png"><img height="112" width="521" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/5100.image_thumb_70FFE5BE.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/5100.image_5F00_thumb_5F00_70FFE5BE.png" alt="image" border="0" title="image" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a> </p>
<p>Executing the TFS Rollback option from the Tools menu will display the primary dialog window for the rollback operation as shown in the following screen shot.&nbsp;&nbsp; </p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/3365.image_3AAEBDAF.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/3365.image_5F00_3AAEBDAF.png"><img height="276" width="526" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/1234.image_thumb_4EC7DA38.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/1234.image_5F00_thumb_5F00_4EC7DA38.png" alt="image" border="0" title="image" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a> </p>
<p>As you can see, the UI is pretty straight forward.&nbsp; Before you can browse for a version control path and changeset, you must first you provide a URL for your TFS server and click the Connect button.&nbsp; Once you are connected to the TFS Server, the status bar will indicate the URL of the server you are currently connected to.&nbsp; At this point you can now browse for the Server Path and the corresponding changeset that you want to rollback as shown below. </p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/7266.image_5FCC081B.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/7266.image_5F00_5FCC081B.png"><img height="309" width="479" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/3060.image_thumb_05C1B872.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/3060.image_5F00_thumb_5F00_05C1B872.png" alt="image" border="0" title="image" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a> </p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/8662.image_2B4B35D3.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/8662.image_5F00_2B4B35D3.png"><img height="290" width="481" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/2804.image_thumb_23539371.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/2804.image_5F00_thumb_5F00_23539371.png" alt="image" border="0" title="image" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a> </p>
<p>While tf.exe will allow you to specify multiple changesets for rollback only a single changeset is currently supported by the extension.</p>
<p>You&rsquo;ll also note from the main dialog that a workspace name must be provided to perform the rollback.&nbsp; Specifying a temporary workspace is more of a legacy requirement for working with TFS 2008 where you needed to download the entire source tree for the selected Server Path in order to perform the rollback.&nbsp; While this is no longer required with TFS 2010, the process of using a temporary workspace mapping still seems like the right approach, so the same method is applied.&nbsp; The temporary workspace name is mapped to the local path that you specify and then the source files are downloaded to this temporary workspace in order to perform the rollback.&nbsp; Then once you indicate that the rollback is complete (e.g. you&rsquo;ve checked in the corresponding changes) the temporary workspace and corresponding source files are removed from your local machine.</p>
<p>So once you&rsquo;ve provided all the necessary inputs to perform the rollback, simply click the Submit button to kick off the rollback.&nbsp; This will make all the necessary calls via TFS&rsquo;s <a target="_blank" href="https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.versioncontrolserver.aspx">VersionControlServer</a> class in order to set up the workspace and create the mapping (by the way, this is the same class that is used for browsing the source control tree and&nbsp; for querying for the changeset).&nbsp; Once the workspace and the associated mapping are established, the Process class is used to execute the command line utility as shown below. </p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 500px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span> PerformRollback()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060">   2:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #0000ff">int</span> exitCode = 0;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060">   4:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060">   5:</span>     Process tfProcess = <span style="color: #0000ff">new</span> Process();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060">   6:</span>     tfProcess.StartInfo.UseShellExecute = <span style="color: #0000ff">false</span>;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060">   7:</span>     tfProcess.StartInfo.WorkingDirectory = _localPath;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060">   8:</span>     tfProcess.StartInfo.FileName = CommandPath;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060">   9:</span>     tfProcess.StartInfo.Arguments = String.Format(<span style="color: #006080">"rollback /changeset:{0}~{0} \"{1}\" {2}"</span>,</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum10" style="color: #606060">  10:</span>                                                   _changeSet,</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum11" style="color: #606060">  11:</span>                                                   _serverPath,</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum12" style="color: #606060">  12:</span>                                                   (_recursive == <span style="color: #0000ff">true</span>) ? <span style="color: #006080">"/recursive"</span> : <span style="color: #0000ff">string</span>.Empty);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum13" style="color: #606060">  13:</span>     tfProcess.Start();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum14" style="color: #606060">  14:</span>     tfProcess.WaitForExit();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum15" style="color: #606060">  15:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum16" style="color: #606060">  16:</span>     exitCode = tfProcess.ExitCode;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum17" style="color: #606060">  17:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum18" style="color: #606060">  18:</span>     <span style="color: #0000ff">return</span> exitCode;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum19" style="color: #606060">  19:</span> }</pre>
<!--CRLF--></div>
</div>
<p>As mentioned above, since the rollback is creating pending changes in the temporary workspace, you need to indicate when the operation is complete so that the package knows when to perform its cleanup tasks (e.g. removing the temporary workspace and files).&nbsp;&nbsp; So once the Process instance for the rollback operation completes, you&rsquo;ll see the following dialog indicating that further action is required on your part to complete the rollback.&nbsp; At this point you should either check in the pending changes from the rollback operation or undo those changes if you decide the changes should not be committed.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/2311.image_7AD4B15C.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/2311.image_5F00_7AD4B15C.png"><img height="276" width="407" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/3377.image_thumb_67B384B0.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/3377.image_5F00_thumb_5F00_67B384B0.png" alt="image" border="0" title="image" style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" /></a> </p>
<p>If you elect not to check in the changes you can choose to undo the pending changes manually.&nbsp; Otherwise, when the extension attempts to remove the workspace it will check for any pending changes.&nbsp; If any pending changes are found it will prompt you as to whether or not you want to delete the temporary workspace (thereby undoing the changes).&nbsp; If you elect not to delete the temporary workspace in this scenario then your pending changes will be preserved locally.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/4035.image_05B192A5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/4035.image_5F00_05B192A5.png"><img height="166" width="426" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/metablogapi/7103.image_thumb_0F968410.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38-metablogapi/7103.image_5F00_thumb_5F00_0F968410.png" alt="image" border="0" title="image" 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" /></a></p>
<p>I won&rsquo;t go into all the details around writing the VS Package.&nbsp; The package is responsible for creating the new menu command that gets added to the Tools menu.&nbsp; The event handler for the menu command is then responsible for launching the main dialog which is implemented as a WPF window.&nbsp; The main dialog and the browsing dialogs then make the necessary calls through the TFS version control API to browse the version control folders, etc.&nbsp; There is a <a target="_blank" href="https://msdn.microsoft.com/en-us/library/bb164725.aspx">detailed walkthrough on MSDN</a> that discusses creating a menu command using the VSPackage template.</p>
<p>One interesting item of note with respect to the implementation is maintaining the user&rsquo;s settings.&nbsp; First of all, I anticipate that the end user will re-use the same values for the TFS URL, the local path used for the temporary workspace and the temporary workspace name.&nbsp; The extension will also look for tf.exe in the default installation path (C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE) and if not found will prompt the user for the path to the executable.&nbsp; Rather than have the user re-enter the values every time they launch the extension, you can use the <a target="_blank" href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.settings.shellsettingsmanager.aspx">ShellSettingsManager</a> to create a collection of user settings that can be persisted.&nbsp; The retrieval of these settings is also performed in the event handler for the menu command as shown.&nbsp; The user&rsquo;s settings are saved in the Closing event handler for the rollback window.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 800px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060">   1:</span> WritableSettingsStore userSettingsStore = <span style="color: #0000ff">null</span>;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060">   2:</span> TfsRollback.MainWindow rollbackWindow;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060">   3:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060">   4:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> MenuItemCallback(<span style="color: #0000ff">object</span> sender, EventArgs e)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060">   5:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060">   6:</span>     SettingsManager settingsManager = <span style="color: #0000ff">new</span> ShellSettingsManager(<span style="color: #0000ff">this</span>);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060">   7:</span>     userSettingsStore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060">   8:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060">   9:</span>     rollbackWindow = <span style="color: #0000ff">new</span> TfsRollback.MainWindow();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum10" style="color: #606060">  10:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum11" style="color: #606060">  11:</span>     <span style="color: #008000">// Get any saved settings</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum12" style="color: #606060">  12:</span>     <span style="color: #0000ff">if</span> (userSettingsStore.CollectionExists(SettingsName))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum13" style="color: #606060">  13:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum14" style="color: #606060">  14:</span>         <span style="color: #0000ff">if</span> (userSettingsStore.PropertyExists(SettingsName, TfsUrlPropertyName))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum15" style="color: #606060">  15:</span>             rollbackWindow.TfsUrl = userSettingsStore.GetString(SettingsName, TfsUrlPropertyName);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum16" style="color: #606060">  16:</span>         <span style="color: #0000ff">if</span> (userSettingsStore.PropertyExists(SettingsName, WorkspacePropertyName))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum17" style="color: #606060">  17:</span>             rollbackWindow.WorkspaceName = userSettingsStore.GetString(SettingsName, WorkspacePropertyName);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum18" style="color: #606060">  18:</span>         <span style="color: #0000ff">if</span> (userSettingsStore.PropertyExists(SettingsName, LocalPathPropertyName))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum19" style="color: #606060">  19:</span>             rollbackWindow.LocalPath = userSettingsStore.GetString(SettingsName, LocalPathPropertyName);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum20" style="color: #606060">  20:</span>         <span style="color: #0000ff">if</span> (userSettingsStore.PropertyExists(SettingsName, CommandPathPropertyName))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum21" style="color: #606060">  21:</span>             rollbackWindow.CommandPath = userSettingsStore.GetString(SettingsName, CommandPathPropertyName);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum22" style="color: #606060">  22:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum23" style="color: #606060">  23:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum24" style="color: #606060">  24:</span>     <span style="color: #008000">// Show the rollback dialog</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum25" style="color: #606060">  25:</span>     rollbackWindow.Closing += <span style="color: #0000ff">new</span> System.ComponentModel.CancelEventHandler(rollbackWindow_Closing);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum26" style="color: #606060">  26:</span>     rollbackWindow.Show();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum27" style="color: #606060">  27:</span> }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum28" style="color: #606060">  28:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum29" style="color: #606060">  29:</span> <span style="color: #0000ff">void</span> rollbackWindow_Closing(<span style="color: #0000ff">object</span> sender, System.ComponentModel.CancelEventArgs e)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum30" style="color: #606060">  30:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum31" style="color: #606060">  31:</span>     <span style="color: #008000">// Save any settings</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum32" style="color: #606060">  32:</span>     <span style="color: #0000ff">if</span> (userSettingsStore.CollectionExists(SettingsName) == <span style="color: #0000ff">false</span>)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum33" style="color: #606060">  33:</span>         userSettingsStore.CreateCollection(SettingsName);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum34" style="color: #606060">  34:</span>     <span style="color: #0000ff">if</span> (!String.IsNullOrEmpty(rollbackWindow.TfsUrl))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum35" style="color: #606060">  35:</span>         userSettingsStore.SetString(SettingsName, TfsUrlPropertyName, rollbackWindow.TfsUrl);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum36" style="color: #606060">  36:</span>     <span style="color: #0000ff">if</span> (!String.IsNullOrEmpty(rollbackWindow.WorkspaceName))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum37" style="color: #606060">  37:</span>         userSettingsStore.SetString(SettingsName, WorkspacePropertyName, rollbackWindow.WorkspaceName);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum38" style="color: #606060">  38:</span>     <span style="color: #0000ff">if</span> (!String.IsNullOrEmpty(rollbackWindow.LocalPath))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum39" style="color: #606060">  39:</span>         userSettingsStore.SetString(SettingsName, LocalPathPropertyName, rollbackWindow.LocalPath);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum40" style="color: #606060">  40:</span>     <span style="color: #0000ff">if</span> (!String.IsNullOrEmpty(rollbackWindow.CommandPath))</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum41" style="color: #606060">  41:</span>         userSettingsStore.SetString(SettingsName, CommandPathPropertyName, rollbackWindow.CommandPath);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum42" style="color: #606060">  42:</span> }</pre>
<!--CRLF--></div>
</div>
<p>One additional feature that I might look to add in a subsequent release would be providing connectivity to TFS 2008.&nbsp; I&rsquo;ve run into scenarios where customers have upgraded to Visual Studio 2010, but their TFS installation is still running on 2008.&nbsp; I&rsquo;d expect those situations won&rsquo;t last much longer, but if you have interest in the extension supporting this scenario let me know. </p>
<p>You can install the extension by downloading it from the <a target="_blank" href="https://visualstudiogallery.msdn.microsoft.com/2f3bb953-69d2-4419-8203-12868bea49a9" title="Visual Studio Gallery">Visual Studio Gallery</a> or by installing it from <a target="_blank" href="https://msdn.microsoft.com/en-us/library/dd293639.aspx">Extension Manager</a> in Visual Studio.</p>]]></content:encoded>
    </item>
    <item>
      <title>Creating a Custom Base Page for Windows Phone 7</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/creating-a-custom-base-page-for-windows-phone-7</link>
      <pubDate>Thu, 03 Mar 2011 17:36:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2011/03/03/creating-a-custom-base-page-for-windows-phone-7/</guid>
      <description><![CDATA[When I first starting creating applications for Windows Phone 7, I noticed there was certain...]]></description>
      <content:encoded><![CDATA[<p>When I first starting creating applications for Windows Phone 7, I noticed there was certain functionality that I was duplicating across my pages.&nbsp; Just like I do with ASP.Net applications, my immediate thought was to create a custom base page, derived from <a target="_blank" href="https://msdn.microsoft.com/en-us/library/microsoft.phone.controls.phoneapplicationpage(v=VS.92).aspx">PhoneApplicationPage</a>, that all my pages would then inherit from.&nbsp; Being fairly new to Windows Phone 7 development, and Silverlight development in general, it wasn&rsquo;t readily apparent to me how to do this, but it turns out to be fairly straightforward.</p>
<p>To begin with I&rsquo;ll obviously need a new base class similar to that shown below.</p>
<div id="codeSnippetWrapper">
<div class="csharpcode" id="codeSnippet">
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; height: 77px; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> BasePage : PhoneApplicationPage</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060">   2:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #008000">// BasePage implementation goes here...</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060">   4:</span> }</pre>
<!--CRLF--></div>
</div>
</div>
<!--CRLF--></div>
<p>&nbsp;With the BasePage class in place, we can then derive our individual pages from this class, similar to the following code for MainPage:</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">partial</span> <span style="color: #0000ff">class</span> MainPage : BasePage</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060">   2:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #008000">// Constructor</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060">   4:</span>     <span style="color: #0000ff">public</span> MainPage()</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060">   5:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060">   6:</span>         InitializeComponent();</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060">   7:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060">   8:</span> }</pre>
<!--CRLF--></div>
</div>
<p>In order to make this work, we also need to update the corresponding XAML file to reference the new base class.&nbsp; This requires that we import our local namespace as well.&nbsp; Line 9 in the next code snippet shows the namespace reference while lines 1 and 19 show the open/close tag used to reference the new BasePage class.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; height: 324px; max-height: 400px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060">   1:</span> &lt;local:BasePage </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060">   2:</span>     x:Class=<span style="color: #006080">"Wp7CustomBasePage.Views.MainPage"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060">   3:</span>     xmlns=<span style="color: #006080">"https://schemas.microsoft.com/winfx/2006/xaml/presentation"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060">   4:</span>     xmlns:x=<span style="color: #006080">"https://schemas.microsoft.com/winfx/2006/xaml"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060">   5:</span>     xmlns:phone=<span style="color: #006080">"clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060">   6:</span>     xmlns:shell=<span style="color: #006080">"clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060">   7:</span>     xmlns:d=<span style="color: #006080">"https://schemas.microsoft.com/expression/blend/2008"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060">   8:</span>     xmlns:mc=<span style="color: #006080">"https://schemas.openxmlformats.org/markup-compatibility/2006"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060">   9:</span>     xmlns:local=<span style="color: #006080">"clr-namespace:Wp7CustomBasePage.Views"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum10" style="color: #606060">  10:</span>     mc:Ignorable=<span style="color: #006080">"d"</span> d:DesignWidth=<span style="color: #006080">"480"</span> d:DesignHeight=<span style="color: #006080">"768"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum11" style="color: #606060">  11:</span>     FontFamily=<span style="color: #006080">"{StaticResource PhoneFontFamilyNormal}"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum12" style="color: #606060">  12:</span>     FontSize=<span style="color: #006080">"{StaticResource PhoneFontSizeNormal}"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum13" style="color: #606060">  13:</span>     Foreground=<span style="color: #006080">"{StaticResource PhoneForegroundBrush}"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum14" style="color: #606060">  14:</span>     SupportedOrientations=<span style="color: #006080">"Portrait"</span> Orientation=<span style="color: #006080">"Portrait"</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum15" style="color: #606060">  15:</span>     shell:SystemTray.IsVisible=<span style="color: #006080">"True"</span>&gt;</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum16" style="color: #606060">  16:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum17" style="color: #606060">  17:</span>     <span style="color: #008000;">&lt;!-- Content of page omitted for clarity --&gt;</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum18" style="color: #606060">  18:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum19" style="color: #606060">  19:</span> &lt;/local:BasePage&gt;</pre>
<!--CRLF--></div>
</div>
<p>That&rsquo;s effectively all there is to it.</p>
<p>So what kind of functionality would you want in your base page?&nbsp; I find that I typically add functionality related to navigation, messaging and state management.&nbsp; When I refer to messaging I&rsquo;m referring to the concept of sending notifications from the ViewModel back to the View.&nbsp; This of course assumes that you are using MVVM in your applications.&nbsp; Messaging isn&rsquo;t directly supported in Silverlight for Windows Phone so I use the <a target="_blank" href="https://mvvmlight.codeplex.com/">MVVM Light Toolkit</a> for this purpose.&nbsp; If you&rsquo;re new to MVVM John Papa has a <a target="_blank" href="https://johnpapa.net/silverlight/5-minute-overview-of-mvvm-in-silverlight/">post</a> that provides a good overview.&nbsp; </p>
<p>So here&rsquo;s the base page after some of this functionality has been added.</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; height: 563px; max-height: 600px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> BasePage : PhoneApplicationPage</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum2" style="color: #606060">   2:</span> {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #008000">// Override OnNavigatedTo to register for messages from view model</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum4" style="color: #606060">   4:</span>     <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum5" style="color: #606060">   5:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum6" style="color: #606060">   6:</span>         <span style="color: #0000ff">base</span>.OnNavigatedTo(e);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum7" style="color: #606060">   7:</span>         Messenger.Default.Register&lt;<span style="color: #0000ff">string</span>&gt;(<span style="color: #0000ff">this</span>, <span style="color: #0000ff">this</span>.HandleMessage);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum8" style="color: #606060">   8:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum9" style="color: #606060">   9:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum10" style="color: #606060">  10:</span>     <span style="color: #008000">// Override OnNavigatedFrom to unregister for messages from view model</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum11" style="color: #606060">  11:</span>     <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum12" style="color: #606060">  12:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum13" style="color: #606060">  13:</span>         <span style="color: #0000ff">base</span>.OnNavigatedFrom(e);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum14" style="color: #606060">  14:</span>         Messenger.Default.Unregister(<span style="color: #0000ff">this</span>);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum15" style="color: #606060">  15:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum16" style="color: #606060">  16:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum17" style="color: #606060">  17:</span>     <span style="color: #008000">// Correctly cast derived Application class for accessing public variables</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum18" style="color: #606060">  18:</span>     <span style="color: #0000ff">public</span> Wp7CustomBasePage.App MyApp</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum19" style="color: #606060">  19:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum20" style="color: #606060">  20:</span>         get { <span style="color: #0000ff">return</span> (Wp7CustomBasePage.App)App.Current; }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum21" style="color: #606060">  21:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum22" style="color: #606060">  22:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum23" style="color: #606060">  23:</span>     <span style="color: #008000">// Handler to display messages sent from ViewModel</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum24" style="color: #606060">  24:</span>     <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> HandleMessage(<span style="color: #0000ff">string</span> message)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum25" style="color: #606060">  25:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum26" style="color: #606060">  26:</span>         MessageBox.Show(message, <span style="color: #006080">"CAPTION"</span>, MessageBoxButton.OK);</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum27" style="color: #606060">  27:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum28" style="color: #606060">  28:</span>&nbsp; </pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum29" style="color: #606060">  29:</span>     <span style="color: #008000">// Navigate to a specific view</span></pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum30" style="color: #606060">  30:</span>     <span style="color: #0000ff">protected</span> <span style="color: #0000ff">void</span> NavigateToView(<span style="color: #0000ff">string</span> viewName)</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum31" style="color: #606060">  31:</span>     {</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum32" style="color: #606060">  32:</span>         NavigationService.Navigate(<span style="color: #0000ff">new</span> Uri(String.Format(<span style="color: #006080">"/Views/{0}.xaml"</span>, viewName), UriKind.Relative));</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum33" style="color: #606060">  33:</span>     }</pre>
<!--CRLF-->
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum34" style="color: #606060">  34:</span> }</pre>
<!--CRLF--></div>
</div>
<p>With respect to the messaging discussion above, you&rsquo;ll notice this is handled in the OnNavigatedTo and OnNavigatedFrom overrides in BasePage.&nbsp; In OnNavigatedTo the page registers to receive messages from the ViewModel and passes a common handler for processing the message.&nbsp; In this case, the handler displays a MessageBox.&nbsp; Similarly, every time the user navigates away from the page it unregisters in theOnNavigatedFrom method.&nbsp; Unregistering as you navigate away from the page avoids the problem of getting multiple messages if you had multiple pages instantiated that were simultaneously registered.&nbsp; Now when any of my ViewModels send a message using code similar to the following:</p>
<div id="codeSnippetWrapper" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; width: 97.5%; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; cursor: text; border: silver 1px solid; padding: 4px;">
<div id="codeSnippet" style="text-align: left; line-height: 12pt; background-color: #f4f4f4; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;">
<pre style="text-align: left; line-height: 12pt; background-color: #f4f4f4; margin: 0em; width: 100%; font-family: 'Courier New', courier, monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible; border-style: none; padding: 0px;"><span id="lnum1" style="color: #606060">   1:</span> Messenger.Default.Send&lt;<span style="color: #0000ff">string</span>&gt;(<span style="color: #006080">"Work Done in Page 1 View Model."</span>);</pre>
<!--CRLF--></div>
</div>
<p>Any of my pages will automatically display a message box showing the message.</p>
<p>The final sample code is included below. (Requires the <a href="https://developer.windowsphone.com/">Windows Phone Developer Tools</a> and <a target="_blank" href="https://mvvmlight.codeplex.com/">MVVM Light Toolkit</a>)</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/13/61/29/Wp7CustomBasePage.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-13-61-29/Wp7CustomBasePage.zip">Wp7CustomBasePage.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>JavaScript Lint Check-In Policy for TFS</title>
      <link>https://docs.microsoft.com/archive/blogs/jschaffe/javascript-lint-check-in-policy-for-tfs</link>
      <pubDate>Tue, 22 Feb 2011 16:58:00 GMT</pubDate>
      <dc:creator><![CDATA[James Schaffer]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/jschaffe/2011/02/22/javascript-lint-check-in-policy-for-tfs/</guid>
      <description><![CDATA[Most web applications contain custom Javascript files to perform any number of tasks within the...]]></description>
      <content:encoded><![CDATA[<p>Most web applications contain custom Javascript files to perform any number of tasks within the browser in order to provide an improved experience for the end user.&nbsp; Of course, our Javascript source files are just as prone to syntax errors as the code we write in C# of VB.Net.&nbsp; There are various tools, such as <a target="_blank" href="https://jslint.com/" title="JSLint">JSLint&nbsp;</a>and&nbsp;<a target="_blank" href="https://javascriptlint.com/" title="JavaScript Lint">JavaScript Lint</a>, that allow for syntax checking of JavaScript.&nbsp; However, it might also be beneficial to have this syntax checking&nbsp;functionality incorporated into Team Foundation Server&nbsp;in order to ensure that our JavaScript syntax is correct before it can be checked in.&nbsp; As such, this post discusses the creation of a custom TFS check-in policy that leverages JavaScript Lint to validate any Javascript source files that were added or modified as part of a pending changeset.</p>
<p>I won't go into the specifics on the creation of custom check-in policies for TFS&nbsp;as there is plenty of documentation on <a target="_blank" href="https://msdn.microsoft.com/en-us/library/bb668980.aspx" title="MSDN">MSDN </a>and elsewhere that covers the topic in detail.&nbsp; I will however cover the code for a couple of interesting aspects of the solution, the first of which is the need to specify the path to the JavaScript Lint executable.&nbsp;&nbsp;In order for the check-in policy to perform its work, it must&nbsp;have the JavaScript Lint executable specified&nbsp;as part of its configuration when it is installed.&nbsp; This is handled through an override to the <em>Edit</em> method of the policy.&nbsp; The override displays a custom Windows Form that allows you to browse to the appropriate path of the JavaScript Lint executable and then saves that value via a public property of the policy.&nbsp; This is shown in the following code snippet.</p>
<table frame="box" border="0" style="BORDER-BOTTOM: #000000 0px solid; BORDER-LEFT: #000000 0px solid; BACKGROUND-COLOR: #b9c0ba; BORDER-TOP: #000000 0px solid; BORDER-RIGHT: #000000 0px solid">
<tbody>
<tr>
<td>
<pre style="FONT-FAMILY: consolas"><pre style="FONT-FAMILY: consolas"><pre style="font-family: consolas;">[<span style="color: #2b91af;">Serializable</span>]<br /><span style="color: blue;">public</span>&nbsp;<span style="color: blue;">class</span>&nbsp;<span style="color: #2b91af;">CheckForJavascriptChangesPolicy</span>&nbsp;:&nbsp;<span style="color: #2b91af;">PolicyBase</span><br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  <span style="COLOR: blue">public</span>&nbsp;<span style="COLOR: blue">string</span>&nbsp;JsLintPath;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: blue">public</span>&nbsp;<span style="COLOR: blue">override</span>&nbsp;<span style="COLOR: blue">bool</span>&nbsp;Edit(<span style="COLOR: #2b91af">IPolicyEditArgs</span>&nbsp;policyEditArgs)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: #2b91af">GetPath</span>&nbsp;frm&nbsp;=&nbsp;<span style="COLOR: blue">new</span>&nbsp;<span style="COLOR: #2b91af">GetPath</span>();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frm.StartPosition&nbsp;=&nbsp;<span style="COLOR: #2b91af">FormStartPosition</span>.CenterParent;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: blue">if</span>&nbsp;(!<span style="COLOR: #2b91af">String</span>.IsNullOrEmpty(JsLintPath))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frm.SelectedPath&nbsp;=&nbsp;JsLintPath;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: blue">if</span>&nbsp;(frm.ShowDialog(policyEditArgs.Parent)&nbsp;==&nbsp;<span style="COLOR: #2b91af">DialogResult</span>.OK)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: blue">if</span>&nbsp;(!<span style="COLOR: #2b91af">String</span>.IsNullOrEmpty(frm.SelectedPath))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JsLintPath&nbsp;=&nbsp;frm.SelectedPath;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: blue">return</span>&nbsp;<span style="COLOR: blue">true</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="COLOR: blue">return</span>&nbsp;<span style="COLOR: blue">false</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</pre>
<pre style="font-family: consolas;"></pre>
<pre style="font-family: consolas;">        ......</pre>
<pre style="font-family: consolas;">}</pre>
</pre>
</pre>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Since the derived policy class is marked as Serializable the value of the JsLintPath property will be persisted and available when the policy is evaluated during check-in.&nbsp; </p>
<p>The other&nbsp;interesting piece of the custom policy is of course found in the override of the <em>Evaluate</em> method as shown below.</p>
<table frame="box" cellpadding="1" cellspacing="1" border="0" style="background-color: #b9c0ba; border: #10100f 0px solid;">
<tbody>
<tr>
<td>
<pre style="font-family: consolas;"><pre style="font-family: consolas;"><span style="color: blue;"><pre style="font-family: consolas;"><span style="color: blue;"><pre style="font-family: consolas;"><span style="color: blue;"><pre style="font-family: consolas;"><span style="color: blue;">public</span>&nbsp;<span style="color: blue;">override</span>&nbsp;<span style="color: #2b91af;">PolicyFailure</span>[]&nbsp;Evaluate()<br />{<br />&nbsp;&nbsp;<span style="color: blue;">bool</span>&nbsp;jsLintFound&nbsp;=&nbsp;<span style="color: blue;">false</span>;<br />&nbsp;&nbsp;<span style="color: #2b91af;">StringCollection</span>&nbsp;policyFailureMessages&nbsp;=&nbsp;<span style="color: blue;">new</span>&nbsp;<span style="color: #2b91af;">StringCollection</span>();<br /> <br />&nbsp;&nbsp;<span style="color: #2b91af;">PendingChange</span>[]&nbsp;changes&nbsp;=&nbsp;PendingCheckin.PendingChanges.CheckedPendingChanges;<br />&nbsp;&nbsp;<span style="color: blue;">foreach</span>&nbsp;(<span style="color: #2b91af;">PendingChange</span>&nbsp;pendingChange&nbsp;<span style="color: blue;">in</span>&nbsp;changes)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">if</span>&nbsp;((pendingChange.ChangeType.HasFlag(<span style="color: #2b91af;">ChangeType</span>.Add)&nbsp;||&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pendingChange.ChangeType.HasFlag(<span style="color: #2b91af;">ChangeType</span>.Edit))&nbsp;&amp;&amp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pendingChange.FileName.EndsWith(<span style="color: #a31515;">".js"</span>))<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">if</span>&nbsp;(jsLintFound&nbsp;||&nbsp;System.IO.<span style="color: #2b91af;">File</span>.Exists(JsLintPath))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jsLintFound&nbsp;=&nbsp;<span style="color: blue;">true</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2b91af;">Process</span>&nbsp;jslProcess&nbsp;=&nbsp;<span style="color: blue;">new</span>&nbsp;<span style="color: #2b91af;">Process</span>();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jslProcess.StartInfo.FileName&nbsp;=&nbsp;JsLintPath;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jslProcess.StartInfo.WindowStyle&nbsp;=&nbsp;<span style="color: #2b91af;">ProcessWindowStyle</span>.Hidden;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jslProcess.StartInfo.Arguments&nbsp;=&nbsp;<span style="color: #2b91af;">String</span>.Format(<span style="color: #a31515;">"-process&nbsp;\"{0}\""</span>,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pendingChange.LocalItem);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jslProcess.Start();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jslProcess.WaitForExit();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">if</span>&nbsp;(jslProcess.ExitCode&nbsp;!=&nbsp;0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;policyFailureMessages.Add(<span style="color: #2b91af;">String</span>.Format(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #a31515;">"Javascript&nbsp;Lint&nbsp;check&nbsp;failed&nbsp;for&nbsp;{0}"</span>,&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pendingChange.LocalItem));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;policyFailureMessages.Add(<span style="color: #a31515;">"Javascript&nbsp;Lint&nbsp;executable&nbsp;wasn't&nbsp;found."</span>);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">break</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;}<br /> <br />&nbsp;&nbsp;<span style="color: blue;">if</span>&nbsp;(policyFailureMessages.Count&nbsp;&gt;&nbsp;0)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">PolicyFailure</span>&gt;&nbsp;policyFailures&nbsp;=&nbsp;<span style="color: blue;">new</span>&nbsp;<span style="color: #2b91af;">List</span>&lt;<span style="color: #2b91af;">PolicyFailure</span>&gt;();<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">foreach</span>&nbsp;(<span style="color: blue;">string</span>&nbsp;message&nbsp;<span style="color: blue;">in</span>&nbsp;policyFailureMessages)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;policyFailures.Add(<span style="color: blue;">new</span>&nbsp;<span style="color: #2b91af;">PolicyFailure</span>(message,&nbsp;<span style="color: blue;">this</span>));<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">return</span>&nbsp;policyFailures.ToArray();<br />&nbsp;&nbsp;}<br />&nbsp;&nbsp;<span style="color: blue;">else</span><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: blue;">return</span>&nbsp;<span style="color: blue;">new</span>&nbsp;<span style="color: #2b91af;">PolicyFailure</span>[0];<br />}</pre>
</span></pre>
</span></pre>
</span></pre>
</pre>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>Here the code effectively enumerates each item in the changeset, looking for additions or modifications with an extension of *.js.&nbsp; If any are found, the JavaScript Lint command line is spun up as a separate process and run against the file.&nbsp; Javascript Lint will emit a return code value other than 0 if any syntax errors are found.&nbsp; If that is the case, then a new entry is added to the <a target="_blank" href="https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.policyfailure.aspx" title="PolicyFailure">PolicyFailure </a>array indicating that the check-in should not proceed.&nbsp; This results in output to the Pending Changes window in the Policy Warnings pane similar to the following:</p>
<p>&nbsp;<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/38/7853.Output.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-38/7853.Output.png" border="0" /></p>
<p>I've created a Visual Studio 2010&nbsp;extension that installs the custom policy if you are interested in trying it out.&nbsp; Of course you'll also need to download the JavaScript Lint executable.&nbsp; In order to install the policy just perform the following:</p>
<ol>
<li>Download and extract the *.vsix file from the provided zip.</li>
<li>Install the *.vsix by double clicking the file.<ol>
<li><strong><span style="color: #ff0000;">NOTE</span></strong>: If Visual Studio is open when you perform the install you may need to restart Visual Studio before you can continue with the next step.</li>
</ol></li>
<li>From Team Explorer, right click the project where you want to enable the policy and select <strong>Team Project Settings-&gt;Source Control...</strong> from the context menu.</li>
<li>From the <strong>Source Control Settings</strong> dialog select the <strong>Check-in Policy</strong> tab, click the <strong>Add...</strong> button, select the <strong>Check for Javascript Changes Policy</strong> and click <strong>OK</strong>.</li>
<li>Upon initially enabling the policy, supply the local path to the Javascript Lint executable (jsl.exe).</li>
</ol>
<p>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/12/82/85/JavascriptLintCheckinPolicy.vsix.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-12-82-85/JavascriptLintCheckinPolicy.vsix.zip">JavascriptLintCheckinPolicy.vsix.zip</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>