<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-20032820</id><updated>2026-03-20T20:11:34.828+13:00</updated><category term="Tools"/><category term="Technology"/><category term="TDD"/><category term="Presentation Layer"/><category term="Data Access Layer"/><category term="Deployment"/><category term="Business Logic Layer"/><category term="C# Guidelines"/><category term="Performance Engineering"/><category term="Process"/><category term="Faker"/><category term="Hardware"/><category term="Review"/><category term="Testing"/><category term="TypeScript"/><title type='text'>Manni on DotNet</title><subtitle type='html'>Comments, how-to&#39;s, examples, tools, techniques and other material regarding .NET and related technologies.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>161</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-20032820.post-6884030739324733884</id><published>2018-07-10T13:39:00.000+12:00</published><updated>2018-07-10T13:39:32.457+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Faker"/><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="Testing"/><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>Creating Fake Data For Unit Tests With RimuTec.Faker</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
Setting up data for tests can be tedious. For example sometimes you may end up using first names like “First 1”, “First 2”, etc. Data like this may result in duplicates, so you then go to the next step using first names like “First “+ Guid.NewGuid() which may be a problem, too. Using such a name in a user interface may no longer fit the available space, where real-life names like “John” or “Anna” would fit easily.&lt;br /&gt;
&lt;br /&gt;
Another aspect can be that you are required to have a most recent version of your system or product for demo purposes, let’s say a pre-sales situation or an internal product review. Trying having a conversation about a screen that says “First123456 Last645861”. Wouldn’t it be nice if it would display names such as “John Doe” or “Anna Karenina”? It most likely would also create a much better impression with prospects, customers or other stakeholders. Your software looks more “complete”.&lt;br /&gt;
&lt;br /&gt;
Ruby developers have a gem named Faker which is available on &lt;a href=&quot;https://github.com/stympy/faker&quot; target=&quot;_blank&quot;&gt;github&lt;/a&gt;. Faker is based on a Perl library and has a large library of fake data generators.&lt;br /&gt;
&lt;br /&gt;
There have been a few efforts to port the Ruby gem to .NET. Most of these have a limited set of generators and haven’t been maintained for years.&lt;br /&gt;
&lt;br /&gt;
Therefore we decided to have another look. Where other projects use regular resource files, we decided to use the yaml files from Ruby’s Faker gem verbatim. By taking this approach we would automatically have some guardrails that would allow leveraging as many of the great ideas from the Faker gem as possible.&lt;br /&gt;
&lt;br /&gt;
The result is RimuTec.Faker which offers the following classes of generators:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Address&lt;/li&gt;
&lt;li&gt;Company&lt;/li&gt;
&lt;li&gt;Educator&lt;/li&gt;
&lt;li&gt;Finance&lt;/li&gt;
&lt;li&gt;IDNumber&lt;/li&gt;
&lt;li&gt;Internet&lt;/li&gt;
&lt;li&gt;Job&lt;/li&gt;
&lt;li&gt;Lorem&lt;/li&gt;
&lt;li&gt;Name&lt;/li&gt;
&lt;li&gt;PhoneNumber&lt;/li&gt;
&lt;li&gt;RandomNumber&lt;/li&gt;
&lt;/ul&gt;
Obviously this is not the complete list yet. We release frequently and are happy to receive suggestions for priorities in terms of what should be added next. Just log an issue on github.&lt;br /&gt;
&lt;br /&gt;
Using RimuTec.Faker the example from the beginning be written as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/ManfredLange/ee42af9392c21ba70aaed51ddc6b6be1.js&quot;&gt;&lt;/script&gt;

You can get both, the &lt;a href=&quot;https://github.com/RimuTec/Faker&quot; target=&quot;_blank&quot;&gt;source code&lt;/a&gt; as well as the &lt;a href=&quot;https://www.nuget.org/packages/RimuTec.Faker&quot; target=&quot;_blank&quot;&gt;NuGet package&lt;/a&gt; under the MIT license. This means you can use it for free and also use it in your own projects as you see fit, including commercial and closed-source projects.&lt;br /&gt;
&lt;br /&gt;
Happy coding!&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/6884030739324733884/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2018/07/creating-fake-data-for-unit-tests-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6884030739324733884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6884030739324733884'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2018/07/creating-fake-data-for-unit-tests-with.html' title='Creating Fake Data For Unit Tests With RimuTec.Faker'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-6432599143486031814</id><published>2017-02-24T14:05:00.004+13:00</published><updated>2017-02-24T15:51:13.757+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><category scheme="http://www.blogger.com/atom/ns#" term="TypeScript"/><title type='text'>TypeScript Errors TS2300 and TS2374 in VS2017 RC</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
We recently updated to Visual Studio 2017 RC from Visual Studio 2013. I won&#39;t go into the details why we skipped Visual Studio 2015.&lt;br /&gt;
&lt;br /&gt;
The upgrade at some point then trigger to update to the latest TypeScript toolset version (2.1 at the time of writing).&lt;br /&gt;
&lt;br /&gt;
We then notice a series of TypeScript compiler errors with codes TS2300 and TS2374. It turns out that the compiler was actually happy. The error list is created by IntelliSense. To identify them as generated by IntelliSense you need to ensure that you select &quot;IntelliSense Only&quot; from the drop-down list in the &quot;Error List&quot; view of Visual Studio (VS) (click image to enlarge it):&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi12b832VXZFE8TyYDDoRViwCkA5x4QlWpiTp3LokPi7zYSp8so6l9bEY4grqxQpW8SrBvKlrzIJ3rkgyR_p9pdWSXMUhq-5x7BlgBLzrhXhhn1i3Bt2gmnt-gV5KWlljCF2_zEag/s1600/2017-02-24_13-47-19-VS2017-TypeScriptErrors.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;202&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi12b832VXZFE8TyYDDoRViwCkA5x4QlWpiTp3LokPi7zYSp8so6l9bEY4grqxQpW8SrBvKlrzIJ3rkgyR_p9pdWSXMUhq-5x7BlgBLzrhXhhn1i3Bt2gmnt-gV5KWlljCF2_zEag/s400/2017-02-24_13-47-19-VS2017-TypeScriptErrors.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
In our case we observed the following errors:&lt;br /&gt;
&lt;ul style=&quot;text-align: left;&quot;&gt;
&lt;li&gt;TS2300 Duplicate identifier &#39;export=&#39;&lt;/li&gt;
&lt;li&gt;TS2374 Duplicate string index signature&lt;/li&gt;
&lt;li&gt;TS2375 Duplicate number index signature&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
When we check for the files for which these were recorded, we discovered that these were related to jQuery.d.ts, knockout.d.ts and index.d.ts. All of these files were part of the latest NuGet package for either jQuery or Knockout, so outside of our control.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
After some experimentation we identified adding a tsconfig.json file to the project solved the problem.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Here is the complete content of the tsconfig.json file:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;In other words: apart from the curly braces it is empty. We placed this file in the same directory as the project file (Web.csproj in our case) and included it in the project.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;The file tsconfig.json does not have to be empty. You are free to add settings as needed. The key point for us was to avoid the false positive by IntelliSense.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;With VS 2013 it worked without tsconfig.json. However, it looks as if the tooling has changed and that for IntelliSense to work correctly the file has to be present.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;In closing, a gentle reminder to select &quot;Build&amp;nbsp;+ IntelliSense&quot; from the drop-down list in the &quot;Error List&quot; to see all errors again (if any). Here is an image that shows this as well as the location for the tsconfig.json file (click image to enlarge it):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc2lWi2B6VyVkUoeWWmXYxCzZSviiI9wsT_soPD6EXLsFXtvbY467yhSXicpgKLWF1vbKI8jVziYiudtV_-tJje-P9VxPz3JITcCOr5ib21Ut1Sbt_8OefQYdImBLtobFgtsScUA/s1600/2017-02-24_13-47-19-VS2017-TypeScriptErrors-img2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc2lWi2B6VyVkUoeWWmXYxCzZSviiI9wsT_soPD6EXLsFXtvbY467yhSXicpgKLWF1vbKI8jVziYiudtV_-tJje-P9VxPz3JITcCOr5ib21Ut1Sbt_8OefQYdImBLtobFgtsScUA/s400/2017-02-24_13-47-19-VS2017-TypeScriptErrors-img2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;Happy coding!&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/6432599143486031814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2017/02/typescript-errors-ts2300-and-ts2374-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6432599143486031814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6432599143486031814'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2017/02/typescript-errors-ts2300-and-ts2374-in.html' title='TypeScript Errors TS2300 and TS2374 in VS2017 RC'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi12b832VXZFE8TyYDDoRViwCkA5x4QlWpiTp3LokPi7zYSp8so6l9bEY4grqxQpW8SrBvKlrzIJ3rkgyR_p9pdWSXMUhq-5x7BlgBLzrhXhhn1i3Bt2gmnt-gV5KWlljCF2_zEag/s72-c/2017-02-24_13-47-19-VS2017-TypeScriptErrors.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-1493301473558858107</id><published>2015-08-09T18:38:00.000+12:00</published><updated>2015-08-09T18:38:26.284+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C# Guidelines"/><title type='text'>Generating Resource Designer Files During Build with Visual Studio</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
In Visual Studio files containing resources have the extension *.resx. As you edit this file VS will use a custom tool to generate a strongly typed *designer.cs file. However, since this is a generated file, you should not need to put it under version control. Consequentially you will need to generate the file. One option is to use the context menu and select &quot;Run Custom Tool&quot;. This is cumbersome if you check out the code base and have many resource files. It would be great, if those designer files were created automatically when building the project.&lt;br /&gt;
&lt;br /&gt;
Another scenario is where resource files are re-used across multiple projects. Here, too, automatic generation during build would be useful.&lt;br /&gt;
&lt;br /&gt;
Finally it would be great if a solution for automatically generating the designer files would work for both building the project in Visual Studio and building it via msbuild at the command line.&lt;br /&gt;
&lt;br /&gt;
The solution presented here was developed with Visual Studio 2013 and C#. It may or may not work in other environments.&lt;br /&gt;
&lt;br /&gt;
To automatically generate the *.designer.cs files from *.resx files, follow these steps:&lt;br /&gt;
&lt;br /&gt;
1. Close your solution&lt;br /&gt;
&lt;br /&gt;
2. Open as an XML file the project file in which you want to automatically generate the designer files. Note that you need to load it as an XML file. You can&#39;t edit these settings through the project property page.&lt;br /&gt;
&lt;br /&gt;
3. Add a target to the project as follows:

