<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Chris Tacke</title>
    <link>http://blog.opennetcf.com/ctacke/</link>
    <description>Bringing Managed Code to the Embedded World</description>
    <copyright>Chris Tacke</copyright>
    <lastBuildDate>Wed, 04 Jun 2008 15:36:47 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.8.5223.2</generator>
    <managingEditor>ctacke@opennetcf.com</managingEditor>
    <webMaster>ctacke@opennetcf.com</webMaster>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=16a22596-0eb2-4f6d-8c43-e238e6d8bf1e</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,16a22596-0eb2-4f6d-8c43-e238e6d8bf1e.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,16a22596-0eb2-4f6d-8c43-e238e6d8bf1e.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=16a22596-0eb2-4f6d-8c43-e238e6d8bf1e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      We've been working for a couple months now at migrating some of our projects from
      our older <a href="http://www.sourcegear.com/vault/">SourceGear Vault</a> source code
      repository to Microsoft's <a href="http://msdn.microsoft.com/en-us/tfs2008/default.aspx">Team
      Foundation Server</a>.  I've been perfectly happy with Vault - it's a great,
      inexpensive code repository - but we wanted to start doing <a href="http://en.wikipedia.org/wiki/Test-driven_development">test
      driven design</a> and adding <a href="http://en.wikipedia.org/wiki/Continuous_integration">continuous
      integration</a> into the mix.  One would think that since that's what TFS is
      all about that this would be pretty simple, right?  Hardly.
   </p>
        <p>
      TFS may work out of the box for desktop developers, but when it comes to doing device
      work you quickly end up in a tar pit of problems, which is only compounded when you're
      new to TFS to begin with.  In my opinion a root of these problems is that the <a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx">Visual
      Studio</a> IDE is not using <a href="http://msdn.microsoft.com/en-us/library/ms164311.aspx">msbuild.exe</a> and <a href="http://msdn.microsoft.com/en-us/library/ms182489(VS.80).aspx">mstest.exe</a> for
      doing device project builds and tests.  This is evidenced by the fact that you
      can create a device project with unit tests and they all run just happily from the
      IDE, but if you open a command windows and use msbuild with your solution it fails
      miserably. 
   </p>
        <p>
      I consider this a major failure on the part of the <a href="http://blogs.msdn.com/vsdteam/">Visual
      Studio for Devices (VSD) team</a>.  You see TFS doesn't launch Studio to build
      your solution, it uses msbuild.  So to just get the solution to compile you have
      to learn how TFS works and make modifications.  Oh, and once it's compiling that
      certainly doesn't mean that unit tests will actually run.  We've hit several
      snags along the way on that too.
   </p>
        <p>
      Fortunately for us, I have a good friend and long-time colleague, <a href="http://forums.microsoft.com/MSDN/User/Profile.aspx?UserID=296899&amp;SiteID=1">Tim
      Bassett</a>, who is big into CI and TDD, has a lot of experience with TFS and
      is considering <a href="http://tfsadvantage.com/">hanging out his own shingle</a>. He
      just has no experience doing device development (well not really any since the days
      of eVB when we worked together).  So we formed a kind of symbiotic relationship
      with him <a href="http://tfsadvantage.com/blogs/tim/archive/2008/06/04/building-compact-framework-unit-tests-in-microsoft-team-foundation-server-with-team-foundation-build.aspx">helping
      us getting our server working</a> and running and us helping him develop <a href="http://ciontfs.com/content/THCF.aspx">some
      products</a> that will benefit any other hapless suckers who think that maybe automating
      builds and testing for device development might be useful.  If you're in that
      boat, take a look at what he's got. <a href="http://tfsadvantage.com/forums/">Ask
      him questions</a>.  Help him help us improve the experience of using TFS for
      device work. And if you ever have the ear of anyone on the VSD or CF team, tell them
      they should be dogfooding this stuff so they can feel our pain and that yes, unit
      tests for native code *is* necessary.
   </p>
        <p>
       
   </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=16a22596-0eb2-4f6d-8c43-e238e6d8bf1e" />
        <br />
        <hr />
   Managed Code in the Embedded World</body>
      <title>Theorem: CF + CI + TFS == PIA</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,16a22596-0eb2-4f6d-8c43-e238e6d8bf1e.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/06/04/TheoremCFCITFSPIA.aspx</link>
      <pubDate>Wed, 04 Jun 2008 15:36:47 GMT</pubDate>
      <description>&lt;p&gt;
   We've been working for a couple months now at migrating some of our projects from
   our older &lt;a href="http://www.sourcegear.com/vault/"&gt;SourceGear Vault&lt;/a&gt; source code
   repository to Microsoft's &lt;a href="http://msdn.microsoft.com/en-us/tfs2008/default.aspx"&gt;Team
   Foundation Server&lt;/a&gt;.&amp;nbsp; I've been perfectly happy with Vault - it's a great,
   inexpensive code repository - but we wanted to start doing &lt;a href="http://en.wikipedia.org/wiki/Test-driven_development"&gt;test
   driven design&lt;/a&gt; and adding &lt;a href="http://en.wikipedia.org/wiki/Continuous_integration"&gt;continuous
   integration&lt;/a&gt; into the mix.&amp;nbsp; One would think that since that's what TFS is
   all about that this would be pretty simple, right?&amp;nbsp; Hardly.
&lt;/p&gt;
&lt;p&gt;
   TFS may work out of the box for desktop developers, but when it comes to doing device
   work you quickly end up in a tar pit of problems, which is only compounded when you're
   new to TFS to begin with.&amp;nbsp; In my opinion a root of these problems is that the &lt;a href="http://msdn.microsoft.com/en-us/vstudio/default.aspx"&gt;Visual
   Studio&lt;/a&gt; IDE is not using &lt;a href="http://msdn.microsoft.com/en-us/library/ms164311.aspx"&gt;msbuild.exe&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/ms182489(VS.80).aspx"&gt;mstest.exe&lt;/a&gt; for
   doing device project builds and tests.&amp;nbsp; This is evidenced by the fact that you
   can create a device project with unit tests and they all run just happily from the
   IDE, but if you open a command windows and use msbuild with your solution it fails
   miserably. 
&lt;/p&gt;
&lt;p&gt;
   I consider this a major failure on the part of the &lt;a href="http://blogs.msdn.com/vsdteam/"&gt;Visual
   Studio for Devices (VSD) team&lt;/a&gt;.&amp;nbsp; You see TFS doesn't launch Studio to build
   your solution, it uses msbuild.&amp;nbsp; So to just get the solution to compile you have
   to learn how TFS works and make modifications.&amp;nbsp; Oh, and once it's compiling that
   certainly doesn't mean that unit tests will actually run.&amp;nbsp; We've hit several
   snags along the way on that too.