&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;lt;Target Name=&quot;GenerateDesignerFiles&quot;&amp;gt;
   &amp;lt;Message Text=&quot;Deleting old Designer Files...&quot;/&amp;gt;
   &amp;lt;Delete Files=&quot;@(EmbeddedResource-&amp;gt;&#39;%(RootDir)%(Directory)%(Filename).resources&#39;)&quot;/&amp;gt;
   &amp;lt;Delete Files=&quot;@(EmbeddedResource-&amp;gt;&#39;%(RootDir)%(Directory)%(Filename).designer.cs&#39;)&quot;/&amp;gt;
   &amp;lt;Message Text=&quot;Generating Designer Files...&quot;/&amp;gt;
   &amp;lt;GenerateResource
      Sources=&quot;@(EmbeddedResource)&quot;
      StronglyTypedLanguage=&quot;C#&quot;
      StronglyTypedClassName=&quot;%(Filename)&quot;
      StronglyTypedNamespace=&quot;@(EmbeddedResource-&amp;gt;&#39;%(CustomToolNamespace)&#39;)&quot;
      StronglyTypedFileName=&quot;@(EmbeddedResource-&amp;gt;&#39;%(RootDir)%(Directory)%(Filename).designer.cs&#39;)&quot;
      PublicClass=&quot;true&quot;
      &amp;gt;
   &amp;lt;/GenerateResource&amp;gt;
   &amp;lt;Message Text=&quot;Generating Designer Files complete.&quot;/&amp;gt;
&amp;lt;/Target&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
4. Locate the target named &quot;BeforeBuild&quot;. This target may be commented out (the default).&lt;br /&gt;
&lt;br /&gt;
5. Modify the &quot;BeforeBuild&quot; target as follows:

&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;lt;Target Name=&quot;BeforeBuild&quot;&amp;gt;
   &amp;lt;CallTarget Targets=&quot;GenerateDesignerFiles&quot;/&amp;gt;
&amp;lt;/Target&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
This solution is based on all resource files being listed as &quot;EmbeddedResource&quot; within an ItemGroup of the project file, e.g.

&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&amp;lt;ItemGroup&amp;gt;
  &amp;lt;EmbeddedResource Include=&quot;Resources\Creditor\Display_Creditor.resx&quot;&amp;gt;
    &amp;lt;Generator&amp;gt;PublicResXFileCodeGenerator&amp;lt;/Generator&amp;gt;
    &amp;lt;LastGenOutput&amp;gt;Display_Creditor.Designer.cs&amp;lt;/LastGenOutput&amp;gt;
    &amp;lt;CustomToolNamespace&amp;gt;Acme.Web.Resources.Creditor&amp;lt;/CustomToolNamespace&amp;gt;
  &amp;lt;/EmbeddedResource&amp;gt;
  &amp;lt;EmbeddedResource Include=&quot;Resources\InboundEmail\Tooltip_InboundEmailDetails.resx&quot;&amp;gt;
    &amp;lt;Generator&amp;gt;PublicResXFileCodeGenerator&amp;lt;/Generator&amp;gt;
    &amp;lt;LastGenOutput&amp;gt;Tooltip_InboundEmailDetails.Designer.cs&amp;lt;/LastGenOutput&amp;gt;
    &amp;lt;CustomToolNamespace&amp;gt;Acme.Web.Resources.InboundEmail&amp;lt;/CustomToolNamespace&amp;gt;
  &amp;lt;/EmbeddedResource&amp;gt;
  &amp;lt;EmbeddedResource Include=&quot;Resources\Creditor\Tooltip_CreditorDetails.resx&quot;&amp;gt;
    &amp;lt;Generator&amp;gt;PublicResXFileCodeGenerator&amp;lt;/Generator&amp;gt;
    &amp;lt;LastGenOutput&amp;gt;Tooltip_CreditorDetails.Designer.cs&amp;lt;/LastGenOutput&amp;gt;
    &amp;lt;CustomToolNamespace&amp;gt;Acme.Web.Resources.Creditor&amp;lt;/CustomToolNamespace&amp;gt;
  &amp;lt;/EmbeddedResource&amp;gt;
&amp;lt;/ItemGroup&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
Disclaimer: This has been tested with Visual Studio 2013 and C# projects. It also works using msbuild. It may or may not work for other environments.&lt;/div&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/1493301473558858107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2015/08/generating-resource-designer-files.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/1493301473558858107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/1493301473558858107'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2015/08/generating-resource-designer-files.html' title='Generating Resource Designer Files During Build with Visual Studio'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-1121664564418013443</id><published>2014-01-21T19:26:00.001+13:00</published><updated>2014-01-21T19:28:27.268+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Deployment"/><category scheme="http://www.blogger.com/atom/ns#" term="Process"/><title type='text'>ASP.NET MVC, TypeScript, Azure Website and Git Deploy</title><content type='html'>&lt;h3&gt;The Issue&lt;/h3&gt; &lt;p&gt;The issue and the workaround in this post applies to:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Visual Studio 2013&lt;/li&gt; &lt;li&gt;ASP.NET MVC using at least one TypeScript file&lt;/li&gt; &lt;li&gt;Azure Website with git deploy&lt;/li&gt; &lt;li&gt;Sites build and deployed before &lt;a href=&quot;https://github.com/projectkudu/kudu/issues/721&quot; target=&quot;_blank&quot;&gt;kudu issue 721&lt;/a&gt; was resolved&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Building a web site with ASP.NET and TypeScript targeting Azure Website I ran into an issue after I added the first TypeScript file and tried to deploy the web site using git deploy. It would fail with the following error message:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;C:\DWASFiles\Sites\typescripttest\VirtualDirectory0\site\repository\TypeScriptHTMLApp1.csproj(67,3): error MSB4019: The imported project &quot;D:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\TypeScript\Microsoft.TypeScript.targets&quot; was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;The root cause for this is that the file Microsoft.TypeScript.targets file is not yet available using git deploy for Azure Websites.&lt;/p&gt; &lt;p&gt;The issue that I ran into is documented and discussed in a few places, e.g.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;a title=&quot;https://github.com/projectkudu/kudu/issues/556&quot; href=&quot;https://github.com/projectkudu/kudu/issues/556&quot;&gt;https://github.com/projectkudu/kudu/issues/556&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a title=&quot;https://github.com/projectkudu/kudu/issues/721&quot; href=&quot;https://github.com/projectkudu/kudu/issues/721&quot;&gt;https://github.com/projectkudu/kudu/issues/721&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a title=&quot;http://stackoverflow.com/questions/14883496/is-there-a-way-to-run-the-typescript-compiler-as-part-of-the-azure-git-deploy&quot; href=&quot;http://stackoverflow.com/questions/14883496/is-there-a-way-to-run-the-typescript-compiler-as-part-of-the-azure-git-deploy&quot;&gt;http://stackoverflow.com/questions/14883496/is-there-a-way-to-run-the-typescript-compiler-as-part-of-the-azure-git-deploy&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Here is my workaround that solved the issue for now. Rumors has it that Microsoft is working on a proper solution for the issue.&lt;/p&gt; &lt;p&gt;Note that the workaround does not require a custom “deploy.cmd” file which I felt was a plus despite having creating custom deploy scripts for other projects and other reasons.&lt;/p&gt; &lt;h3&gt;The Workaround&lt;/h3&gt; &lt;p&gt;The workaround is based on making the msbuild task and the TypeScript compiler available when the msbuild script (aka solution file and project files) are executed.&lt;/p&gt; &lt;p&gt;In my repository I created a folder 3rdparty in parallel to the solution file.&lt;/p&gt; &lt;p&gt;Next I created a subfolder typescript-sdk and copied the content of “C:\Program Files (x86)\Microsoft SDKs\TypeScript” into “3rdparty\typescript-sdk”. The folder contains a file tsc.exe. Make sure this is version 0.9.1.1. This version worked for me. Apparently there are other versions out there. For example version 0.9.5.0 is reported to create an error.&lt;/p&gt; &lt;p&gt;I also needed the msbuild task. For that I created a subfolder typescript-task and copied the content of “C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\TypeScript” into “3rdparty\typescript-task”.&lt;/p&gt; &lt;p&gt;The next two steps required editing the file “Microsoft.TypeScript.targets” located in “3rdparty/typescript-task” and the ASP.NET MVC project file. I won’t detail these changes here as all of this workaround is available in a repository.&lt;/p&gt; &lt;p&gt;With this workaround I have the same behavior for Azure Website’s git deploy as I have locally building from Visual Studio 2013. To use a TypeScript file, all I have to do is adding the file, reference the resulting javascript in the appropriate place in my views or layouts, commit and push. No further steps required.&lt;/p&gt; &lt;p&gt;Once the issue is resolved, all I have to do is undo the changes in the project file and remove the folders “3rdparty\typescript-sdk” and “3rdparty\typescript-task” and everything else is back to normal.&lt;/p&gt; &lt;p&gt;This workaround should also be applicable for scenarios where you already have a custom deploy script. The workaround does not require any changes to custom deploy scripts.&lt;/p&gt; &lt;p&gt;All of the source code is available in a sample project at &lt;a title=&quot;https://bitbucket.org/ml_agileutilities/typescript-sample&quot; href=&quot;https://bitbucket.org/ml_agileutilities/typescript-sample&quot;&gt;https://bitbucket.org/ml_agileutilities/typescript-sample&lt;/a&gt;. There is a branch with a version that allows reproducing the problem. There is a second branch that demonstrates that the workaround fixes the issue. If you want to try out either scenario create an Azure Website and have it use git deploy from one the respective branch.&lt;/p&gt; &lt;h3&gt;Credits&lt;/h3&gt; &lt;p&gt;I’d like to thank Thiago Almeida and &lt;a href=&quot;http://blog.davidebbo.com/&quot; target=&quot;_blank&quot;&gt;David Ebbo&lt;/a&gt;, Microsoft, for their awesome support in finding and testing this workaround.&lt;/p&gt; &lt;p&gt;Although I didn’t need a custom deploy script in the end, I would also like to thank Amit Apple for his very helpful description of &lt;a href=&quot;http://blog.amitapple.com/post/38417491924/azurewebsitecustomdeploymentpart1&quot; target=&quot;_blank&quot;&gt;how to create custom deploy script for Azure Websites&lt;/a&gt;.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/1121664564418013443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2014/01/aspnet-mvc-typescript-azure-website-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/1121664564418013443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/1121664564418013443'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2014/01/aspnet-mvc-typescript-azure-website-and.html' title='ASP.NET MVC, TypeScript, Azure Website and Git Deploy'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-4947632474214116929</id><published>2013-07-15T19:32:00.001+12:00</published><updated>2013-07-15T19:32:58.135+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>No Split Window for TypeScript?</title><content type='html'>&lt;p&gt;In case you installed &lt;a href=&quot;https://www.microsoft.com/en-us/download/details.aspx?id=34790&quot; target=&quot;_blank&quot;&gt;TypeScript for Visual Studio 2012&lt;/a&gt; and are wondering why you are not getting the split window for a &lt;a href=&quot;http://www.typescriptlang.org/&quot; target=&quot;_blank&quot;&gt;TypeScript&lt;/a&gt; file: Check whether you have installed “&lt;a href=&quot;http://visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6&quot; target=&quot;_blank&quot;&gt;Web Essentials 2012&lt;/a&gt;” as well. The latter gives you the split windows.&lt;/p&gt; &lt;p&gt;We had a couple of cases in one of the teams I’m working with where installing Web Essentials resolved the issue.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/4947632474214116929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2013/07/no-split-window-for-typescript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/4947632474214116929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/4947632474214116929'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2013/07/no-split-window-for-typescript.html' title='No Split Window for TypeScript?'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-6597965177812269882</id><published>2013-05-24T17:41:00.001+12:00</published><updated>2013-05-25T10:20:19.227+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>Xamarin Studio: Hello, world! fails to build</title><content type='html'>&lt;p&gt;I just purchased, installed and tried out Xamarin Studio. My motivation is that I want to try out this C#-based approach towards developing applications for Android.&lt;/p&gt; &lt;p&gt;Not that I want to move away from Visual Studio. I’m just working through a few examples and wanted to rule out VS as an influencing factor.&lt;/p&gt; &lt;p&gt;Problem is that the Hello World example already failed. The error message was “The “Aapt” task failed unexpectedly.” And there was also a “System.InvalidOperationException: Sequence contains no elements” and an error code “MSB4018”. Here is a screenshot:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqCDr8lsxKvNt1LUqZz1jv8oe5WmdaSW7W5YDyQmHcJHsXXhda3UVkJXv5L7Zv9FPKfIokUpdmeqJoBnK56Q7Ks2gd8pTkIJcIRlZDivXbJvtA_j2rY4yywzFazr2Zh56RFvHg/s1600-h/image%25255B3%25255D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKX1QlsH3GxjI8X0Imw2tsmtN5AxnVSG0mNRPMTd3Mnn_b_TngygvlRq682HrKKcwGwsZItfuYFhmvQYA-js-1Ne9dzrvXHFvSGGWI676UYQxmRATCPU32UHMOooC-_en0rxsO/?imgmax=800&quot; width=&quot;503&quot; height=&quot;127&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;To solve it launch the Android SDK Manager. In my case it showed that there was a new update for the Android DSF Platform-tool and also showed that the Android SDK Build-tools were not installed. I just left all checked/unchecked as it was and installed what was checked. Admittedly not very selective but it did the trick. Now it’s building.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/6597965177812269882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2013/05/xamarin-studio-hello-world-fails-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6597965177812269882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6597965177812269882'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2013/05/xamarin-studio-hello-world-fails-to.html' title='Xamarin Studio: Hello, world! fails to build'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKX1QlsH3GxjI8X0Imw2tsmtN5AxnVSG0mNRPMTd3Mnn_b_TngygvlRq682HrKKcwGwsZItfuYFhmvQYA-js-1Ne9dzrvXHFvSGGWI676UYQxmRATCPU32UHMOooC-_en0rxsO/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-8687595510466973827</id><published>2013-05-23T16:25:00.001+12:00</published><updated>2013-05-23T16:25:33.328+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>Visual Studio Image Library</title><content type='html'>&lt;p&gt;Just tried to locate the Visual Studio Image Library. I couldn’t find it. Various sources suggest to locate the file VS2010ImageLibrary.zip. This doesn’t exist on my machine, though.&lt;/p&gt; &lt;p&gt;It turned out that I never had Visual Studio 2010 on this machine, only Visual Studio 2012 has been installed. It appears as if VS2012 doesn’t install it by default.&lt;/p&gt; &lt;p&gt;However, you can download the VS2012 Image Library &lt;a href=&quot;http://www.microsoft.com/en-us/download/details.aspx?id=35825&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. Hopefully this post helps you saving some time.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/8687595510466973827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2013/05/visual-studio-image-library.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8687595510466973827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8687595510466973827'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2013/05/visual-studio-image-library.html' title='Visual Studio Image Library'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-8093612001884765800</id><published>2013-05-04T13:34:00.001+12:00</published><updated>2013-05-12T07:57:41.546+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>WiX: Installing Files to Public Documents Folder</title><content type='html'>&lt;p&gt;A few days ago I stumbled over the problem of installing files into the “Public Documents” folder using the Windows Installer Toolkit (&lt;a href=&quot;http://wixtoolset.org/&quot; target=&quot;_blank&quot;&gt;WiX&lt;/a&gt;). Although the different bits a pieces are available somewhere on the internet I couldn’t locate a single source that describes a complete solution.&lt;/p&gt; &lt;p&gt;On Windows based systems each user has their own personal folder but there is also a folder called “Public Documents”. For the task at hand, I wanted to install a few sample text files into a subfolder of the public documents folder using WiX. For this example I used Visual Studio 2012 (Professional Edition or better is sufficient) with the Visual Studio extension installed by WiX 4.0.&lt;/p&gt; &lt;p&gt;Let’s start with the wizard for the WiX setup project:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7O1qWzm6-zuaPC9xz6_AUNDp1eTRVNTkxGamEhdSQaz2rJUnOm_cBYlAAyFf_evPjaT3l__Il5g9R5afPDDbHPmqWATtzGcddp0udwXsRPYV75sZrM7eeph1RpysVnWqSUuSj/s1600-h/image%25255B8%25255D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjLgYDC6sgbBGhAdNy0Ry0Cn1Vu5PUKfaZ910jytpck7bJE61YGTdc8ImoABNnFjDnlt1eUZw-oeZZLjC4hpbyKmo1zUBc-hnC1Q0nEWE9salgX1lWJzsNa2eZJcdRnOMFDqoN/?imgmax=800&quot; width=&quot;90%&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;As the name for the setup you can pick anything you like. In this case I chose “Acme.Setup”. The resulting project looks very simple. It has no references and only a single WiX script file in it:&lt;/p&gt; &lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh42USgzwqcQyXoy7VU5tEPYNAnYVFMpgbuC6fDYoBh1hvPtcB87fqlBo7EIG0kaRyR3aXMEJlgV4kf0ShUEphp0beO5UvNWpq59Q7IPS1G7YcogPpPIusk0OrR0FGH-ThRBxI7/s1600-h/image%25255B12%25255D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvUL2ad17uWKkPFfW0Avu7h10mwD1DfJiy9NWu73CrgQyjiUP3ZAelaSPWjKaqtfXjz-OYGcAn_I2YaG3B1egCITe4QFSyQTRUkMRr3pXvskbTLxDkeFGi3Eh0cXxfC1Mmz8xs/?imgmax=800&quot; width=&quot;321&quot; height=&quot;196&quot;&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;The content of Produce.wxs is very basic (Note that the first few digits of all GUIDs in this post are replaced with the string ‘YOURGUID’. You need to replace the GUIDs with your own to make it work):&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;xml&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1.0&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;UTF-8&quot;&lt;/span&gt;?&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Wix&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;http://wixtoolset.org/schemas/v4/wxs&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Product&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;*&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme.Setup&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Language&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1033&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1.0.0.0&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Manufacturer&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;UpgradeCode&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;YOURGUID-269e-4795-97d7-a392d75749fb&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Package&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;InstallerVersion&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;200&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Compressed&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;yes&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;InstallScope&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;perMachine&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;MajorUpgrade&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;DowngradeErrorMessage&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;A newer version of [ProductName] is already installed.&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;MediaTemplate&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Feature&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProductFeature&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme.Setup&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroupRef&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProductComponents&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Feature&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;TARGETDIR&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;SourceDir&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProgramFilesFolder&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;INSTALLFOLDER&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme.Setup&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroup&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProductComponents&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;INSTALLFOLDER&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- &amp;lt;Component Id=&quot;ProductComponent&quot;&amp;gt; --&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- TODO: Insert files, registry keys, and other resources here. --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- &amp;lt;/Component&amp;gt; --&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroup&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Wix&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
Obviously, we now need to change this to add some files. So let’s pick a text file from a different project in the same solution. In this case I created a C# library projects called Acme.Lib and added one simple text file. We can ignore the default class ‘Class1’ that is generated in the Acme.Lib project. It is not relevant for this blog post. Here is what the solution looks like now:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ4F7pz4V5jYpsthAHSFBdTFNF2GY7ISt0ULaqsnoVhOEqrwIlvPYdC9sHU6kk8Pi9xNg1DmuxkyFUePvpYSddyDMAfMsBQt6jBmPq6B1JmOT3LVkP9mIP8z56n40zWaXCilKo/s1600-h/image%25255B16%25255D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHAdySavrAabWe0cyO9mTzVat9Au4dTKnLVtUKtpsJpBDUoXUHFPvopp5gMfIsrmOtybsYz2zr_2q3q8wcjlfneK01wJeKohfLE7dyxLMHLHe-DJb032vE6d2VL7CfINh-J4wZ/?imgmax=800&quot; width=&quot;347&quot; height=&quot;297&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The content of the file readme.txt and it’s name are irrelevant as well. Choose what works best for your case.&lt;/p&gt;
&lt;p&gt;Next we need to make sure that the installer script knows about the text file and where it is located. The first option is to use your knowledge about the location of the two projects, Acme.Lib and Acme.Setup. So you could change the file Product.wxs as follows:&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroup&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProductComponents&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;INSTALLFOLDER&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. --&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- &amp;lt;Component Id=&quot;ProductComponent&quot;&amp;gt; --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- TODO: Insert files, registry keys, and other resources here. --&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Component&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ReadmeFile&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Guid&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{YOURGUID-994F-49C0-A7AC-53D1571A295A}&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
         &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;readme.txt&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;readme.txt&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Source&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;..\Acme.Lib\readme.txt&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- &amp;lt;/Component&amp;gt; --&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroup&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Some points of interest. First of all we need to add a new &amp;lt;Component&amp;gt; to the script. Your installer can consist of thousands of components if you wish. In this case I’m only adding one component with an Id and a GUID. Again, please note that I have replaced the first few digits of the GUID with ‘YOURGUID’. You need to replace all GUIDs in this example with newly generated GUIDs anyways to make it work.&lt;/p&gt;
&lt;p&gt;Inside of the component I place a &amp;lt;File&amp;gt; tag with the Id, the name and the Source of the file. The Id needs to be unique within the installer while the name is the name that the file will have once installed. The ‘Source’ attributes tells the WiX toolset where to find the file so it can be included into the installer. Note that in contrast to some other installer tools sets the build of the installer will fail in case the WiX toolset can’t find the file.&lt;/p&gt;
&lt;p&gt;At this stage there one additional tweak that we have to do to compile this build script successfully. We need to edit the &#39;Manufacturer’ attribute at the beginning of Product.wxs. Here are the first four lines (Note that ‘Manufacturer’ has been set to ‘Acme’):&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;xml&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1.0&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;UTF-8&quot;&lt;/span&gt;?&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Wix&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;http://wixtoolset.org/schemas/v4/wxs&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Product&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;*&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme.Setup&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Language&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1033&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1.0.0.0&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Manufacturer&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;UpgradeCode&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;YOURGUID-269e-4795-97d7-a392d75749fb&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Package&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;InstallerVersion&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;200&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Compressed&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;yes&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;InstallScope&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;perMachine&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;If you now build your solution it should build without problems.&lt;/p&gt;
&lt;p&gt;At this stage all you have is an installer that installs into the into a subfolder in Program Files. It works but it is not what we want. So let’s have a look how we can change that.&lt;/p&gt;
&lt;p&gt;The trick is to add some WiX specific extensions. This can be accomplished by adding a reference to the installer project, ‘Acme.Setup&quot;’ in this example. The dialog box looks as follows and we want to add a file called ‘WixUtilExtension.dll’:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD6F0p9kkrcbOm6N98SnBvDiGRJOKybg5S6RXh5hfpH0dazMbogZJcu2W_9CACivRtmOi2Vd_j2KNKOCtoNtNF4VJf3YiU0y9_q1B1F3WaxlYUlycSI_WEA2vMsg-L3GNULX4g/s1600-h/image%25255B21%25255D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_ibqpVyezv0_-ke91JU1Af2r6mgaJwmbV3TctGORWHnFVKx3U_rsR6pTKb9OF2gJezWJ6KgckTWiqldrAL2-W4oES2setQvfkmFgHgTqi-izCh6BSTCD75kz63B636_fHDgby/?imgmax=800&quot; width=&quot;469&quot; height=&quot;499&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Adding this reference enables support for functionality that allows installing into the “Public Documents” folder.&lt;/p&gt;
&lt;p&gt;The way we can use this is by adding a property reference with the Id ‘WIX_DIR_COMMON_DOCUMENTS’ as follows:&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Product&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;*&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme.Setup&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Language&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1033&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1.0.0.0&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Manufacturer&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;UpgradeCode&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;YOURGUID-269e-4795-97d7-a392d75749fb&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Package&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;InstallerVersion&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;200&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Compressed&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;yes&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;InstallScope&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;perMachine&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;MajorUpgrade&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;DowngradeErrorMessage&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;A newer version of [ProductName] is already installed.&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;MediaTemplate&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;

   &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;PropertyRef&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;WIX_DIR_COMMON_DOCUMENTS&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;

   &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Feature&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProductFeature&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme.Setup&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroupRef&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProductComponents&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Feature&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;WiX will set the property ‘WIX_DIR_COMMON_DOCUMENTS’ to the correct path for the “Public Documents” folder when the installer is executed. We don’t have to worry about that.&lt;/p&gt;
&lt;p&gt;Now this property has been referenced we can use it to specify where we would like to install our readme file. For that we first need to change the &amp;lt;Directory&amp;gt; tag content as follows:&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;TARGETDIR&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;SourceDir&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;WIX_DIR_COMMON_DOCUMENTS&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
         &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ACMEDOCUFOLDER&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme Documentation&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
         &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProgramFilesFolder&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;INSTALLFOLDER&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme.Setup&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;
Note the additional directory tag with the Id ‘WIX_DIR_COMMON_DOCUMENTS’. I left the other directory tag in place. We don’t need it for the example in this blog post. For yuor actual installer you may want to use it to place binary files into a folder inside of “Program Files”. 
&lt;p&gt;The next change you have to make is adding a new component group that installs into the WIX_DIR_COMMON_DOCUMENTS folder. Here is the snippet that achieves this:&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroup&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProductComponents&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;INSTALLFOLDER&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. --&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- &amp;lt;Component Id=&quot;ProductComponent&quot;&amp;gt; --&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- TODO: Insert files, registry keys, and other resources here. --&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;rem&quot;&gt;&amp;lt;!-- &amp;lt;/Component&amp;gt; --&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroup&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroup&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;DocuComponents&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ACMEDOCUFOLDER&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Component&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ReadmeFile&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Guid&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;{YOURGUID-994F-49C0-A7AC-53D1571A295A}&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
         &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;File&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;readme.txt&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;readme.txt&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Source&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;..\Acme.Lib\readme.txt&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroup&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Fragment&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;/pre&gt;
&lt;p&gt;Note that again I left the default component group untouched (Id=”ProductComponents”). Instead I created a new component group and gave it the id ‘DocuCompoents’. Then I moved the component ‘ReadmeFile’ from the former to the latter.&lt;/p&gt;
&lt;p&gt;We are not quite finished yet. One item is missing. The installer does not yet know that it should include this new component / component group into the installer. So here is what we need to do to accomplish that:&lt;/p&gt;&lt;pre class=&quot;csharpcode&quot;&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Product&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;*&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme.Setup&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Language&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1033&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Version&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1.0.0.0&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Manufacturer&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;UpgradeCode&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;YOURGUID-269e-4795-97d7-a392d75749fb&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Package&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;InstallerVersion&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;200&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Compressed&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;yes&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;InstallScope&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;perMachine&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;MajorUpgrade&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;DowngradeErrorMessage&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;A newer version of [ProductName] is already installed.&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;MediaTemplate&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;

   &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;PropertyRef&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;WIX_DIR_COMMON_DOCUMENTS&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;

   &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Feature&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProductFeature&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Title&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;Acme.Setup&quot;&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Level&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroupRef&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;ProductComponents&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;ComponentGroupRef&lt;/span&gt; &lt;span class=&quot;attr&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;=&quot;DocuComponents&quot;&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Feature&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;kwrd&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;html&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;kwrd&quot;&gt;&amp;gt;&lt;br&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type=&quot;text/css&quot;&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, &quot;Courier New&quot;, courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;

&lt;p&gt;Once you build and execute the resulting installer then the result will look as follows:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi61id5gZikyk-syv9pQh9VOgZn-XPXBKrW7qoj80jJwqNBUV9fo6YWO-dNVlfMbCB3PPky_UyhkaCq5kpiO4v5iCVADYeP9-orN_WxmLFB_XjQ4sc0kAfmwxR9okLhuKJXQuWY/s1600-h/image%25255B29%25255D.png&quot;&gt;&lt;img title=&quot;image&quot; style=&quot;border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiltB3bd_fgBJ9daG7atlzNmMrXkpaQPOe64YwsefV8nPdkBFb62kNtw5xM2FTKw8BB7XHz91lSZFStq_sZUe40nV5sq1MxhUQqvri_ujP8QDT02OR0TMNdUjbHFpdBLElk6k7K/?imgmax=800&quot; width=&quot;490&quot; height=&quot;263&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And this screenshot demonstrates that we have accomplished what we wanted: We successfully installed a folder and a file into the “Public Documents” folder.&lt;/p&gt;
&lt;p&gt;If you’d like the full source code of this solution please send an email to manfredmlange at gmail dot com.&lt;/p&gt;
&lt;p&gt;Happy coding!&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/8093612001884765800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2013/05/wix-installing-files-to-public.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8093612001884765800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8093612001884765800'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2013/05/wix-installing-files-to-public.html' title='WiX: Installing Files to Public Documents Folder'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjLgYDC6sgbBGhAdNy0Ry0Cn1Vu5PUKfaZ910jytpck7bJE61YGTdc8ImoABNnFjDnlt1eUZw-oeZZLjC4hpbyKmo1zUBc-hnC1Q0nEWE9salgX1lWJzsNa2eZJcdRnOMFDqoN/s72-c?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-474243724683936359</id><published>2013-04-07T08:43:00.001+12:00</published><updated>2013-04-07T08:45:23.781+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>Outstanding Support</title><content type='html'>&lt;p&gt;I had an issue with JIRA/Greenhopper today and contacted Atlassian’s support at 08:12 am (it’s Sunday here). At 08:17 am I had a message from a human being saying that he was investigating. Communication was flowing and at 08:34 am the issue was resolved. Total time spent: 17 minutes from reporting the problem.&lt;/p&gt; &lt;p&gt;The way I have experienced working with Atlassian they will probably say this is just the normal way they operate. And I agree they have always been very easy to work with.&lt;/p&gt; &lt;p&gt;I’m mentioning it here since I think their support can serve as an example for a lot of other companies. I trust that you can easily create your own list of those who can improve.&lt;/p&gt; &lt;p&gt;Bottom line: Today I experienced excellent support from Atlassian … as usual. Thank you, Nick!&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/474243724683936359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2013/04/outstanding-support.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/474243724683936359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/474243724683936359'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2013/04/outstanding-support.html' title='Outstanding Support'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-8977725333195058391</id><published>2013-03-16T19:24:00.001+13:00</published><updated>2013-03-16T19:29:29.374+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>Ubuntu 12.10 in Virtual Box on Windows 7</title><content type='html'>&lt;p&gt;Today I spent some time to get Ubuntu 12.10 installed as a virtual machine using VirtualBox. That as such wasn’t the challenge. For example a pretty good description can be found at &lt;a href=&quot;http://www.sevenforums.com/tutorials/130922-linux-install-windows-7-virtual-machine-using-virtualbox.html&quot;&gt;Windows Seven Forums&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Getting the guest additions installed was the problem. Quite a few sources suggested to use VirtualBox’s menu “Devices” – “Install Guest Additions…” However, what was offered as a solution didn’t work in my case. Note that I’m not a Linux or VirtualBox expert, so my lack of knowledge might have been the reason.&lt;/p&gt; &lt;p&gt;After quite some search I found a very good description on &lt;a href=&quot;http://www.sysprobs.com/&quot;&gt;Sysprobs&lt;/a&gt;. Dinesh did a fantastic job with his &lt;a href=&quot;http://www.sysprobs.com/latest-ubuntu-12-10-on-virtualbox-4-2-installed-guest-additions&quot;&gt;blog post&lt;/a&gt;. Now I can resize the VM’s window any way I like and the VM’s screen adjusts properly. Almost seamless integration Nice!&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/8977725333195058391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2013/03/ubuntu-1210-in-virtual-box-on-windows-7.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8977725333195058391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8977725333195058391'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2013/03/ubuntu-1210-in-virtual-box-on-windows-7.html' title='Ubuntu 12.10 in Virtual Box on Windows 7'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-6357742876228808982</id><published>2012-12-06T19:07:00.001+13:00</published><updated>2012-12-06T19:10:14.906+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>csUnit Interim Release 2.8.4723</title><content type='html'>&lt;p&gt;We have made available a new release of csUnit. This is an interim release with the version number 2.8.4723 and can be found on &lt;a href=&quot;https://github.com/ManfredLange/csUnit/downloads&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;This release requires .NET 4.5. It doesn’t have an installer and no Visual Studio plugin. The download is a zip file that you need to extract into a folder then run csUnitRunner from there. If you encounter an issue please log the issue &lt;a href=&quot;https://github.com/ManfredLange/csUnit/issues&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; with detailed info about your environment, the version of csUnit you are using and steps to reproduce.&lt;/p&gt; &lt;p&gt;We intend to create a WiX based installer next.&lt;/p&gt; &lt;p&gt;For more info about csUnit check out &lt;a href=&quot;http://www.csunit.org&quot; target=&quot;_blank&quot;&gt;csUnit’s homepage&lt;/a&gt;.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/6357742876228808982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2012/12/csunit-interim-release-284723.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6357742876228808982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6357742876228808982'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2012/12/csunit-interim-release-284723.html' title='csUnit Interim Release 2.8.4723'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-4861656698035001804</id><published>2012-09-15T10:31:00.001+12:00</published><updated>2012-09-15T10:31:56.191+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>Free Azure Storage Explorers</title><content type='html'>&lt;p&gt;When working with Azure you’ll eventually work with storage (blob, table, …). Wouldn’t it be nice if you had a simple way to browse through the content of your Azure storage? And wouldn’t it be nice if you also use the same tool to access your local Azure storage emulator?&lt;/p&gt; &lt;p&gt;Here are two tools that do exactly that. And in addition they are free.&lt;/p&gt; &lt;p&gt;The first tool is “&lt;a href=&quot;http://azurestorageexplorer.codeplex.com/&quot; target=&quot;_blank&quot;&gt;Azure Storage Explorer&lt;/a&gt;” provided by &lt;a href=&quot;http://cloud.neudesic.com/&quot; target=&quot;_blank&quot;&gt;Neudesic&lt;/a&gt;. This tool is open source, hosted on Codeplex. It is licensed under the “&lt;a href=&quot;http://azurestorageexplorer.codeplex.com/license&quot; target=&quot;_blank&quot;&gt;Common Development and Distribution License (CDDL)&lt;/a&gt;”. I’ve used this tool for several months now and was very valuable, allowing moving files, copying files, creating containers, deleting containers, etc. You can set up all your storage accounts, including local development storage and then access it without having to enter credentials again. It remembers your access keys.&lt;/p&gt; &lt;p&gt;The second tool is “&lt;a href=&quot;http://www.cloudberrylab.com/free-microsoft-azure-explorer.aspx&quot; target=&quot;_blank&quot;&gt;CloudBerry Explorer for Windows Azure&lt;/a&gt;” provided by &lt;a href=&quot;http://www.cloudberrylab.com&quot; target=&quot;_blank&quot;&gt;CloudBerry&lt;/a&gt;. This tools is available as freeware. I just downloaded it and played with it for a little while, so can’t provide any detailed insights yet.&lt;/p&gt; &lt;p&gt;Having a tool for browsing your Azure storage content is a handy tool for developers as well. That’s why I thought it would be worth mentioning here.&lt;/p&gt; &lt;p&gt;Happy coding!&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/4861656698035001804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2012/09/free-azure-storage-explorers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/4861656698035001804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/4861656698035001804'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2012/09/free-azure-storage-explorers.html' title='Free Azure Storage Explorers'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-5293993419034534255</id><published>2012-09-11T20:01:00.001+12:00</published><updated>2012-09-11T21:11:22.383+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Process"/><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>NullReferenceException in Html.ValidationSummary()</title><content type='html'>&lt;p&gt;I was implementing a view using ASP.NET MVC, MVC 4 in this case but I suspect the version is irrelevant. I received a NullReferenceException when any validation failed, ie the model state was invalid.&lt;/p&gt; &lt;p&gt;The stack trace was close to useless and looked similar to the following:&lt;/p&gt; &lt;p&gt;at ASP._Page_Views_Issue_Create_cshtml.Execute() in c:\projects\au\AgileTraxx\Web\Views\Issue\Create.cshtml:line 26&lt;br&gt;at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()&lt;br&gt;at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()&lt;br&gt;at System.Web.WebPages.StartPage.RunPage()&lt;br&gt;at System.Web.WebPages.StartPage.ExecutePageHierarchy()&lt;br&gt;at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)&lt;br&gt;at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)&lt;br&gt;at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)&lt;br&gt;at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)&lt;br&gt;at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)&lt;br&gt;at System.Web.Mvc.ControllerActionInvoker.&amp;lt;&amp;gt;c__DisplayClass1a.&amp;lt;InvokeActionResultWithFilters&amp;gt;b__17()&lt;br&gt;at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation)&lt;br&gt;&lt;/p&gt; &lt;p&gt;Line 26 which the stack trace referring to was:&lt;/p&gt; &lt;p&gt;Html.ValidationSummary();&lt;/p&gt; &lt;p&gt;This wasn’t much help either. It took me a lot of experimentation to find out that in this particular case the property Model of the view was null. Once I set the model for this view, it all went nicely.&lt;/p&gt; &lt;p&gt;Note that not always it is obvious from scanning the code that one didn’t set the model for a view. Therefore I’m blogging my experience here and to give the recommendation that should you encounter the same or similar behavior, to the following:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Set a breakpoint on the line where the exception is thrown.  &lt;li&gt;Debug the application  &lt;li&gt;When the breakpoint is hit, enter “Model” in the “Immediate Window” in Visual Studio and check whether it outputs “null”.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Happy coding!&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/5293993419034534255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2012/09/nullreferenceexception-in.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/5293993419034534255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/5293993419034534255'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2012/09/nullreferenceexception-in.html' title='NullReferenceException in Html.ValidationSummary()'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-2561130601551302246</id><published>2012-04-21T12:34:00.001+12:00</published><updated>2012-04-21T12:35:39.835+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C# Guidelines"/><title type='text'>ASP.NET: Base Directory and Developer Tests</title><content type='html'>&lt;p&gt;Assume that in your ASP.NET application you need to access a file that is part of the deployed web site. On the other hand you would like to also run some developer tests. &lt;/p&gt; &lt;p&gt;The way I like to organize developer tests is putting them in a separate project and a separate assembly. For example for an ASP.NET project “MySite” I would have a second project called “MySite.Tests”. In the test project I then reference the “MySite” project which gives me direct access to all code inside of “MySite”. Typically give all projects a strong name and therefore can make internals of “MySite” visible to code in “MySite.Tests” by placing the InternalsVisibleToAttribute on the “MySite” assembly.&lt;/p&gt; &lt;p&gt;The challenge now with accessing the file is that depending on whether they are run from within an ASP.NET server (IIS or WebDev.WebServer) or within a unit test runner, finding the root folder (or base directory) can be tricky in some cases.&lt;/p&gt; &lt;p&gt;For example we could use a solution based on the MapPath method of the HttpContext.Current.Server object. This is described in more details in an &lt;a href=&quot;http://stackoverflow.com/a/5908383/411428&quot; target=&quot;_blank&quot;&gt;answer on StackOverflow&lt;/a&gt; and works when an HttpContext is available. When the same code is run in a unit test runner HttpContext.Current is null (Controller.HttpContext in MVC), so this solution wouldn’t work.&lt;/p&gt; &lt;p&gt;The solution that I have chosen and that works so far is based on the application domain. The following code is all that is required and it works in both IIS, WebDev.WebServer as well as when executed within a unit test runner:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;var domainRoot = AppDomain.CurrentDomain.BaseDirectory;
var configFile = Path.Combine(domainRoot, Common.DbSettingsFile);

&lt;/pre&gt;
&lt;p&gt;Happy coding!&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/2561130601551302246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2012/04/aspnet-base-directory-and-developer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/2561130601551302246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/2561130601551302246'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2012/04/aspnet-base-directory-and-developer.html' title='ASP.NET: Base Directory and Developer Tests'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-5988283050906348992</id><published>2012-04-18T09:37:00.001+12:00</published><updated>2012-04-18T09:37:53.631+12:00</updated><title type='text'>MVC 3 and &amp;quot;Microsoft JScript runtime error: &amp;#39;jQuery&amp;#39; is undefined&amp;quot;</title><content type='html'>&lt;p&gt;In the course of working on an ASP.NET MVC 3 based project I updated jQuery via NuGet. This worked as expected, except for one view where the application then reported the error &quot;Microsoft JScript runtime error: &#39;jQuery&#39; is undefined&quot;.&lt;/p&gt; &lt;p&gt;The resolution was to check the Java Script references in the view that had the problem. It was also necessary to updated _Layout.cshtml as follows:&lt;/p&gt;&lt;pre class=&quot;brush: xml; highlight: [7,8];&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
   &amp;lt;meta charset=&quot;utf-8&quot; /&amp;gt;
   &amp;lt;title&amp;gt;@ViewBag.Title&amp;lt;/title&amp;gt;
   &amp;lt;link href=&quot;@Url.Content(&quot;~/Content/Site.css&quot;)&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&amp;gt;
   &amp;lt;script src=&quot;@Url.Content(&quot;~/Scripts/jquery-1.7.1.min.js&quot;)&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;
   &amp;lt;script src=&quot;@Url.Content(&quot;~/Scripts/modernizr-2.0.6-development-only.js&quot;)&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
   ...
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;After these changes it worked like a charm.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/5988283050906348992/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2012/04/mvc-3-and-jscript-runtime-error-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/5988283050906348992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/5988283050906348992'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2012/04/mvc-3-and-jscript-runtime-error-is.html' title='MVC 3 and &amp;quot;Microsoft JScript runtime error: &amp;#39;jQuery&amp;#39; is undefined&amp;quot;'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-4081958204619565791</id><published>2012-04-16T15:19:00.001+12:00</published><updated>2012-04-16T15:19:55.980+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>WiX 3.6 Beta Behavior When Building</title><content type='html'>&lt;p&gt;Just noticed an interesting behavior of a solution that contains about 20 projects and one WiX project. It would fail when using “Rebuild All” with some strange error in a wxs-file that compiled fine previously. When using “Rebuild” on the WiX project it would build just fine. This was reproducible at that point.&lt;/p&gt; &lt;p&gt;To resolve it I restarted Visual Studio and all was fine again. I couldn’t reproduce the issue. I guess that it was some add-in that got a pointer or reference mixed-up.&lt;/p&gt; &lt;p&gt;My setup is: Visual Studio 2010 Professional, ReSharper, dotCover, AnkhSVN, WiX 3.6 beta.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/4081958204619565791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2012/04/wix-36-beta-behavior-when-building.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/4081958204619565791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/4081958204619565791'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2012/04/wix-36-beta-behavior-when-building.html' title='WiX 3.6 Beta Behavior When Building'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-1376934430827505952</id><published>2012-04-09T12:08:00.001+12:00</published><updated>2012-04-09T17:00:36.918+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Business Logic Layer"/><category scheme="http://www.blogger.com/atom/ns#" term="Presentation Layer"/><title type='text'>More On Closing WCF Connections</title><content type='html'>&lt;p&gt;Some time ago I blogged about &lt;a href=&quot;http://manfredlange.blogspot.co.nz/2010/02/consuming-wcf-service.html&quot; target=&quot;_blank&quot;&gt;how to implement a WCF client in C#&lt;/a&gt; using VS2008. In particular I mentioned that implementing the client side code with a using statement may potentially lead to problems as – against their own advice – Microsoft chose to implement the Dispose() method of class System.ServiceModel.ClientBase&amp;lt;TChannel&amp;gt; in such a way that it can throw exceptions. (Dispose() implementations should not throw exceptions.) This implementation that violates Microsoft’s own guideline is also described &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa355056.aspx&quot; target=&quot;_blank&quot;&gt;in an article&lt;/a&gt; where Microsoft recommends not to use “using” when working with WCF clients.&lt;/p&gt; &lt;p&gt;In this blog post I’ll revisit the options for handling client side code. In the meantime I’ve moved to VS2010 and I’m using .NET 4.0. To get started let’s recall the code from back then:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;var client = new PondServiceClient();

try {
   _pondStatusMessage.Text = _pondNameTextBox.Text +
      (client.IsFrozen(_pondNameTextBox.Text) ?
      &quot; is frozen.&quot; : &quot; free of ice.&quot;);
   client.Close();
}
catch (CommunicationException ex) {
   // Handle exception
   client.Abort();
}
catch (TimeoutException ex) {
   // Handle exception
   client.Abort();
}
catch (Exception ex) {
   // Handle exception
   client.Abort();
}&lt;/pre&gt;
&lt;p&gt;So the canonical form (also described on MSDN) is to check for CommunicationException and TimeoutException. If the service defines Service Fault&#39;s you may want to catch those exceptions (FaultException&amp;lt;T&amp;gt;) as well.&lt;/p&gt;
&lt;p&gt;It would be great if there were ways to fix this problem as there is one more issue with using the canonical way. Imagine you have lots of touch points between your client and a service. Wouldn’t it be nice if you could avoid all that try-catch business? It looks like a lot of code duplication after all.&lt;/p&gt;
&lt;h3&gt;Marc Gravell’s Solution&lt;/h3&gt;
&lt;p&gt;One possible solution is described by &lt;a href=&quot;http://marcgravell.blogspot.co.nz/2008/11/dontdontuse-using.html&quot; target=&quot;_blank&quot;&gt;Marc Gravell in his blog&lt;/a&gt;. He makes extensive use of generics. Using Marc’s solution the above code would look something like this:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;using (var client = new Proxy().Wrap()) {
   _pondStatusMessage.Text = _pondNameTextBox.Text +
      (client.BaseObject.IsFrozen(_pondNameTextBox.Text) ?
      &quot; is frozen.&quot; : &quot; free of ice.&quot;);
}&lt;/pre&gt;
&lt;p&gt;I agree with Marc that this solution would be safe, easy to call and would eliminate the code duplications. His solution calls the service client’s Dispose() method (ClientBase&amp;lt;TChannel&amp;gt;.Dispose()) but wraps it inside a try-catch construct. If an exception is thrown by the Dispose() it is swallowed.&lt;/p&gt;
&lt;p&gt;The first concern I have with this solution is that it doesn’t call Abort() and Close() respectively as per Microsoft’s recommendation. It just swallows the exception that might be thrown by the Dispose method.&lt;/p&gt;
&lt;p&gt;The second concern I have is that the expression “new Proxy().Wrap()” doesn’t appear very intuitive and easy to understand. This is probably a minor point as with more experience in using this solution one can will become used to it.&lt;/p&gt;
&lt;h3&gt;Jeremy Jameson’s Solution&lt;/h3&gt;
&lt;p&gt;Another option can be found at &lt;a href=&quot;http://www.technologytoolbox.com/blog/jjameson/archive/2010/03/18/avoiding-problems-with-the-using-statement-and-wcf-service-proxies.aspx&quot; target=&quot;_blank&quot;&gt;Jeremy Jameson’s blog&lt;/a&gt;. Jeremy suggests to derive a class and add a new implementation for Dispose(). To stay with the pond service example, that new class would then look as follows:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;public class PondServiceClientWithDisposeFix 
   : PondServiceClient, IDisposable {
   void IDisposable.Dispose() {
      if (this.State == CommunicationState.Faulted) {
         this.Abort();
      }
      else if (this.State != CommunicationState.Closed) {
         this.Close();
      }
   }
}&lt;/pre&gt;
&lt;p&gt;With this class in place the implementation of the client side could then be re-written as follows:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;using(var client = new PondServiceClientWithDisposeFix()) {
   _pondStatusMessage.Text = _pondNameTextBox.Text +
      (client.IsFrozen(_pondNameTextBox.Text) ?
      &quot; is frozen.&quot; : &quot; free of ice.&quot;);
}&lt;/pre&gt;
&lt;p&gt;Very elegant, easy to understand and correct by the looks of it. I was tempted to use this option if it wasn’t for a concern that I have with this. With reverse engineering it is possible to find out what ClientBase&amp;lt;TChannel&amp;gt;.Dispose() does. When Jeremy wrote his blog (March 2010) the Dispose() implementation simply called Close().&lt;/p&gt;
&lt;p&gt;My concern is that the new implementation doesn’t call the base class implementation at all. By the way the PondServiceClient class is declared partial so the Dispose method could probably be implemented as an extension method as well. As long as the base class implementation is not called, this couldn’t resolve my concern, though. What if Microsoft at any time decides to change the implementation of ClientBase&amp;lt;TChannel&amp;gt;.Dispose()? This kind of change typically happens – thanks, Murphy! – we we expect it the least.&lt;/p&gt;
&lt;p&gt;Even if the implementation was never changed, there is a small thing that concerns me. &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms733912.aspx&quot; target=&quot;_blank&quot;&gt;Microsoft has included a little note&lt;/a&gt; regarding the use of the ClientBase&amp;lt;TChannel&amp;gt;.State property:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixn8Ag_Vacn6wSihIAsiHevDW8xIlZtN4TssKcqu-Y9KKnZEroufjuzvOL7LHtgjTuU5HMSieGArfP3mn_UCJAqDD-SP3B0R2omBnpsieaKiFfuBCOLpQI73av1hlf6e-uncBQ/s1600-h/image%25255B3%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUKerxFqvJ9CkXRRzXDeN8-OJ-3yArQgIJ-rJiIGM3dfJTTxsYNir7OP8jGhmEqXVXuFEmddP2nBuR9IMfkkd3xRgKecCKB1u4IR0Ufu0vutXwzUqtpApFduPYhbZMR-knET5h/?imgmax=800&quot; width=&quot;395&quot; height=&quot;170&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So, Jeremy’s solution probably will work. But it is against Microsoft’s recommendation of not using the State property. In particular I get nervous because of the term “race condition”. If problems occur because of race conditions these are typically hard to find and resolve, therefore a very expensive type of issue.&lt;/p&gt;
&lt;p&gt;Therefore if we want to follow that recommendation we are back to square one. We would have to surround the use of ClientBase&amp;lt;TChannel&amp;gt; derived objects with boilerplate try-catch statements.&lt;/p&gt;
&lt;h3&gt;Using Anonymous Methods&lt;/h3&gt;
&lt;p&gt;Basically the problem is that in order to remove the code duplication a pair of code snipped has be executed before and after the service invocation. Proper handling of communication objects almost sounds like an aspect… so for a moment I even considered looking into libraries like &lt;a href=&quot;http://www.castleproject.org/dynamicproxy/index.html&quot; target=&quot;_blank&quot;&gt;DynamicProxy2&lt;/a&gt; or &lt;a href=&quot;http://www.ninject.org&quot; target=&quot;_blank&quot;&gt;Ninject&lt;/a&gt;. On second thought, though, these felt like overkill for something that appears very simple.&lt;/p&gt;
&lt;p&gt;Enter anonymous methods. Basically you can pass a block of code to a different method that does things, executes the block of code, maybe does other things, then returns. How does this apply to the code snippet for the pond service example above. Let’s try to highlight with colors what the boiler plate code is and what the code is that is different:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmo6pQ2IBAcxgHxEr2p967w6vTThmYajUtFgFTo71MCuuSvA8poslu_uSHdgVAHci4K8pFhEuefBML2FBPWZVDScGcPqYsn3grQhr2NNTszKmf3h6WMSQWIko7K9eo_z1VrSmj/s1600-h/image%25255B8%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4DKJff35K52mQQqe9gSGSP5FSU0n20WnMIYkv2PmiG7a5chGDsVi1GeLUv08Bg0AJuCzhfgZpmM-IC2u6lMMhXQo6bSXUScbeYbH5ygCC224eNUCKHnEdigPU3sC72xrB0evO/?imgmax=800&quot; width=&quot;351&quot; height=&quot;324&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The code within green rectangles is the actual implementation while the code in the orange rectangles is the boilerplate code. Note, how the orange pieces surround the second green piece.&lt;/p&gt;
&lt;p&gt;The way to simply this is using a class that works like an interceptor. I implemented a class called ServiceClientInterceptor and it’s main method now looks as follows, again using green and orange rectangles as above:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdy5OdssQShC6sE-W8VS48mmHPeFY5BXb-d-oQPVzEgPTAZX_Z9W0IKupY8x9Ss_z87l-y7A4zJBH1zWIgALgp56FfU8WumC29TEeVKpwAvAnl8BrpDlacT7AHIuhPZdVUg-XJ/s1600-h/image%25255B12%25255D.png&quot;&gt;&lt;img style=&quot;background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; padding-top: 0px&quot; title=&quot;image&quot; border=&quot;0&quot; alt=&quot;image&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUIFLmgivZPJiMmvrVALq_vaf_kTg5BhG-tVTCVqc2xG58ScYjTlE7-rWD8d8jNJ5mhoQxZL2pofTy9N-GKcxg86Xn0KVtdOP-1el6p28_SRmUO74oTtYSg5-9hQ6g1MG29V9G/?imgmax=800&quot; width=&quot;313&quot; height=&quot;307&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see the green rectangle simply invokes the function that was passed in. With the ServiceClientInterceptor in place you can now write the client side code as follows:&lt;/p&gt;&lt;pre class=&quot;brush: csharp; highlight: [1];&quot;&gt;using (var client = new PondServiceClient()) {
   new ServiceClientInterceptor(client).Invoke(() =&amp;gt; {
      _pondStatusMessage.Text = _pondNameTextBox.Text +
         (client.IsFrozen(_pondNameTextBox.Text) ?
         &quot; is frozen.&quot; : &quot; free of ice.&quot;);
   });
}&lt;/pre&gt;
&lt;p&gt;Line 2 in this example show the beginning of an anonymous method that is passed in as a parameter to the Invoke() method. The cool thing is that inside of the anonymous method you have access to the variables that are accessible at the point of where the anonymous method is defined. It is not limited to where the intercept invokes the execution of that anonymous method.&lt;/p&gt;
&lt;p&gt;As a result you can now wrap service invocations with try-catch statements without code duplication.&lt;pre&gt;&lt;/pre&gt;
&lt;p&gt;With this general concept working there are of course further questions that I haven’t covered in this blog post. For example, what if you want reuse the service client for further invocations in the same using block? What if you had multiple service clients that are used within the same anonymous method? I’ll leave these to you for further explorations as there several options in each case.&lt;/p&gt;
&lt;p&gt;The solution presented here meets the following requirements:&lt;/p&gt;
&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;Allows use of using construct 
&lt;li&gt;Properly closes or aborts WCF connections depending on exception thrown 
&lt;li&gt;Avoids code duplication 
&lt;li&gt;Does not make use of ClientBase&amp;lt;TChannel&amp;gt;.State property as per Microsoft’s recommendation&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;To complete this blog post, below is the full source for the ServiceClientInterceptor class. In that case I have changed the parameter type of the Invoke method to Action. In the screenshots above I still used ServiceMethod which had an identical definition but was the result of earlier experimentation. The Action delegate encapsulates a method that has no parameters and does not return a value. As always you are welcome to use this code at your own risk. &lt;/p&gt;
&lt;p&gt;If you know of a solution better than any of the ones mentioned in this post I&#39;d like to hear from you. Happy coding!&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;public class ServiceClientInterceptor {
   public ServiceClientInterceptor(
         ICommunicationObject serviceClient) {
      _serviceClient = serviceClient;
   }

   public void Invoke(Action func) {
      try {
         func.Invoke();
         _serviceClient.Close();
      }
      catch (CommunicationException ex) {
         _serviceClient.Abort();
         // Handling and/or re-throwing exception is 
         // application specific
      }
      catch (TimeoutException ex) {
         _serviceClient.Abort();
         // Handling and/or re-throwing exception is 
         // application specific
      }
      catch (Exception ex) {
         _serviceClient.Abort();
         // Handling and/or re-throwing exception is 
         // application specific
      }
   }

   private ICommunicationObject _serviceClient;
}&lt;/pre&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/1376934430827505952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2012/04/more-on-closing-wcf-connections.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/1376934430827505952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/1376934430827505952'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2012/04/more-on-closing-wcf-connections.html' title='More On Closing WCF Connections'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUKerxFqvJ9CkXRRzXDeN8-OJ-3yArQgIJ-rJiIGM3dfJTTxsYNir7OP8jGhmEqXVXuFEmddP2nBuR9IMfkkd3xRgKecCKB1u4IR0Ufu0vutXwzUqtpApFduPYhbZMR-knET5h/s72-c?imgmax=800" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-8594187139091335246</id><published>2012-03-03T14:42:00.001+13:00</published><updated>2012-03-03T14:42:30.959+13:00</updated><title type='text'>VisualBasic .NET and C#</title><content type='html'>&lt;p&gt;In case you need to compare language features of VB.NET and C#, you might find the following &lt;a href=&quot;http://www.harding.edu/fmccown/vbnet_csharp_comparison.html&quot; target=&quot;_blank&quot;&gt;URL&lt;/a&gt; helpful. It contains a quite detailed comparison of both languages.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/8594187139091335246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2012/03/visualbasic-net-and-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8594187139091335246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8594187139091335246'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2012/03/visualbasic-net-and-c.html' title='VisualBasic .NET and C#'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-6689608743205824188</id><published>2012-01-19T20:22:00.001+13:00</published><updated>2012-01-19T20:23:31.251+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>ReSharper Not Showing Any Tests?</title><content type='html'>&lt;p&gt;Version 6.x of ReSharper appears to have a tendency to forget about some tests in a solution once a while (at least once a day in my case). When using “Run All Tests From Solution” it can happen that it shows only a subset of them. In extreme cases it can happen that no tests are shown in the “Unit Tests Session” window.&lt;/p&gt; &lt;p&gt;I’ve noticed that the behavior becomes better after removing all other extensions. I don’t feel this is very practical. The extensions I use are AnkhSVN and Powertools and I’m using Visual Studio 2010 on a 64 bit Windows 7. All software are the latest released versions and has the most recent patches or service packs applied.&lt;/p&gt; &lt;p&gt;I reinstalled everything but that didn’t change the behavior. When I run all unit tests outside of Visual Studio, e.g. using &lt;a href=&quot;http://www.csunit.org&quot; target=&quot;_blank&quot;&gt;csUnit&lt;/a&gt;, it is all fine.&lt;/p&gt; &lt;p&gt;One way to resolve this is following these five steps:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Close Visual Studio&lt;/li&gt; &lt;li&gt;Delete the _ReSharper.* folder that is located in the folder containing your solution&lt;/li&gt; &lt;li&gt;Start Visual Studio&lt;/li&gt; &lt;li&gt;Reopen your solution&lt;/li&gt; &lt;li&gt;Select “Run all tests from Solution” from the ReSharper menu&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Since once in a while the web deployment functionality requires a restart of Visual Studio as well, I now have two triggers that may force me to restart Visual Studio.&lt;/p&gt; &lt;p&gt;Yes, it is annoying but at least now I have found this work around. Maybe it helps saving you some grief as well.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/6689608743205824188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2012/01/resharper-not-showing-any-tests.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6689608743205824188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6689608743205824188'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2012/01/resharper-not-showing-any-tests.html' title='ReSharper Not Showing Any Tests?'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-8775675133198815317</id><published>2011-12-28T18:38:00.001+13:00</published><updated>2011-12-28T18:49:13.369+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Technology"/><title type='text'>Ninject, Interception and out/ref arguments/parameters</title><content type='html'>&lt;p&gt;While implementing an aspect using &lt;a href=&quot;http://www.ninject.org&quot; target=&quot;_blank&quot;&gt;Ninject&lt;/a&gt; along with its Ninject.Extensions.Interception I found that it wouldn’t work with arguments (parameters) that are ‘out’ or ‘ref’ (‘out’ is just a special case of ‘ref’ really). I found a temporary solution at &lt;a href=&quot;http://www.codeproject.com/KB/cs/FastMethodInvoker.aspx?msg=2523854&quot; target=&quot;_blank&quot;&gt;CodeProject&lt;/a&gt; and in parallel submitted an issue on Github for the Ninject guys to have a look at. I expected this to take a few weeks or even months to be resolved. But they surprised me positively. Support for out/ref arguments/parameters was implemented within 5 hours. Remo, do you sleep at all?&lt;/p&gt; &lt;p&gt;Remo Gloor, one of the Ninject project contributors, responded with saying that the feature will be &lt;a href=&quot;https://github.com/ninject/ninject.extensions.interception/issues/5&quot; target=&quot;_blank&quot;&gt;included in Ninject 3.0&lt;/a&gt;. I checked and he had just committed the needed changes. Thank you, Remo, for the fast turn around! To confirm I updated my local sources from Github, compiled them and it all worked as expected. Sweet!&lt;/p&gt; &lt;p&gt;According to Remo, support for out / ref parameters / arguments will only be available when you use DynamicProxy2. If you want to make use of it prior to the 3.0 release of Ninject just pull the latest set of sources and build it yourself. Happy coding!&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/8775675133198815317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2011/12/ninject-interception-and-outref.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8775675133198815317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8775675133198815317'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2011/12/ninject-interception-and-outref.html' title='Ninject, Interception and out/ref arguments/parameters'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-6246739309294098745</id><published>2011-12-24T10:20:00.001+13:00</published><updated>2011-12-30T07:40:06.561+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Presentation Layer"/><category scheme="http://www.blogger.com/atom/ns#" term="Technology"/><title type='text'>Razor, MVC3, Client-Side Validation and Multiple Submit Buttons</title><content type='html'>&lt;p&gt;In a details view for creating a new model object I wanted to replace the Cancel link with a Cancel button. I wanted both to be buttons as I felt that to be more consistent. I didn’t realize that I would be up for a surprise when I placed two submit buttons into a single form since, of course, not matter what button I would click I would always end up in the same controller method. It was even worse. As client-side validation was enabled, clicking the Cancel button would perform client-side validation and not even make it to the server.&lt;/p&gt; &lt;p&gt;I googled and found a couple of ideas for how to handle multiple submit buttons. For example one type of suggestions is based on implementing a class derived from ActionMethodSelectorAttribute, for example &lt;a href=&quot;http://stackoverflow.com/questions/6353511/mvc-razor-buttons&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; or &lt;a href=&quot;http://www.dotnetcurry.com/(X(1)S(3n14c545mislet45ps2pyu55))/ShowArticle.aspx?ID=724&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. Another type of suggestions is based on implementing a class derived from ActionNameSelectorAttribute, for example &lt;a href=&quot;http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;I couldn’t get any of these to work the way I wanted. I found that they would work only when I disabled client-side validation or JavaScript on the client altogether. Only in these cases, and by giving the submit button a name using the ‘name’ attribute, would the button value be included in the request. Therefore this was just a partial solution as I wanted to support both scenarios (JavaScript disabled, JavaScript enabled). I tried the actionmethod attribute on the input element but either I used it incorrectly or the handling of this new HTML 5 element is not yet correctly handled by either the browsers or MVC on the server. I didn’t investigate this in more detail.&lt;/p&gt; &lt;p&gt;Here is the solution that worked for me.&lt;/p&gt; &lt;p&gt;First I implemented a JavaScript function which I placed at the end of the view (.cshtml):&lt;/p&gt;&lt;pre class=&quot;brush: js;&quot;&gt;&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
   function OnFormButtonClick(action, validate) {
      if (!validate) {
         document.forms[0].noValidate = true;
         document.forms[0].action = &#39;&#39; + action;
         document.forms[0].submit();
      }
}
&amp;lt;/script&amp;gt;&lt;/pre&gt;
&lt;p&gt;The first parameter of this short method is the name of the action (controller method) to be invoked on the server side while the second parameter determines whether or not to validate on the client side. Of course the latter would only kick in when JavaScript is enabled on the client side. If you want to use multiple submit buttons in several place you may want to put this function in a shared file such as ‘_Layout.cshtml’ or similar.&lt;/p&gt;
&lt;p&gt;With the JavaScript function in place I then added the two submit buttons to the Razor view (HTML form) as follows:&lt;/p&gt;&lt;pre class=&quot;brush: xml;&quot;&gt;&amp;lt;p&amp;gt;
   &amp;lt;input type=&quot;submit&quot; value=&quot;Create&quot; name=&quot;button&quot;
    onclick=&quot;OnFormButtonClick(&#39;Create&#39;, true);&quot; /&amp;gt;
   &amp;lt;input type=&quot;submit&quot; value=&quot;Cancel&quot; name=&quot;button&quot;
    onclick=&quot;OnFormButtonClick(&#39;Cancel&#39;, false);&quot; /&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This would now work with JavaScript enabled on the client. How about the scenario when JavaScript was disabled? In that case submitting the form would always submit to the same action (‘Create’ in my case) no matter what button was clicked. Some server side code was required to distinguish this. This is the point I added a class which is derived from ActionNameSelectorAttribute:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;/// &amp;lt;summary&amp;gt;
/// Attribute that helps MVC with selecting the proper method when multiple submit buttons
/// exist in a single form.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;remarks&amp;gt;The implementation is partially based on  &amp;lt;/remarks&amp;gt;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MultiSubmitButtonAttribute : ActionNameSelectorAttribute {
   public override bool IsValidName(ControllerContext controllerContext, 
                                    string actionName, 
                                    MethodInfo methodInfo) {
      // Implementation derived from:
      // http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx
      if (controllerContext.RequestContext.HttpContext.Request[&quot;button&quot;] != null) {
         // JavaScript disabled.
         return controllerContext.RequestContext.HttpContext.Request[&quot;button&quot;] == methodInfo.Name;
      }

      return actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase) 
         || actionName.Equals(&quot;Action&quot;, StringComparison.InvariantCultureIgnoreCase);
   }
}&lt;/pre&gt;
&lt;p&gt;The first if()-statement in this implementation yields to true only if JavaScript is disabled on the client. In that case the request contains the information about which submit button was clicked and this can be compared to the name of the controller method (bear with me for a little longer to see how this will work). Having this new attribute available I was now able to add it to the controller methods handling the two cases (‘Create’ and ‘Cancel’):&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;[HttpPost]
[MultiSubmitButton]
public ActionResult Create(FormCollection collection) {
   // TODO: insert your &#39;Create&#39; logic here
   return RedirectToAction(&quot;Index&quot;);
}

[HttpPost]
[MultiSubmitButton]
public ActionResult Cancel() {
   return RedirectToAction(&quot;Index&quot;);
}&lt;/pre&gt;
&lt;p&gt;When MVC tries to route the action to a controller method it will now also invoke the IsValidName method in the MultiSubmitButtonAttribute class. The two scenarios now work as follows:&lt;/p&gt;
&lt;p&gt;Case 1 - JavaScript enabled: The little JavaScript function is executed on the client side and an appropriate action will be requested. The action is simply routed to the controller method of the same name. Depending on the second parameter of the call to the JavaScript function (and subject to server side settings in web.config) client-side validation is executed or not.&lt;/p&gt;
&lt;p&gt;Case 2 – JavaScript disabled: The client includes the name of the submit button and the MultiSubmitButtonAttribute helps MVC to select the correct controller method.&lt;/p&gt;
&lt;h2&gt;Extending HtmlHelper to Simplify View Implementation&lt;/h2&gt;
&lt;p&gt;There is a way to simplify the view implementation by extending the HtmlHelper class as follows:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;public static class HtmlHelperExtensions {
   public static MvcHtmlString SubmitButton&amp;lt;T&amp;gt;(this HtmlHelper&amp;lt;T&amp;gt; helper, string value, string action, bool validate) {
      return new MvcHtmlString(String.Format(&quot;&amp;lt;input type=\&quot;submit\&quot; value=\&quot;{0}\&quot; name=\&quot;button\&quot; onclick=\&quot;OnFormButtonClick(&#39;{1}&#39;, {2});\&quot; /&amp;gt;&quot;, value, action, validate ? &quot;true&quot; : &quot;false&quot;));
   }
}&lt;/pre&gt;
&lt;p&gt;With this the submit buttons can be coded like this:&lt;/p&gt;&lt;pre class=&quot;brush: xml;&quot;&gt;@* Namespace of the HtmlHelper.SubmitButton() implementation: *@
@using Web.Helpers; 

... other code for Razor based view

&amp;lt;p&amp;gt;
   @Html.SubmitButton(&quot;Create&quot;, &quot;Create&quot;, true)
   @Html.SubmitButton(&quot;Cancel&quot;, &quot;Cancel&quot;, false)
&amp;lt;/p&amp;gt;&lt;/pre&gt;
&lt;p&gt;Note that although it appears as if the first two parameters here are duplicated, they are not. The first parameter is the label that appears on the submit button and you may want to localize it. The second parameter is the name of the action which you typically don’t want to change. Even if everything is in the same language (e.g. English) they can be the same but don’t have to.&lt;/p&gt;
&lt;h2&gt;Automatically Injecting JavaScript&lt;/h2&gt;
&lt;p&gt;So far the solution requires manually adding the OnFormButtonClick() function either to the Razor view or to have it in some shared file. I would like to remove this by making the HtmlHelper.SubmitButton&amp;lt;T&amp;gt;() implementation a little smarter:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;public static class HtmlHelperExtensions {
   public static MvcHtmlString SubmitButton&amp;lt;T&amp;gt;(this HtmlHelper&amp;lt;T&amp;gt; helper, string value, string action, bool validate) {
      var javaScript = string.Empty;
      const string functionName = &quot;_OnFormButtonClicked&quot;;
      if (!helper.ViewData.ContainsKey(functionName)) {
         helper.ViewData.Add(functionName, true);
         const string linefeed = &quot; \n\r&quot;;
         // Inspiration for the following JavaScript function from:
         // http://www.javascript-coder.com/html-form/html-form-action.phtml
         javaScript = &quot;&amp;lt;script type=\&quot;text/javascript\&quot;&amp;gt;&quot; + linefeed
                    + &quot;   function &quot; + functionName + &quot;(action, validate) {&quot; + linefeed
                    + &quot;      if (!validate) {&quot; + linefeed
                    + &quot;         document.forms[0].noValidate = true;&quot; + linefeed
                    + &quot;         document.forms[0].action = &#39;&#39; + action;&quot; + linefeed
                    + &quot;         document.forms[0].submit();&quot; + linefeed
                    + &quot;      }&quot; + linefeed
                    + &quot;   }&quot; + linefeed
                    + &quot;&amp;lt;/script&amp;gt;&quot; + linefeed;
      }
      return new MvcHtmlString(String.Format(&quot;{0}&amp;lt;input type=\&quot;submit\&quot; value=\&quot;{1}\&quot; name=\&quot;button\&quot; onclick=\&quot;{2}(&#39;{3}&#39;, {4});\&quot; /&amp;gt;&quot;, javaScript, value, functionName, action, validate ? &quot;true&quot; : &quot;false&quot;));
   }
}&lt;/pre&gt;
&lt;p&gt;The basic idea is that if the JavaScript function doesn’t exist yet in the view this code adds it. Then it adds one key to the ViewData. If that key is already present this code assumes the JavaScript function has already been added. With this, the JavaScript function can now be removed from the view and all that is needed is this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;MultiSubmitButtonAttribute applied to appropriate controller methods 
&lt;li&gt;Use of HtmlHelper.SubmitButton() in view definition&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;The JavaScript injection is taken care of automatically. Happy coding!&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/6246739309294098745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2011/12/razor-mvc3-client-side-validation-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6246739309294098745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/6246739309294098745'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2011/12/razor-mvc3-client-side-validation-and.html' title='Razor, MVC3, Client-Side Validation and Multiple Submit Buttons'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-4300115420818664957</id><published>2011-11-28T22:11:00.001+13:00</published><updated>2011-11-28T22:17:07.324+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Data Access Layer"/><title type='text'>Automapping with Fluent NHibernate: ShouldMap() implementation</title><content type='html'>&lt;p&gt;When you use the automapping feature of &lt;a href=&quot;http://fluentnhibernate.org/&quot; target=&quot;_blank&quot;&gt;Fluent NHibernate&lt;/a&gt; you will very quickly encounter a class called DefaultAutomappingConfiguration. This is the base class for your own automapping configuration class which you want to implement to control certain aspects of the automapping feature.&lt;/p&gt; &lt;p&gt;During startup of your application you have to provide &lt;a href=&quot;http://nhforge.org&quot; target=&quot;_blank&quot;&gt;NHibernate&lt;/a&gt; with information about how to map your domain classes to the database schema and back. Fluent NHibernate allows doing this automatically. Well, most of the time. There are cases when you want to be a little more specific with regards to those automatically created mappings.&lt;/p&gt; &lt;p&gt;The code you want to execute during startup looks similar to the following:&lt;/p&gt;&lt;pre class=&quot;brush: csharp; highlight: [9];&quot;&gt;private static ISessionFactory CreateSessionFactory() {
  var rawConfig = new Configuration();
  rawConfig.SetNamingStrategy(new PostgresNamingStrategy());
  var sessionFactory = Fluently.Configure(rawConfig)
    .Database(PostgreSQLConfiguration.PostgreSQL82
      .ConnectionString(Common.DatabaseConnectionString))
    .Mappings(m =&amp;gt; m.AutoMappings
      .Add(AutoMap
        .AssemblyOf&amp;lt;Customer&amp;gt;(new DbMappingConfiguration())
      .Conventions.Add(ForeignKey.EndsWith(&quot;Id&quot;))));
   return sessionFactory.BuildSessionFactory();
}
&lt;/pre&gt;
&lt;p&gt;The interesting piece in this case is line 9 where you provide the assembly that contains all your domain classes that you want to map. In this case you only need to provide one such class and Fluent NHibernate will also try to automatically map all other types that it can find in that assembly. Sometimes this is exactly what you want. In other cases you may not want to map all of the classes. Enter the DefaultMappingConfiguration class.&lt;/p&gt;
&lt;p&gt;You can implement you own mapping configuration by deriving from DefaultMappingConfiguration. You can override just the aspects that you want to change, everything else is taken care of by the default implementation.&lt;/p&gt;
&lt;p&gt;In this post I want to show one way for controlling which classes are mapped. A simplistic approach would be implementing your custom mapping configuration as follows:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;public class DbMappingConfiguration 
    : DefaultAutomappingConfiguration {
  public override bool ShouldMap(Type type) {
    return type.Equals(typeof(Customer))
      || type.Equals(typeof(Order))
      || type.Equals(typeof(Address))
      || type.Equals(typeof(Invoice));
  }
}
&lt;/pre&gt;
&lt;p&gt;This works. However as you can imagine this is not very intuitive and you will have to maintain this code as you modify your domain. Each time you add, remove or rename any of your domain classes you will have to update this method (admittedly the renaming is not a problem if you use a refactoring tool).&lt;/p&gt;
&lt;p&gt;So let’s think of a better solution. The one I want to present here is based on a marker attribute. The implementation PersistentDomainClassAttribute is very simple:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;[AttributeUsage(AttributeTargets.Class, 
                AllowMultiple = false, 
                Inherited = false)]
public class PersistentDomainClassAttribute 
  : Attribute {
}
&lt;/pre&gt;
&lt;p&gt;The usage is fairly simple, too. Here is an example:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;[PersistentDomainClass]
public class Customer {
  public virtual Guid Id { get; private set; }
  public virtual string FirstName { get; set; }
  public virtual string LastName { get; set; }
}
&lt;/pre&gt;
&lt;p&gt;Having this in place on all domain classes the custom mapping configuration can now be simplified as follows using a generic implementation:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;public class DbMappingConfiguration 
   : DefaultAutomappingConfiguration {
  public override bool ShouldMap(Type type) {
    var attr = type.GetCustomAttributes(
                  typeof(PersistentDomainClassAttribute),
                  true);
    return attr.Length &amp;gt; 0;
  }
}
&lt;/pre&gt;
&lt;p&gt;As a result you now have a solution that lets you choose which domain classes to make persistent. At the same time you no longer have to maintain the ShouldMap() implementation of your custom mapping configuration either.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/4300115420818664957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2011/11/automapping-with-fluent-nhibernate.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/4300115420818664957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/4300115420818664957'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2011/11/automapping-with-fluent-nhibernate.html' title='Automapping with Fluent NHibernate: ShouldMap() implementation'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-1353491214807774250</id><published>2011-11-27T13:30:00.001+13:00</published><updated>2011-11-27T13:30:56.258+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>Behavior of DirectoryInfo.Delete and Directory.Exists: Directories reappear!?</title><content type='html'>&lt;p&gt;Please note that the following may be a corner case or an isolated case. If not then something is not quite right with running NUnit based test suites from within Visual Studio 2010 using ReSharper 6. Unfortunately I don’t have proof either way but I still wanted to share my observation just in case you have encountered a similar issue.&lt;/p&gt; &lt;p&gt;A couple of weeks ago I wrote some test code that cleaned up folders after tests were executed. The code looked as follows:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;public static void CleanUpFolders(
                    List&amp;lt;DirectoryInfo&amp;gt; directoryInfos) {
   foreach (var directoryInfo in directoryInfos) {
      foreach (var file in directoryInfo.GetFiles(&quot;*&quot;, 
                            SearchOption.AllDirectories)) {
         file.IsReadOnly = false;
      }
      directoryInfo.Delete(true);
   }

   foreach (var directoryInfo in directoryInfos) {
      Assert.IsFalse(Directory.Exists(directoryInfo.FullName));
   }

   directoryInfos.Clear();
}
&lt;/pre&gt;
&lt;p&gt;For each directoryInfo in the collection the code iterates through all files and sets the read-only attribute to false for each of them. Then the directory is deleted with all its contents.&lt;/p&gt;
&lt;p&gt;Then I executed the test suite from within Visual Studio 2010 using ReSharper 6. It turned out that in some cases the assertion in the above code would fail. Despite the directories having been deleted the call to Directory.Exists would return true! So for some reasons the directory was deleted but then it wasn’t. When I reran the tests sometimes this assertion would fail and sometimes it wouldn’t. There were days where it was fine and there were days when the assertion would fail in 90% of the cases.&lt;/p&gt;
&lt;p&gt;In addition to this the assertions would only fail on two particular directories but not on any other. I couldn’t identify the commonality between the directories on which the assertion would fail and the directories that were successfully deleted.&lt;/p&gt;
&lt;p&gt;Initially I thought that maybe a different process or a different thread would have a handle to the directory. In that case my test would just ask the operation system (Windows 7, 64 bit) to mark the directory as deleted and as soon as the last handle was closed it would be removed. However, the tests would generate names and then create directories with that name. No other thread or process knew about the names. I didn’t have any thread in my system under test that would scan the parent directory thus ‘learning’ about the generated directory names.&lt;/p&gt;
&lt;p&gt;To diagnose this issue I tried various things including restarting of Visual Studio and rebooting the workstation. I also tried some of &lt;a href=&quot;http://technet.microsoft.com/en-us/sysinternals&quot; target=&quot;_blank&quot;&gt;Sysinternals&lt;/a&gt;’ tools.&lt;/p&gt;
&lt;p&gt;The biggest surprise was an observation that I made when running the tests under the debugger. I set a breakpoint just after the loop that deleted all the directories. At that point Windows Explorer would report those directories as gone. Also when continuing the execution the assertions would not fail. However, once the entire suites was complete, two directories would reappear in Windows Explorer! So despite Directory.Exists stating the Directory to be non-existent it reappeared! This is repeatable.&lt;/p&gt;
&lt;p&gt;To take elements out of the equation I got the latest revision of csUnit’s source code and upgraded it to VS2010 and .NET 4.0 (these &lt;a href=&quot;https://sourceforge.net/projects/csunit/&quot; target=&quot;_blank&quot;&gt;changes are available&lt;/a&gt; at Sourceforge). Then I executed the same test suite without any modification using csUnit. In this case the directories were properly deleted and did not reappear.&lt;/p&gt;
&lt;p&gt;Where does that leave me? I don’t know. All I can say is this: My test suite creates a number of directories with generated names. When I execute this suite from within VS2010 and using ReSharper 6, two folders reappear despite DirectoryInfo.Delete() being executed successfully and Directory.Exists() confirming that. However when I execute the same test suite from csUnitRunner, the code behaves as expected and the folders remain deleted. Despite searching for a long time I have not been able to find the reason for this difference in behavior.&lt;/p&gt;
&lt;p&gt;The only reasonable conclusion at this stage seem to be that as developers we always need to be suspicious about the tools we use. While they may work in almost all the cases, sometimes they may be the cause for something that doesn’t work.&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/1353491214807774250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2011/11/behavior-of-directoryinfodelete-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/1353491214807774250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/1353491214807774250'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2011/11/behavior-of-directoryinfodelete-and.html' title='Behavior of DirectoryInfo.Delete and Directory.Exists: Directories reappear!?'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-8765821073541177501</id><published>2011-11-22T23:45:00.001+13:00</published><updated>2012-04-14T13:39:50.604+12:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C# Guidelines"/><category scheme="http://www.blogger.com/atom/ns#" term="Data Access Layer"/><title type='text'>DirectoryInfo.Delete() when files are read-only</title><content type='html'>&lt;p&gt;DirectoryInfo.Delete() will fail with UnauthorizedAccessException if that directory or any of its subdirectories contains a file that is read-only. &lt;/p&gt; &lt;p&gt;One solution is to remove the read-only attribute from all files. You can do so while recursively deleting directories. This approach is mentioned in some blogs and it looks as follows:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;public static void RecursivelyDeleteDirectory(
                   DirectoryInfo currentDirectory) {
   try {
      currentDirectory.Attributes = FileAttributes.Normal;
      foreach (var childDirectory in 
                        currentDirectory.GetDirectories()) {
         RecursivelyDeleteDirectory(childDirectory);
      }

      foreach (var file in currentDirectory.GetFiles()) {
         file.IsReadOnly = false;
      }

      currentDirectory.Delete(true);
   }
   catch (Exception ex) {
      Console.WriteLine(ex); // Better option: Use log4net
   }
}&lt;/pre&gt;
&lt;p&gt;While this works some people do not like recursion. So here is an option for how the same can be achieved without recursion:&lt;/p&gt;&lt;pre class=&quot;brush: csharp;&quot;&gt;public static void DeleteDirectory(
                   DirectoryInfo currentDirectory) {
   try {
      foreach (var file in currentDirectory.GetFiles(
               &quot;*&quot;, SearchOption.AllDirectories)) {
         file.IsReadOnly = false;
      }
      currentDirectory.Delete(true);
   }
   catch (Exception ex) {
      Console.WriteLine(ex); // Better option: Use log4net
   }
}&lt;/pre&gt;
&lt;p&gt;Please note that these implementations report exceptions at the console. A better option would be to use a standard logging framework like &lt;a href=&quot;http://logging.apache.org/log4net/&quot; target=&quot;_blank&quot;&gt;log4net&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/8765821073541177501/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2011/11/directoryinfo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8765821073541177501'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/8765821073541177501'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2011/11/directoryinfo.html' title='DirectoryInfo.Delete() when files are read-only'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-20032820.post-819764804757596510</id><published>2011-11-08T20:07:00.001+13:00</published><updated>2011-11-08T20:07:55.705+13:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="TDD"/><category scheme="http://www.blogger.com/atom/ns#" term="Tools"/><title type='text'>ReSharper Not Executing Your Tests?</title><content type='html'>&lt;p&gt;Today I ran into a small issue as ReSharper was not willing to execute my tests. Generally it does but today it was different. Let me explain.&lt;/p&gt; &lt;p&gt;I have two assemblies, one that contains the unit tests and one that contains the code under test. In ReSharper’s session window the unit tests were properly listed. I was even able to “execute” them. However it would always show that them as not executed with a gray bullet in front of them. This was the behavior for both “Run Test” and “Debug Test”. The Output window was empty and didn’t show anything that would indicate what was wrong.&lt;/p&gt; &lt;p&gt;I also check my unit tests but all attributes were properly in place and both the class and the methods were public and the methods had the correct signature. So what was going on?&lt;/p&gt; &lt;p&gt;To diagnose the issue I launched the unit test tool as a stand-alone application. When I tried to load the assembly with the unit tests it was immediately clear what was wrong when I saw the word BadImageFormatException displayed in a message box.&lt;/p&gt; &lt;p&gt;It turned out that the assembly with the unit tests was set to build for “Any CPU” while the assembly under test was build for “x86”. Since I am using a 64 bit machine the two assemblies were compiled as per those targets. The unit tests as 64 bit while the assembly under test as 32 bit. No wonder it didn’t work.&lt;/p&gt; &lt;p&gt;This is easy to fix, in my case by setting the target for the assembly with the unit tests to “x86” as well. It would, however, be nice if ReSharper had reported the exception in some form as it would have saved time. Well, maybe in the next version? Maybe this post helps you to save some time.&lt;/p&gt; &lt;p&gt;&lt;font size=&quot;1&quot;&gt;(Note: I’m using ReSharper version 6.0.2202.688 with Visual Studio 2010 SP1 on a 64 bit Windows 7 Enterprise Edition)&lt;/font&gt;&lt;/p&gt;  &lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;script type=&quot;text/javascript&quot;&gt;&lt;!--
google_ad_client = &quot;pub-2808695142842813&quot;;
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = &quot;728x15_0ads_al&quot;;
//2007-02-24: csUnit
google_ad_channel = &quot;6588413627&quot;;
//--&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://pagead2.googlesyndication.com/pagead/show_ads.js&quot;&gt;
&lt;/script&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://manfredlange.blogspot.com/feeds/819764804757596510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://manfredlange.blogspot.com/2011/11/resharper-not-executing-your-tests.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/819764804757596510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/20032820/posts/default/819764804757596510'/><link rel='alternate' type='text/html' href='http://manfredlange.blogspot.com/2011/11/resharper-not-executing-your-tests.html' title='ReSharper Not Executing Your Tests?'/><author><name>Manfred Lange</name><uri>http://www.blogger.com/profile/01100831606055102208</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-KoWGqGATFPXuOTiWXNoLFt7Oyrib9lvwbO6OPV6BbCSfFwDw9s5iTcP2gQiwQAF5j5CjxlP79NCZEeWkgYXCd9mdbzt7qbSl7DhKXFZwf-t635NWIeOmTRnfiPUZA/s220/10.7.2019+Lange+355+%284%29-min.jpg'/></author><thr:total>1</thr:total></entry></feed>