&lt;/p&gt;
&lt;p&gt;
   Fortunately for us, I have a good friend and long-time colleague, &lt;a href="http://forums.microsoft.com/MSDN/User/Profile.aspx?UserID=296899&amp;amp;SiteID=1"&gt;Tim
   Bassett&lt;/a&gt;,&amp;nbsp;who is big into CI and TDD, has a lot of experience with TFS and
   is considering &lt;a href="http://tfsadvantage.com/"&gt;hanging out his own shingle&lt;/a&gt;.&amp;nbsp;He
   just has no experience doing device development (well not really any since the days
   of eVB when we worked together).&amp;nbsp; So we formed a kind of symbiotic relationship
   with him &lt;a href="http://tfsadvantage.com/blogs/tim/archive/2008/06/04/building-compact-framework-unit-tests-in-microsoft-team-foundation-server-with-team-foundation-build.aspx"&gt;helping
   us getting our server working&lt;/a&gt; and running and us helping him develop &lt;a href="http://ciontfs.com/content/THCF.aspx"&gt;some
   products&lt;/a&gt; that will benefit any other hapless suckers who think that maybe automating
   builds and testing for device development might be useful.&amp;nbsp; If you're in that
   boat, take a look at what he's got. &lt;a href="http://tfsadvantage.com/forums/"&gt;Ask
   him questions&lt;/a&gt;.&amp;nbsp; Help him help us improve the experience of using TFS for
   device work. And if you ever have the ear of anyone on the VSD or CF team, tell them
   they should be dogfooding this stuff so they can feel our pain and that yes, unit
   tests for native code *is* necessary.
&lt;/p&gt;
&lt;p&gt;
   &amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=16a22596-0eb2-4f6d-8c43-e238e6d8bf1e" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <comments>http://blog.opennetcf.com/ctacke/CommentView,guid,16a22596-0eb2-4f6d-8c43-e238e6d8bf1e.aspx</comments>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=f550902d-5de2-4a82-82f9-542420cdf958</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,f550902d-5de2-4a82-82f9-542420cdf958.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,f550902d-5de2-4a82-82f9-542420cdf958.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=f550902d-5de2-4a82-82f9-542420cdf958</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      For some time now we've offered "support and maintenance" as an option when purchasing our
      flagship <a href="http://opennetcf.com/CompactFramework/Products/SmartDeviceFramework/tabid/65/Default.aspx">Smart
      Device Framework </a>product.  If I recall correctly, the price is something
      like $240 for a year.  In the entire time we've offered it I can probably count
      the number of sales of that option on one hand - it's way less than 1% of the people
      who bought the extensions.
   </p>
        <p>
      I had a call from a prospective customer asking about the feature and it clued me
      in to what most people's thought process is.  He asked "why should I buy maintenance
      for $240 when I can just buy each new version for $50.  It's less expensive to
      just re-buy."
   </p>
        <p>
      Ah, on the surface that may seem true, and like a good deal.  But here's the
      value in buying maintenance:
   </p>
        <p>
      Right now we're in the process of moving the SDF to Studio 2008.  In the process
      we're also moving to using Team Foundation Server as a back end and integrating unit
      testing and continuious integration.  In this process we're shaking out quite
      a few bugs (take a look at our <a href="http://bugzilla.opennetcf.com">online bug
      database</a> to see what we're up to).  People <u>with</u> maintenance agreements
      can request the source for these fixes at any time.  They also get source drops
      for all service packs (no one else does).  Those <u>without</u> maintenance must
      wait until the next release or service pack to take advantage of these fixes.
   </p>
        <p>
      There is one exception to this rule.  We feel that if you've gone through
      the task of finding it and reporting it, we owe you so if you are the first to find
      and report a bug, we'll provide you the fix immediately upon fixing it.  
   </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f550902d-5de2-4a82-82f9-542420cdf958" />
        <br />
        <hr />
   Managed Code in the Embedded World</body>
      <title>Why buy support for the SDF?</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,f550902d-5de2-4a82-82f9-542420cdf958.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/06/03/WhyBuySupportForTheSDF.aspx</link>
      <pubDate>Tue, 03 Jun 2008 16:48:33 GMT</pubDate>
      <description>&lt;p&gt;
   For some time now we've offered "support and maintenance" as an option when purchasing&amp;nbsp;our
   flagship&amp;nbsp;&lt;a href="http://opennetcf.com/CompactFramework/Products/SmartDeviceFramework/tabid/65/Default.aspx"&gt;Smart
   Device Framework &lt;/a&gt;product.&amp;nbsp; If I recall correctly, the price is something
   like $240 for a year.&amp;nbsp; In the entire time we've offered it I can probably count
   the number of sales of that option on one hand - it's way less than 1% of the people
   who bought the extensions.
&lt;/p&gt;
&lt;p&gt;
   I had a call from a prospective customer asking about the feature and it clued me
   in to what most people's thought process is.&amp;nbsp; He asked "why should I buy maintenance
   for $240 when I can just buy each new version for $50.&amp;nbsp; It's less expensive to
   just re-buy."
&lt;/p&gt;
&lt;p&gt;
   Ah, on the surface that may seem true, and like a good deal.&amp;nbsp; But here's the
   value in buying maintenance:
&lt;/p&gt;
&lt;p&gt;
   Right now we're in the process of moving the SDF to Studio 2008.&amp;nbsp; In the process
   we're also moving to using Team Foundation Server as a back end and integrating unit
   testing and continuious integration.&amp;nbsp; In this process we're shaking out quite
   a few bugs (take a look at our &lt;a href="http://bugzilla.opennetcf.com"&gt;online bug
   database&lt;/a&gt; to see what we're up to).&amp;nbsp; People &lt;u&gt;with&lt;/u&gt; maintenance agreements
   can request the source for these fixes at any time.&amp;nbsp; They also get source drops
   for all service packs (no one else does).&amp;nbsp; Those &lt;u&gt;without&lt;/u&gt; maintenance must
   wait until the next release or service pack to take advantage of these fixes.
&lt;/p&gt;
&lt;p&gt;
   There is&amp;nbsp;one exception to this rule.&amp;nbsp; We feel that if you've gone through
   the task of finding it and reporting it, we owe you so if you are the first to find
   and report a bug, we'll provide you the fix immediately upon fixing it.&amp;nbsp; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f550902d-5de2-4a82-82f9-542420cdf958" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <comments>http://blog.opennetcf.com/ctacke/CommentView,guid,f550902d-5de2-4a82-82f9-542420cdf958.aspx</comments>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=f938d733-5d31-4fcd-b55a-8f01b01a5853</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,f938d733-5d31-4fcd-b55a-8f01b01a5853.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,f938d733-5d31-4fcd-b55a-8f01b01a5853.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=f938d733-5d31-4fcd-b55a-8f01b01a5853</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      We're just about to release a new version of Padarn, out ASP.NET Web Server for Windows
      CE.  This version brings SSL support as well as Basic and Digest authentication. 
      Another part of this release was trying to keep the footprint reasonably small. 
      Here's a screen shot of all of the assemblies needed for the entire engine implementation:
   </p>
        <p>
          <img height="81" alt="padarnfootprint.PNG" src="http://blog.opennetcf.com/ctacke/content/binary/padarnfootprint.PNG" width="279" border="1" />
        </p>
        <p>
      So yes, we have an ASP.NET web server with SSL and authentication support and it's
      just 305KB - and half of that is for SSL alone.
   </p>
        <p>
       
   </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f938d733-5d31-4fcd-b55a-8f01b01a5853" />
        <br />
        <hr />
   Managed Code in the Embedded World</body>
      <title>Padarn's Footprint</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,f938d733-5d31-4fcd-b55a-8f01b01a5853.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/05/29/PadarnsFootprint.aspx</link>
      <pubDate>Thu, 29 May 2008 16:26:56 GMT</pubDate>
      <description>&lt;p&gt;
   We're just about to release a new version of Padarn, out ASP.NET Web Server for Windows
   CE.&amp;nbsp;&amp;nbsp;This version brings&amp;nbsp;SSL support as well as Basic and Digest authentication.&amp;nbsp;
   Another part of this release was trying to keep the footprint reasonably small.&amp;nbsp;
   Here's a screen shot of all of the assemblies needed for the entire engine implementation:
&lt;/p&gt;
&lt;p&gt;
   &lt;img height=81 alt=padarnfootprint.PNG src="http://blog.opennetcf.com/ctacke/content/binary/padarnfootprint.PNG" width=279 border=1&gt;
&lt;/p&gt;
&lt;p&gt;
   So yes, we have an ASP.NET web server with SSL and authentication support and it's
   just 305KB - and half of that is for SSL alone.
&lt;/p&gt;
&lt;p&gt;
   &amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=f938d733-5d31-4fcd-b55a-8f01b01a5853" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <comments>http://blog.opennetcf.com/ctacke/CommentView,guid,f938d733-5d31-4fcd-b55a-8f01b01a5853.aspx</comments>
      <category>OpenNETCF;Padarn</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=c3f1b45e-4801-4780-be17-e0e86867e6c4</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,c3f1b45e-4801-4780-be17-e0e86867e6c4.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,c3f1b45e-4801-4780-be17-e0e86867e6c4.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=c3f1b45e-4801-4780-be17-e0e86867e6c4</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <title>App.Config file with Smart Device Unit Tests</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,c3f1b45e-4801-4780-be17-e0e86867e6c4.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/05/28/AppConfigFileWithSmartDeviceUnitTests.aspx</link>
      <pubDate>Wed, 28 May 2008 16:46:42 GMT</pubDate>
      <description>&lt;span style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-themecolor: dark2"&gt; 
&lt;p&gt;
   Since the Compact Framework doesn't have support for App.Config file, we created our
   own implementation that follows the full framework model.&amp;nbsp; It requires that the
   config file be named “MyApp.exe.config” (which is how it works on the desktop) with
   a subset of the desktop functionality and it's worked well for some time.&amp;nbsp; Until
   recently that is.
&lt;/p&gt;
&lt;p&gt;
   Yesterday I set out to create some unit tests for some of our OpenNETCF.Rss namespace
   objects.&amp;nbsp; Well the FeedEngine object requires information from an app.config
   file on construction, so I figured it would be simple - I'd just add an app.config
   file to the test project and mark it as a DeploymentItem.&amp;nbsp; After a little investigation
   I found that the calling assembly for a device unit test is SmartDeviceTestHost.exe,
   which by default runs out of \Program Files\SmartDeviceTest on the target device.&amp;nbsp;
   That means that to use your own app config file from a unit test it would need to
   be named SmartDeviceTestHost.exe.config.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
   Interestingly (or frustratingly, depending on when you asked me yesterday), this test
   host deploys *its own* version of a config file with the same name with some info
   on what framework it’s running against.&amp;nbsp; The test framework just heavy-handedly
   overwrites any existing file rather than merging its contents into the existing one,
   and it overwrites *after* it deploys all of the test pieces, so you can’t just merge
   its contents into your own app config and use it.
&lt;/p&gt;
&lt;p&gt;
   As a workaround I actually modified the OpenNETCF implementation for app config files.&amp;nbsp;
   I didn't really want to, but the only other solution I could think of was to write
   code that would open the MS-deployed version and do a manual merge in the unit&amp;nbsp;
   test code before the test is run, and that seemed like a much uglier route. The OpenNETCF
   Configuration implementation now looks for a file named MyApp.exe.config.unittest
   before looking for MyApp.exe.config and uses the "unittest"-suffixed version if it’s
   there.&amp;nbsp; I then modified my TestBase class (from which all of my unit tests derive)
   to add this:
&lt;/p&gt;
&lt;/span&gt; 
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-themecolor: dark2"&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-themecolor: dark2"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;TestInitialize&lt;/span&gt;&lt;font color=#000000&gt;]&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;virtual&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;void&lt;/span&gt;&lt;font color=#000000&gt; TestInitialize()&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;CopyTestConfigFile();&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;
   &lt;o:p&gt;
      &lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;private&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;void&lt;/span&gt;&lt;font color=#000000&gt; CopyTestConfigFile()&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;//
   copy the config file to the test host folder&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color=#000000&gt; src
   = &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Path&lt;/span&gt;&lt;font color=#000000&gt;.Combine(TestContext.TestDeploymentDir, &lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"SmartDeviceTestHost.exe.config"&lt;/span&gt;&lt;font color=#000000&gt;);&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color=#000000&gt; dest
   = &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Path&lt;/span&gt;&lt;font color=#000000&gt;.Combine(TestHostFolder, &lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"SmartDeviceTestHost.exe.config.unittest"&lt;/span&gt;&lt;font color=#000000&gt;);&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;if&lt;/span&gt;&lt;font color=#000000&gt; ((&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;File&lt;/span&gt;&lt;font color=#000000&gt;.Exists(src))
   &amp;amp;&amp;amp; (!&lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;File&lt;/span&gt;&lt;font color=#000000&gt;.Exists(dest)))&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: #2b91af"&gt;File&lt;/span&gt;&lt;font color=#000000&gt;.Copy(src,
   dest);&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;
   &lt;o:p&gt;
      &lt;font color=#000000&gt;&amp;nbsp;&lt;/font&gt;
   &lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;&lt;font color=#000000&gt; TestHostFolder&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;get&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;span style="mso-spacerun: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;return&lt;/span&gt;&lt;font color=#000000&gt;&amp;nbsp; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Path&lt;/span&gt;&lt;font color=#000000&gt;.GetDirectoryName(&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Path&lt;/span&gt;&lt;font color=#000000&gt;.GetDirectoryName(&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Path&lt;/span&gt;&lt;font color=#000000&gt;.GetDirectoryName(&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;&lt;font color=#000000&gt;.GetCallingAssembly().GetName().CodeBase)));&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt; mso-layout-grid-align: none"&gt;
   &lt;span style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;&lt;font color=#000000&gt;&lt;span style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;o:p&gt;&lt;/o:p&gt;
   &lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
   &lt;span style="FONT-SIZE: 11pt; COLOR: #1f497d; FONT-FAMILY: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-themecolor: dark2"&gt;
   &lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   Now I simply add SmartDeviceTestHost.exe.config to the unit test project, mark it
   as a deployment item&amp;nbsp;and voila - it works as expected.&amp;nbsp; Just how it &lt;u&gt;should
   have&lt;/u&gt; yesterday morning&amp;nbsp;when I set out to write a couple simple tests.
&lt;/p&gt;
&lt;p&gt;
   And for the record - the current "solution" for debugging device unit tests (which
   involves putting in a Debugger.Break() call in the unit test and then doing an "attach
   to process" from another instance of Studio) is an unweildy pain in the ass.&amp;nbsp;
   It takes no less than a minute just te get a unit test running and in a state that
   you can step through code.&amp;nbsp; That might not sound like a lot, but try this: put
   a breakpoint in your code and when the debugger hit is, wait a full minute before
   you step or look at the Locals window.&amp;nbsp; Now do this every time you want to debug.
&lt;/p&gt;
&lt;p&gt;
   &amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=c3f1b45e-4801-4780-be17-e0e86867e6c4" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <comments>http://blog.opennetcf.com/ctacke/CommentView,guid,c3f1b45e-4801-4780-be17-e0e86867e6c4.aspx</comments>
      <category>.NET Compact Framework;CE Device Development;OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=9f9a5f01-0e64-4dcc-b6f5-dd5e81e48209</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,9f9a5f01-0e64-4dcc-b6f5-dd5e81e48209.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,9f9a5f01-0e64-4dcc-b6f5-dd5e81e48209.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=9f9a5f01-0e64-4dcc-b6f5-dd5e81e48209</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I don't use LINQ terribly often because it seems that most of the work I do is pre-CF
      3.5.  It only creeps into my code in things like unit tests or test projects.  
      <br /><br />
      This weekend I spent a little time updating my AudioTagR project and adding some tools
      and utilities to it.  One of the challenges I faced was let's assume I have two
      root directories that contain music files (they really can be any file, but this is
      a real-world example, so we'll use the exact scenario I had).  In each of these
      roots are folders for Artists.  In each of those are one or more folders that
      represent albums by that artist.<br /><br />
      Now let's assume one of those root folders (Root A) is my "root" music collection
      and it contains a few thousand artists.  The other root folder (Root B) is a
      collection of music off my old hard drives, CDs, etc.  I know that there are
      duplicates between these folders - artists that exist in both as well as albums that
      exist in both.  I want to go through Root B and move only those albums to Root
      A if they don't already exist.  That means that I want to move all albums that
      aren't already in Root A, creating the containing Artist folder if it's there. 
      If the folder is there, I want to skip it and I'll manually check the list of songs
      later.<br /><br />
      The traditional way to do this would be to write a recursive method that would look
      something like this pseudocode:<br /><br />
      void Parse(sourcefolder, destfolder)<br />
      {<br />
         foreach(directory in sourcefolder.directories)<br />
         {<br />
             if(! exists(destfolder[folder]))<br />
             {<br />
                Copy(sourcefolder, destfolder);<br />
             }<br />
             else<br />
             {<br />
                 Parse(directory, destfolder
      + directory);<br />
             }<br />
         }<br />
      }<br /><br />
      Well since this code really is nothing but a series of operations on a collection,
      LINQ immediately comes to mind as a good fit.<br /><br />
      The first challenge I ran into is that my algorithm requires a list of directories
      contained in a parent directory.  Unfortunately Directory.GetDirectories returns
      a list with the fully qualified path and I just needed the name of the folder itself. 
      So I wrote a couple of extension methods that get purely a list of the directory names,
      not the paths.  I also added one for checking to see if a directory was empty
      (to be used later for cleanliness):<br /><br /><br /></p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">class</span> IO<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> 
      public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">bool</span> IsEmptyDirectory(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> path)<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span>return</span> (Directory.GetDirectories(path).Count() <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">+</span> Directory.GetFiles(path).Count())
      == 0;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> FolderNameWithoutPath(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> path)<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span>return</span> Path.GetFileName(path);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
      GetFolderNamesWithoutPath(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">this</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> path)<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span>return</span> (from
      folder <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span> Directory.GetDirectories(path)<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span></span></span>select
      folder.FolderNameWithoutPath()).ToArray();<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>}<br />
      }<br /></span>
        </p>
        <p>
      Once I had those, the resulting merge method was a simple iteration across a couple
      LINQ queries.<br /><br /><span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> MergeFolders(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> sourceFolder, <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> destinationFolder)<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>//
      copy those in A but not in B</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>foreach</span>(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> folder <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span></span>sourceFolder.GetFolderNamesWithoutPath().Except(<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span></span>destinationFolder.GetFolderNamesWithoutPath(),
      StringComparer.InvariantCultureIgnoreCase))<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span>Directory.Move(Path.Combine(sourceFolder,
      folder), Path.Combine(destinationFolder, folder));<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>}<br /><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>//
      now go through those in both and repeat</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>foreach</span> (<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> folder <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">in</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span></span>sourceFolder.GetFolderNamesWithoutPath().Intersect(<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span></span>destinationFolder.GetFolderNamesWithoutPath(),
      StringComparer.InvariantCultureIgnoreCase))<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span>string</span> src <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> Path.Combine(sourceFolder,
      folder);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span>MergeFolders(src,
      Path.Combine(destinationFolder, folder));<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span>if</span> (src.IsEmptyDirectory())
      Directory.Delete(src);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span>}<br />
      }<br /></span></p>
        <p>
       
   </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=9f9a5f01-0e64-4dcc-b6f5-dd5e81e48209" />
        <br />
        <hr />
   Managed Code in the Embedded World</body>
      <title>The beauty of LINQ and extension methods</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,9f9a5f01-0e64-4dcc-b6f5-dd5e81e48209.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/05/27/TheBeautyOfLINQAndExtensionMethods.aspx</link>
      <pubDate>Tue, 27 May 2008 14:33:04 GMT</pubDate>
      <description>&lt;p&gt;
   I don't use LINQ terribly often because it seems that most of the work I do is pre-CF
   3.5.&amp;nbsp; It only creeps into my code in things like unit tests or test projects.&amp;nbsp; 
   &lt;br&gt;
   &lt;br&gt;
   This weekend I spent a little time updating my AudioTagR project and adding some tools
   and utilities to it.&amp;nbsp; One of the challenges I faced was let's assume I have two
   root directories that contain music files (they really can be any file, but this is
   a real-world example, so we'll use the exact scenario I had).&amp;nbsp; In each of these
   roots are folders for Artists.&amp;nbsp; In each of those are one or more folders that
   represent albums by that artist.&lt;br&gt;
   &lt;br&gt;
   Now let's assume one of those root folders (Root A) is my "root" music collection
   and it contains a few thousand artists.&amp;nbsp; The other root folder (Root B) is a
   collection of music off my old hard drives, CDs, etc.&amp;nbsp; I know that there are
   duplicates between these folders - artists that exist in both as well as albums that
   exist in both.&amp;nbsp; I want to go through Root B and move only those albums to Root
   A if they don't already exist.&amp;nbsp; That means that I want to move all albums that
   aren't already in Root A, creating the containing Artist folder if it's there.&amp;nbsp;
   If the folder is there, I want to skip it and I'll manually check the list of songs
   later.&lt;br&gt;
   &lt;br&gt;
   The traditional way to do this would be to write a recursive method that would look
   something like this pseudocode:&lt;br&gt;
   &lt;br&gt;
   void Parse(sourcefolder, destfolder)&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp;&amp;nbsp; foreach(directory in sourcefolder.directories)&lt;br&gt;
   &amp;nbsp;&amp;nbsp; {&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(! exists(destfolder[folder]))&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Copy(sourcefolder, destfolder);&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Parse(directory, destfolder
   + directory);&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
   &amp;nbsp;&amp;nbsp; }&lt;br&gt;
   }&lt;br&gt;
   &lt;br&gt;
   Well since this code really is nothing but a series of operations on a collection,
   LINQ immediately comes to mind as a good fit.&lt;br&gt;
   &lt;br&gt;
   The first challenge I ran into is that my algorithm requires a list of directories
   contained in a parent directory.&amp;nbsp; Unfortunately Directory.GetDirectories returns
   a list with the fully qualified path and I just needed the name of the folder itself.&amp;nbsp;
   So I wrote a couple of extension methods that get purely a list of the directory names,
   not the paths.&amp;nbsp; I also added one for checking to see if a directory was empty
   (to be used later for cleanliness):&lt;br&gt;
   &lt;br&gt;
   &lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;class&lt;/span&gt; IO&lt;br&gt;
   {&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
   public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;bool&lt;/span&gt; IsEmptyDirectory(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; path)&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;return&lt;/span&gt; (Directory.GetDirectories(path).Count() &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;+&lt;/span&gt; Directory.GetFiles(path).Count())
   == 0;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; FolderNameWithoutPath(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; path)&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;return&lt;/span&gt; Path.GetFileName(path);&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
   GetFolderNamesWithoutPath(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;this&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; path)&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;return&lt;/span&gt; (from
   folder &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt; Directory.GetDirectories(path)&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;select
   folder.FolderNameWithoutPath()).ToArray();&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
   }&lt;br&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   Once I had those, the resulting merge method was a simple iteration across a couple
   LINQ queries.&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; MergeFolders(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; sourceFolder, &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; destinationFolder)&lt;br&gt;
   {&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;//
   copy those in A but not in B&lt;/span&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;foreach&lt;/span&gt;(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; folder &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;sourceFolder.GetFolderNamesWithoutPath().Except(&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;destinationFolder.GetFolderNamesWithoutPath(),
   StringComparer.InvariantCultureIgnoreCase))&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;Directory.Move(Path.Combine(sourceFolder,
   folder), Path.Combine(destinationFolder, folder));&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;//
   now go through those in both and repeat&lt;/span&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;foreach&lt;/span&gt; (&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; folder &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;in&lt;/span&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;sourceFolder.GetFolderNamesWithoutPath().Intersect(&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;destinationFolder.GetFolderNamesWithoutPath(),
   StringComparer.InvariantCultureIgnoreCase))&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;string&lt;/span&gt; src &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; Path.Combine(sourceFolder,
   folder);&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;MergeFolders(src,
   Path.Combine(destinationFolder, folder));&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;if&lt;/span&gt; (src.IsEmptyDirectory())
   Directory.Delete(src);&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
   }&lt;br&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   &amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=9f9a5f01-0e64-4dcc-b6f5-dd5e81e48209" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <comments>http://blog.opennetcf.com/ctacke/CommentView,guid,9f9a5f01-0e64-4dcc-b6f5-dd5e81e48209.aspx</comments>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=9d61d40a-734b-4760-9d0f-b4a0cd01fbf2</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,9d61d40a-734b-4760-9d0f-b4a0cd01fbf2.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,9d61d40a-734b-4760-9d0f-b4a0cd01fbf2.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=9d61d40a-734b-4760-9d0f-b4a0cd01fbf2</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <div>We've published a new article on the OpenNETCF Community Site titled "Native
      vs. Managed Code: GDI Performance"
   </div>
        <div> 
   </div>
        <div>
          <a href="http://community.opennetcf.com/articles/cf/archive/2008/05/19/native-vs-managed-code-gdi-performance.aspx">http://community.opennetcf.com/articles/cf/archive/2008/05/19/native-vs-managed-code-gdi-performance.aspx</a>
        </div>
        <div> 
   </div>
        <div>In it, I look at the performance differences between native and managed code
      making GDI calls.
   </div>
        <div> 
   </div>
        <div>In case you missed them, our other recently published articles include:
   </div>
        <div> 
   </div>
        <div>- Performance Implications of Crossing the P/Invoke Boundary
   </div>
        <div>- An Introduction to WCF for Device Developers<br />
      - Getting a Millisecond-Resolution DateTime under Windows CE<br />
      - Using GDI+ on Windows Mobile<br />
      - Sharing Windows Mobile Ink with the Desktop<br />
      - OpenNETCF Mobile Ink Library for Windows Mobile 6<br />
      - Improving Data Access Performance with Data Caching<br />
      - Developing Connected Smart Device Applications with sqlClient<br />
      - Debugging Without ActiveSync<br />
      - Image Manipulation in Windows Mobile 5.0<br />
      - Don't Fear the Garbage Collector
   </div>
        <div> 
   </div>
        <div>All of our articles are available online at:<br /><a href="http://community.OpenNETCF.com/articles">http://community.OpenNETCF.com/articles</a></div>
        <div> 
   </div>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=9d61d40a-734b-4760-9d0f-b4a0cd01fbf2" />
        <br />
        <hr />
   Managed Code in the Embedded World</body>
      <title>New Community Article: GDI Performance</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,9d61d40a-734b-4760-9d0f-b4a0cd01fbf2.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/05/19/NewCommunityArticleGDIPerformance.aspx</link>
      <pubDate>Mon, 19 May 2008 16:27:16 GMT</pubDate>
      <description>&lt;div&gt;We've published a new article on the OpenNETCF Community Site titled "Native
   vs. Managed Code: GDI Performance"
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;&lt;a href="http://community.opennetcf.com/articles/cf/archive/2008/05/19/native-vs-managed-code-gdi-performance.aspx"&gt;http://community.opennetcf.com/articles/cf/archive/2008/05/19/native-vs-managed-code-gdi-performance.aspx&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;In it, I look at the performance differences between native and managed code
   making GDI calls.
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;In case you missed them, our other recently published articles include:
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;- Performance Implications of Crossing the P/Invoke Boundary
&lt;/div&gt;
&lt;div&gt;- An Introduction to WCF for Device Developers&lt;br&gt;
   - Getting a Millisecond-Resolution DateTime under Windows CE&lt;br&gt;
   - Using GDI+ on Windows Mobile&lt;br&gt;
   - Sharing Windows Mobile Ink with the Desktop&lt;br&gt;
   - OpenNETCF Mobile Ink Library for Windows Mobile 6&lt;br&gt;
   - Improving Data Access Performance with Data Caching&lt;br&gt;
   - Developing Connected Smart Device Applications with sqlClient&lt;br&gt;
   - Debugging Without ActiveSync&lt;br&gt;
   - Image Manipulation in Windows Mobile 5.0&lt;br&gt;
   - Don't Fear the Garbage Collector
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;div&gt;All of our articles are available online at:&lt;br&gt;
   &lt;a href="http://community.OpenNETCF.com/articles"&gt;http://community.OpenNETCF.com/articles&lt;/a&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=9d61d40a-734b-4760-9d0f-b4a0cd01fbf2" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <comments>http://blog.opennetcf.com/ctacke/CommentView,guid,9d61d40a-734b-4760-9d0f-b4a0cd01fbf2.aspx</comments>
      <category>Community;Compact Framework Code;OpenNETCF;Windows CE Code</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=bab37b43-49b4-44c7-bcb8-259b66922052</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,bab37b43-49b4-44c7-bcb8-259b66922052.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,bab37b43-49b4-44c7-bcb8-259b66922052.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=bab37b43-49b4-44c7-bcb8-259b66922052</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">OpenNETCF is in the midst of some major
   infrastructure updates to get automated unit testing of device assemblies working
   with Team Foundation Server.  Let's just say that it's nowhere near a simple
   task.<br /><br />
   As part of the work, we needed to automate access to the Device Emulator using the <a href="http://msdn.microsoft.com/en-us/library/bb531172.aspx">Microsoft-supplied
   Automation Interfaces</a>.  Their C++ and WScript samples for usage leave a bit
   to be desired, so we wrapped them in an object-oriented model to provide at least
   a skeletal framework for launching, resetting, saving state etc.  The classes
   haven't been heavily tested and the test harness for the classes is very basic, but
   it's a good starting point, and the download (below) is what we're using in our continuous
   integration process, so it's definitely functional.<br /><br /><img src="/ctacke/binary/dem.png" /><br /><br />
   We're releasing this source under <a href="http://opennetcf.com/mitx11license.ocf">the
   MIT X-11 license</a>.  If you make updates and want to submit them back to us,
   we'll be happy to integrate them, but it's not required.<br /><br /><a href="/ctacke/binary/OpenNETCF.DeviceEmulator.zip">Download the source and test
   harness here</a><br /><p></p><img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=bab37b43-49b4-44c7-bcb8-259b66922052" /><br /><hr />
   Managed Code in the Embedded World</body>
      <title>Emulator Manager Object Model</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,bab37b43-49b4-44c7-bcb8-259b66922052.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/05/09/EmulatorManagerObjectModel.aspx</link>
      <pubDate>Fri, 09 May 2008 19:04:11 GMT</pubDate>
      <description>OpenNETCF is in the midst of some major infrastructure updates to get automated unit testing of device assemblies working with Team Foundation Server.&amp;nbsp; Let's just say that it's nowhere near a simple task.&lt;br&gt;
&lt;br&gt;
As part of the work, we needed to automate access to the Device Emulator using the &lt;a href="http://msdn.microsoft.com/en-us/library/bb531172.aspx"&gt;Microsoft-supplied
Automation Interfaces&lt;/a&gt;.&amp;nbsp; Their C++ and WScript samples for usage leave a bit
to be desired, so we wrapped them in an object-oriented model to provide at least
a skeletal framework for launching, resetting, saving state etc.&amp;nbsp; The classes
haven't been heavily tested and the test harness for the classes is very basic, but
it's a good starting point, and the download (below) is what we're using in our continuous
integration process, so it's definitely functional.&lt;br&gt;
&lt;br&gt;
&lt;img src="/ctacke/binary/dem.png"&gt;
&lt;br&gt;
&lt;br&gt;
We're releasing this source under &lt;a href="http://opennetcf.com/mitx11license.ocf"&gt;the
MIT X-11 license&lt;/a&gt;.&amp;nbsp; If you make updates and want to submit them back to us,
we'll be happy to integrate them, but it's not required.&lt;br&gt;
&lt;br&gt;
&lt;a href="/ctacke/binary/OpenNETCF.DeviceEmulator.zip"&gt;Download the source and test
harness here&lt;/a&gt;
&lt;br&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=bab37b43-49b4-44c7-bcb8-259b66922052" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <comments>http://blog.opennetcf.com/ctacke/CommentView,guid,bab37b43-49b4-44c7-bcb8-259b66922052.aspx</comments>
      <category>OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=ee3624d5-1bbe-446b-bfa9-dc7315398a36</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,ee3624d5-1bbe-446b-bfa9-dc7315398a36.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,ee3624d5-1bbe-446b-bfa9-dc7315398a36.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=ee3624d5-1bbe-446b-bfa9-dc7315398a36</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Finally!  Someone has created <a href="http://www.eqatec.com/tools/profiler">a
      code profiler for the .NET Compact Framework</a>.  And what's even more exciting
      is that it's <u>free</u>.  I've not used it, so I can't vouch for how well it
      works, or how easy it is to use, but the fact it exists is quite promising.
   </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=ee3624d5-1bbe-446b-bfa9-dc7315398a36" />
        <br />
        <hr />
   Managed Code in the Embedded World</body>
      <title>Compact Framework Code Profiler</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,ee3624d5-1bbe-446b-bfa9-dc7315398a36.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/05/05/CompactFrameworkCodeProfiler.aspx</link>
      <pubDate>Mon, 05 May 2008 12:14:17 GMT</pubDate>
      <description>&lt;p&gt;
   Finally!&amp;nbsp; Someone has created &lt;a href="http://www.eqatec.com/tools/profiler"&gt;a
   code profiler for the .NET Compact Framework&lt;/a&gt;.&amp;nbsp; And what's even more exciting
   is that it's &lt;u&gt;free&lt;/u&gt;.&amp;nbsp; I've not used it, so I can't vouch for how well it
   works, or how easy it is to use, but the fact it exists is quite promising.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=ee3624d5-1bbe-446b-bfa9-dc7315398a36" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <comments>http://blog.opennetcf.com/ctacke/CommentView,guid,ee3624d5-1bbe-446b-bfa9-dc7315398a36.aspx</comments>
      <category>.NET Compact Framework;OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=59f3f797-803b-4a22-bb07-1dd0b7c92321</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,59f3f797-803b-4a22-bb07-1dd0b7c92321.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,59f3f797-803b-4a22-bb07-1dd0b7c92321.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=59f3f797-803b-4a22-bb07-1dd0b7c92321</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Ever since learning how to use <a href="http://en.wikipedia.org/wiki/Function_pointer">function
      pointers</a> in C, I've always been a fan of using them to help make code a bit more
      usable, especially when you've got a <a href="http://en.wikipedia.org/wiki/State_machine">state
      machine</a>.  Today, as I'm working on a Wizard UI for a desktop application
      I came across a typical scenario for using a function pointer.  Depending on
      the stage of the Wizard you're in, a button will have to do separate things.<br /><br />
      That got me to thinking that most managed developers simply don't understand the power
      and utility of <a href="http://msdn2.microsoft.com/en-us/library/900fyy8e(VS.80).aspx">delegates</a>,
      but instead simply consider them a necessity when using <a href="http://msdn2.microsoft.com/en-us/library/zyzhdc6b.aspx">Control.Invoke </a>or
      creating custom events. Sure, in my case I could have a switch statement in the click
      handler and do logic there, or I could unhook the click handler from one method and
      hook it to another, but those all seem ugly and a pain in the ass to me.  A simple
      function pointer change is all you need.  So I decided I'd throw together a really
      simple example of how you would use a delegate to change the behavior of a Button
      click.<br /><br />
      Let's assume that we have a button that we want to click, and when it's clicked it
      will do one of 4 things, depending on the state of our application.  We'll just
      use a messagebox here to give you the idea - what it does is up to you- it's a function
      after all.<br /></p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> FunctionA()<br />
      {<br />
        MessageBox.Show(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"FunctionA"</span>);<br />
      }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> FunctionB()<br />
      {<br />
        MessageBox.Show(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"FunctionB"</span>);<br />
      }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> FunctionC()<br />
      {<br />
        MessageBox.Show(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"FunctionC"</span>);<br />
      }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">public</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> FunctionD()<br />
      {<br />
        MessageBox.Show(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"FunctionD"</span>);<br />
      }<br /></span>
        </p>
        <p>
      To simulate the different "states" I simply added a ListBox (called functionList)
      to the Form and manually added the function names to it in the Form's constructor. 
      Sure, I could have used Reflection to be clever and populate the list, but I'm tryiong
      to keep it simple and show delegates.
   </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">functionList.Items.Add(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"FunctionA"</span>);<br />
      functionList.Items.Add(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"FunctionB"</span>);<br />
      functionList.Items.Add(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"FunctionC"</span>);<br />
      functionList.Items.Add(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"FunctionD"</span>);<br /></span>
        </p>
        <p>
      Alright, so now we know that depending on which item is selected, we want to call
      one of our four functions.  Since they all have the same interface (and they
      have to to use a delegate) we simply define a delegate that matches them.  This
      delegate can be privately scoped inside your class.
   </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">delegate</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> FunctionDelegate();<br /><br /></span>
        </p>
        <p>
      And then we create an instance variable to hold the current function pointer we want
      to use:
   </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span>
          <font face="Courier New">
            <font color="#000000"> FunctionDelegate
      m_functionPointer </font>
            <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span>
            <font color="#000000">
            </font>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>
            <font color="#000000">;</font>
          </font>
        </p>
        <p>
      We add an event handler for the SelectedIndexChanged event of the ListBox (in the
      Form constructor)
   </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">functionList.SelectedIndexChanged
      += <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> EventHandler(functionList_SelectedIndexChanged);</span>
        </p>
        <p>
      And implement the event handler.  It simply looks at the newly selected index
      in the list and changes the value stored in m_functionPointer appropriately.
   </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> functionList_SelectedIndexChanged(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
      EventArgs e)<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> 
      // determine which function pointer to store based on selection</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> 
      switch</span> (functionList.SelectedIndex)<br />
        {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span>case</span> 0:<br />
            m_functionPointer <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> FunctionA;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">      </font>break</span>;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span></span>case</span> 1:<br />
            m_functionPointer <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> FunctionB;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">      </font>break</span>;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span></span>case</span> 2:<br />
            m_functionPointer <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> FunctionC;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">      </font>break</span>;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span></span>case</span> 3:<br />
            m_functionPointer <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> FunctionD;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">      </font>break</span>;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  </span></span></span>default</span>:<br />
            m_functionPointer <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><font color="#000000">      </font>break</span>;<br />
        }<br />
      }<br /></span>
        </p>
        <p>
      Next we wire up an event handler for our button (again the the Form constructor):
   </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">callButton.Click
      += <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> EventHandler(callButton_Click);</span>
        </p>
        <p>
      And finally the magic and simplicity of the state-dependent call
   </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> callButton_Click(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
      EventArgs e)<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> 
      // call our function (as long as it's not null)</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"> 
      if</span> (m_functionPointer !<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
        {<br />
          m_functionPointer();<br />
        }<br />
      }<br /></span>
        </p>
        <p>
      That's all there is to it.  Run the application, select a function and click
      the button.
   </p>
        <p>
          <img alt="" hspace="0" src="http://blog.opennetcf.org/ctacke/images/fcnptr.jpg" align="middle" border="1" />
        </p>
        <p>
          <a href="/ctacke/binary/DelegateSample.zip">Get the full source here</a>.
   </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=59f3f797-803b-4a22-bb07-1dd0b7c92321" />
        <br />
        <hr />
   Managed Code in the Embedded World</body>
      <title>Using Delegates (i.e. Function Pointers)</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,59f3f797-803b-4a22-bb07-1dd0b7c92321.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/04/18/UsingDelegatesIeFunctionPointers.aspx</link>
      <pubDate>Fri, 18 Apr 2008 22:07:46 GMT</pubDate>
      <description>&lt;p&gt;
   Ever since learning how to use &lt;a href="http://en.wikipedia.org/wiki/Function_pointer"&gt;function
   pointers&lt;/a&gt; in C, I've always been a fan of using them to help make code a bit more
   usable, especially when you've got a &lt;a href="http://en.wikipedia.org/wiki/State_machine"&gt;state
   machine&lt;/a&gt;.&amp;nbsp; Today, as I'm working on a Wizard UI for a desktop application
   I came across a typical scenario for using a function pointer.&amp;nbsp; Depending on
   the stage of the Wizard you're in, a button will have to do separate things.&lt;br&gt;
   &lt;br&gt;
   That got me to thinking that most managed developers simply don't understand the power
   and utility of &lt;a href="http://msdn2.microsoft.com/en-us/library/900fyy8e(VS.80).aspx"&gt;delegates&lt;/a&gt;,
   but instead simply consider them a necessity when using &lt;a href="http://msdn2.microsoft.com/en-us/library/zyzhdc6b.aspx"&gt;Control.Invoke &lt;/a&gt;or
   creating custom events. Sure, in my case I could have a switch statement in the click
   handler and do logic there, or I could unhook the click handler from one method and
   hook it to another, but those all seem ugly and a pain in the ass to me.&amp;nbsp; A simple
   function pointer change is all you need.&amp;nbsp; So I decided I'd throw together a really
   simple example of how you would use a delegate to change the behavior of a Button
   click.&lt;br&gt;
   &lt;br&gt;
   Let's assume that we have a button that we want to click, and when it's clicked it
   will do one of 4 things, depending on the state of our application.&amp;nbsp; We'll just
   use a messagebox here to give you the idea - what it does is up to you- it's a function
   after all.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; FunctionA()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; MessageBox.Show(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"FunctionA"&lt;/span&gt;);&lt;br&gt;
   }&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; FunctionB()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; MessageBox.Show(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"FunctionB"&lt;/span&gt;);&lt;br&gt;
   }&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; FunctionC()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; MessageBox.Show(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"FunctionC"&lt;/span&gt;);&lt;br&gt;
   }&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;public&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; FunctionD()&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp; MessageBox.Show(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"FunctionD"&lt;/span&gt;);&lt;br&gt;
   }&lt;br&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   To simulate the different "states" I simply added a ListBox (called functionList)
   to the Form and manually added the function names to it in the Form's constructor.&amp;nbsp;
   Sure, I could have used Reflection to be clever and populate the list, but I'm tryiong
   to keep it simple and show delegates.
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;functionList.Items.Add(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"FunctionA"&lt;/span&gt;);&lt;br&gt;
   functionList.Items.Add(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"FunctionB"&lt;/span&gt;);&lt;br&gt;
   functionList.Items.Add(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"FunctionC"&lt;/span&gt;);&lt;br&gt;
   functionList.Items.Add(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"FunctionD"&lt;/span&gt;);&lt;br&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   Alright, so now we know that depending on which item is selected, we want to call
   one of our four functions.&amp;nbsp; Since they all have the same interface (and they
   have to to use a delegate) we simply define a delegate that matches them.&amp;nbsp; This
   delegate can be privately scoped inside your class.
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;delegate&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; FunctionDelegate();&lt;br&gt;
   &lt;br&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   And then we create an instance variable to hold the current function pointer we want
   to use:
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt;&lt;font face="Courier New"&gt;&lt;font color=#000000&gt; FunctionDelegate
   m_functionPointer &lt;/font&gt;&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt;&lt;font color=#000000&gt; &lt;/font&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;&lt;font color=#000000&gt;;&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
   We add an event handler for the SelectedIndexChanged event of the ListBox (in the
   Form constructor)
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;functionList.SelectedIndexChanged
   += &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; EventHandler(functionList_SelectedIndexChanged);&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   And implement the event handler.&amp;nbsp; It simply looks at the newly selected index
   in the list and changes the value stored in m_functionPointer appropriately.
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; functionList_SelectedIndexChanged(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
   EventArgs e)&lt;br&gt;
   {&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
   // determine which function pointer to store based on selection&lt;/span&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
   switch&lt;/span&gt; (functionList.SelectedIndex)&lt;br&gt;
   &amp;nbsp; {&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;case&lt;/span&gt; 0:&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_functionPointer &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; FunctionA;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;break&lt;/span&gt;;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;case&lt;/span&gt; 1:&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_functionPointer &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; FunctionB;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;break&lt;/span&gt;;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;case&lt;/span&gt; 2:&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_functionPointer &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; FunctionC;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;break&lt;/span&gt;;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;case&lt;/span&gt; 3:&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_functionPointer &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; FunctionD;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;break&lt;/span&gt;;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;default&lt;/span&gt;:&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_functionPointer &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/font&gt;break&lt;/span&gt;;&lt;br&gt;
   &amp;nbsp; }&lt;br&gt;
   }&lt;br&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   Next we wire up an event handler for our button (again the the Form constructor):
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;callButton.Click
   += &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; EventHandler(callButton_Click);&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   And finally the magic and simplicity of the state-dependent call
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; callButton_Click(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
   EventArgs e)&lt;br&gt;
   {&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
   // call our function (as long as it's not null)&lt;/span&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;
   if&lt;/span&gt; (m_functionPointer !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
   &amp;nbsp; {&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; m_functionPointer();&lt;br&gt;
   &amp;nbsp; }&lt;br&gt;
   }&lt;br&gt;
   &lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
   That's all there is to it.&amp;nbsp; Run the application, select a function and click
   the button.
&lt;/p&gt;
&lt;p&gt;
   &lt;img alt="" hspace=0 src="http://blog.opennetcf.org/ctacke/images/fcnptr.jpg" align=middle border=1&gt;
&lt;/p&gt;
&lt;p&gt;
   &lt;a href="/ctacke/binary/DelegateSample.zip"&gt;Get the full source here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=59f3f797-803b-4a22-bb07-1dd0b7c92321" /&gt;
&lt;br /&gt;
&lt;hr /&gt;Managed Code in the Embedded World</description>
      <comments>http://blog.opennetcf.com/ctacke/CommentView,guid,59f3f797-803b-4a22-bb07-1dd0b7c92321.aspx</comments>
      <category>Compact Framework Code;OpenNETCF</category>
    </item>
    <item>
      <trackback:ping>http://blog.opennetcf.com/ctacke/Trackback.aspx?guid=d839eeb7-2cb6-4842-a504-93d1bab0b0af</trackback:ping>
      <pingback:server>http://blog.opennetcf.com/ctacke/pingback.aspx</pingback:server>
      <pingback:target>http://blog.opennetcf.com/ctacke/PermaLink,guid,d839eeb7-2cb6-4842-a504-93d1bab0b0af.aspx</pingback:target>
      <dc:creator>
      </dc:creator>
      <wfw:comment>http://blog.opennetcf.com/ctacke/CommentView,guid,d839eeb7-2cb6-4842-a504-93d1bab0b0af.aspx</wfw:comment>
      <wfw:commentRss>http://blog.opennetcf.com/ctacke/SyndicationService.asmx/GetEntryCommentsRss?guid=d839eeb7-2cb6-4842-a504-93d1bab0b0af</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      In a recent project we decided to migrate the application's data engine from SQL CE
      3.1 to SQL CE 3.5.  The challenge with this is that the file formats themselves
      are not compatible and trying to connect to a 3.1 database usign the 3.5 objects will
      cause an Exception.  3.5 provides a method to upgrade 3.1 database files, but
      to use it you really need to know that the file is in 3.1 format to begin with.<br /><br />
      Of course you could always put in logic to connect and catch the exception and then
      upgrade, but let's face it - using exceptions for flow control is a bad practice and
      any ime it can be avoided it should be.  
      <br /><br />
      Surprisingly, the SQL CE team didn't give us any mechanism otherwise to determine
      a database file's version, so I put together the following (which should work on the
      desktop as well as the device):
   </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">enum</span> SSCEVersion<br />
      {<br />
          Unknown,<br />
          v3_1,<br />
          v3_5<br />
      }<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">internal</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">static</span> SSCEVersion
      GetDatabaseVersion(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> path)<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   
      uint</span> signature <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> 0;<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span>using</span> (FileStream
      stream <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> FileStream(path,
      FileMode.Open))<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span>{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span>using</span> (BinaryReader
      reader <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span> BinaryReader(stream))<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span>{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span></span>stream.Seek(16,
      SeekOrigin.Begin);<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span></span>signature <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> reader.ReadUInt32();<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span>}<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span>}<br /><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span>switch</span> (signature)<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span>{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span>case</span> 0x00357b9d: <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
      3.5</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span></span>return</span> SSCEVersion.v3_5;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span>case</span> 0x002dd714: <span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">//
      3.1</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span></span>return</span> SSCEVersion.v3_1;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span>default</span>:<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span></span></span>return</span> SSCEVersion.Unknown;<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">    </span>}<br />
      }<br /></span>
        </p>
        <img width="0" height="0" src="http://blog.opennetcf.com/ctacke/aggbug.ashx?id=d839eeb7-2cb6-4842-a504-93d1bab0b0af" />
        <br />
        <hr />
   Managed Code in the Embedded World</body>
      <title>Determinging a SQL CE database version</title>
      <guid>http://blog.opennetcf.com/ctacke/PermaLink,guid,d839eeb7-2cb6-4842-a504-93d1bab0b0af.aspx</guid>
      <link>http://blog.opennetcf.com/ctacke/2008/04/12/DetermingingASQLCEDatabaseVersion.aspx</link>
      <pubDate>Sat, 12 Apr 2008 19:11:20 GMT</pubDate>
      <description>&lt;p&gt;
   In a recent project we decided to migrate the application's data engine from SQL CE
   3.1 to SQL CE 3.5.&amp;nbsp; The challenge with this is that the file formats themselves
   are not compatible and trying to connect to a 3.1 database usign the 3.5 objects will
   cause an Exception.&amp;nbsp; 3.5 provides a method to upgrade 3.1 database files, but
   to use it you really need to know that the file is in 3.1 format to begin with.&lt;br&gt;
   &lt;br&gt;
   Of course you could always put in logic to connect and catch the exception and then
   upgrade, but let's face it - using exceptions for flow control is a bad practice and
   any ime it can be avoided it should be.&amp;nbsp; 
   &lt;br&gt;
   &lt;br&gt;
   Surprisingly, the SQL CE team didn't give us any mechanism otherwise to determine
   a database file's version, so I put together the following (which should work on the
   desktop as well as the device):
&lt;/p&gt;
&lt;p&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;enum&lt;/span&gt; SSCEVersion&lt;br&gt;
   {&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; Unknown,&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; v3_1,&lt;br&gt;
   &amp;nbsp;&amp;nbsp;&amp;nbsp; v3_5&lt;br&gt;
   }&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;internal&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;static&lt;/span&gt; SSCEVersion
   GetDatabaseVersion(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; path)&lt;br&gt;
   {&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;
   uint&lt;/span&gt; signature &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; 0;&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;using&lt;/span&gt; (FileStream
   stream &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; FileStream(path,
   FileMode.Open))&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;using&lt;/span&gt; (BinaryReader
   reader &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; BinaryReader(stream))&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;{&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;stream.Seek(16,
   SeekOrigin.Begin);&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;signature &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; reader.ReadUInt32();&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;switch&lt;/span&gt; (signature)&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;case&lt;/span&gt; 0x00357b9d: &lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;//
   3.5&lt;/span&gt;
   &lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;return&lt;/span&gt; SSCEVersion.v3_5;&lt;br&gt;
   &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;case&lt;/span&gt