<?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-8111117761365139552</id><updated>2024-08-31T15:00:32.088+02:00</updated><category term="sql server"/><category term="C#"/><category term=".NET"/><category term="ASP.NET"/><category term="CruiseControl.NET"/><category term="WatIn"/><category term="nServiceBus"/><category term="performance"/><category term="syntax highlighter"/><category term="unit testing"/><category term="Automated testing"/><category term="Documentation"/><category term="Encoding"/><category term="FFMpeg"/><category term="FxCop"/><category term="HTTP"/><category term="Handbrake"/><category term="ILMerge"/><category term="MSBuild"/><category term="MSDTC"/><category term="MVC"/><category term="Macro"/><category term="Mocking"/><category term="Moq"/><category term="NCover"/><category term="NUnit"/><category term="Obfuscation"/><category term="PerfMon"/><category term="Powershell"/><category term="SVN"/><category term="Sandcastle"/><category term="T-SQL"/><category term="Visual Studio"/><category term="VisualSVN Server"/><category term="WCF"/><category term="Web services"/><category term="backup"/><category term="debug"/><category term="encryption"/><category term="favicon"/><category term="javascript"/><category term="log4net"/><category term="prettify"/><category term="publishing"/><category term="restore"/><category term="selenium"/><category term="sql"/><category term="sql server express"/><category term="windows services"/><title type='text'>Matt Salmon&#39;s Tech Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default?start-index=26&amp;max-results=25'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-5592011527234040660</id><published>2011-08-18T10:01:00.001+02:00</published><updated>2011-08-18T10:05:28.814+02:00</updated><title type='text'>Cruise Control Powershell Script with spaces in path</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I have a powershell script that is executed as a Cruise Control.NET task.&amp;nbsp; The problem is, the script sat in a length path with spaces in some of the folder names.&amp;nbsp; The “powershell” task itself doesn’t support spaces, so the solution to this is to use old-school 8 character directory names.&lt;/p&gt; &lt;p&gt;For example, if you script lies in the path “C:\Parent Folder\NotParent Folder”, set your task up as follows:&lt;/p&gt; &lt;pre class=&quot;prettyprint&quot; style=&quot;background-color: rgb(240, 240, 240);&quot;&gt;
&amp;lt;powershell&amp;gt;
	&amp;lt;script&amp;gt;myscript.ps1&amp;lt;/script&amp;gt;
	&amp;lt;executable&amp;gt;C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe&amp;lt;/executable&amp;gt;
	&amp;lt;scriptsDirectory&amp;gt;C:\Parent~1\NotPar~1&amp;lt;/scriptsDirectory&amp;gt;
	&amp;lt;description&amp;gt;Build something.&amp;lt;/description&amp;gt;
&amp;lt;/powershell&amp;gt;
&lt;/pre&gt;  </content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/5592011527234040660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2011/08/cruise-control-powershell-script-with.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5592011527234040660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5592011527234040660'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2011/08/cruise-control-powershell-script-with.html' title='Cruise Control Powershell Script with spaces in path'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-4608143094771684766</id><published>2011-07-08T16:03:00.005+02:00</published><updated>2011-07-25T08:10:45.107+02:00</updated><title type='text'>HTTP Header Errors with MVC3 Redirects</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;We noticed in our error logs that we were getting quite a few of these good old errors:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&quot;Cannot redirect after HTTP headers have been sent.&quot;&lt;/code&gt;&lt;/pre&gt;&lt;font face=&quot;Arial&quot;&gt;This wasn’t affecting our system from a usability point of view, but it’s irritating nonetheless.  Anyway, the cause of the error was the following code in the OnActionExecuting override of a custom ActionFilterAttribute:&lt;/font&gt;
&lt;blockquote&gt;&lt;pre&gt;HttpContext.Current.Response.Redirect(“our url”, true)&lt;/pre&gt;&lt;/blockquote&gt;
&lt;p&gt;Looks fine, right?&lt;/p&gt;
&lt;p&gt;The error here is that within action filter attributes, you don’t know what other code is being executed in the request pipeline – in our case we had a BaseController adding caching headers in the OnResultExecuting override.&amp;nbsp; &lt;/p&gt;
&lt;p&gt;The correct way to do this is to set the result of the filterContext object – this gets dealt with immediately and the error goes away.&amp;nbsp; The correct code is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;font face=&quot;Courier New&quot;&gt;filterContext.Result = new RedirectResult(“our url”);&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Pretty trivial, I know, but I Googled this and found very little out there that actually describes this error and the solution.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/4608143094771684766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2011/07/http-header-errors-with-mvc3-redirects.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4608143094771684766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4608143094771684766'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2011/07/http-header-errors-with-mvc3-redirects.html' title='HTTP Header Errors with MVC3 Redirects'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-9144577819885006285</id><published>2011-05-06T17:07:00.001+02:00</published><updated>2011-05-06T17:07:41.840+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="MVC"/><title type='text'>MVC3 Deployment Nightmare</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;I had a freaking nightmare deploying an MVC3 app today.&amp;nbsp; Seems simple.&amp;nbsp; Database was up and running.&amp;nbsp; The code was deployed and had been tested on our local systems.&amp;nbsp; I deployed via our amazing SVN deployment process, and published on the live server.&amp;nbsp; Permissions applied automatically, all the files appeared – all was good in the world.&amp;nbsp; Until I loaded up the site in my browser and hit…&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Infinite Redirects&lt;/strong&gt;  &lt;p&gt;Fan-freaking-tastic.&amp;nbsp; Double-check the Web.config.&amp;nbsp; Fine.&amp;nbsp; Double-check the IIS mappings.&amp;nbsp; Fine. This ruined my day.&amp;nbsp; To cut a long story short: this all boils down to conflicts between the versions of MVC3 binaries between RC1 and RC2.&amp;nbsp; If you search on the web you will find numerous references to issues with the get_viewBag() call, and to be honest, I didn’t have to time to fully understand WHY this is such a cockup.  &lt;p&gt;Either way, the solution I finally came up with was to UNINSTALL MVC3 on the web server, manually add the .dll references to our project, and force &quot;Copy Local&quot;.  &lt;p&gt;&lt;a href=&quot;http://www.tugberkugurlu.com/archive/deployment-of-asp-net-mvc-3-rc-2-application-on-a-shared-hosting-environment-without-begging-the-hosting-company&quot;&gt;http://www.tugberkugurlu.com/archive/deployment-of-asp-net-mvc-3-rc-2-application-on-a-shared-hosting-environment-without-begging-the-hosting-company&lt;/a&gt;  &lt;p&gt;The DLLs that must be referenced:  &lt;ul&gt; &lt;li&gt;Microsoft.Web.Infrastructure  &lt;li&gt;System.Web.Razor  &lt;li&gt;System.Web.WebPages  &lt;li&gt;System.Web.WebPages.Razor  &lt;li&gt;System.Web.Helpers  &lt;li&gt;System.Web.WebPages.Deployment (If you are deploying MVC RC 2, this assembly is necessary to deploy)  &lt;li&gt;System.Web.Mvc&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Make sure these copy locally to your bin folder (Right click, Properties, Copy Local = true)  &lt;p&gt;This sorted out that bug.&amp;nbsp; Enter the next issue: The type or namespace name &#39;WebMatrix&#39; could not be found (are you missing a using directive or an assembly reference?).&amp;nbsp; WTF!?  &lt;p&gt;&lt;strong&gt;Web Matrix Agony Part 1&lt;/strong&gt;  &lt;p&gt;MVC3 RC2 has a bug where some of the source files have &quot;using WebMatrix&quot; references in them. As such, even though you don&#39;t need them, your project will not run without a reference to WebMatrix, which is annoying.  &lt;p&gt;The obvious solution is to add these as a reference, but I tried that and it fails because WebMatrix requires an initialisation call in the Global.asax. Bummer.&amp;nbsp; I redeployed, and my error message now changed to  &lt;p&gt;You must call the &quot;WebSecurity.InitializeDatabaseFile&quot; or &quot;WebSecurity.InitializeDatabaseConnection&quot; method before you call any other method of the &quot;WebSecurity&quot; class.  &lt;p&gt;EFF THIS.  &lt;p&gt;&lt;strong&gt;Web Matrix Agony Part 2&lt;/strong&gt;  &lt;p&gt;To get around this, in your global.asax make sure you add the following code at the bottom of the file:  &lt;pre style=&quot;background-color: rgb(240,240,240)&quot; class=&quot;prettyprint&quot;&gt;namespace WebMatrix.Data { internal class Ignore { } }
namespace WebMatrix.WebData { internal class Ignore { } }
&lt;/pre&gt;
&lt;p&gt;Reference: &lt;a title=&quot;http://stackoverflow.com/questions/4146545/razor-helper-in-mvc-3-rc&quot; href=&quot;http://stackoverflow.com/questions/4146545/razor-helper-in-mvc-3-rc&quot;&gt;http://stackoverflow.com/questions/4146545/razor-helper-in-mvc-3-rc&lt;/a&gt; 
&lt;p&gt;This works as the statements in the MVC3 source binaries are only using statements!&amp;nbsp; I added these lines to the end of my Global.asax with a big comment about how much I hate the world and how much those 2 lines of code REALLY NEED TO STAY; removed the WebMatrix references I had added earlier, published, and redeployed. 
&lt;p&gt;And everything started working. 
  </content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/9144577819885006285/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2011/05/mvc3-deployment-nightmare.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/9144577819885006285'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/9144577819885006285'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2011/05/mvc3-deployment-nightmare.html' title='MVC3 Deployment Nightmare'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-8786880730622988334</id><published>2011-05-05T13:47:00.001+02:00</published><updated>2011-05-05T13:47:53.517+02:00</updated><title type='text'>Odds and Ends</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;Symbolic links in Windows: &lt;a href=&quot;http://technet.microsoft.com/en-us/library/cc753194(WS.10).aspx&quot;&gt;http://technet.microsoft.com/en-us/library/cc753194(WS.10).aspx&lt;/a&gt; – this was weird.&amp;nbsp; I was moaning to Rohland about how I missed have symlinks from Linux, but I’d never bothered to research the alternative in Windows, assuming that Shortcuts were all we have.&amp;nbsp; It turns out, you CAN make sybmbolic links in Windows.&lt;/p&gt; &lt;p&gt;Sick of Windows 7 copying? &lt;a href=&quot;http://www.codesector.com/teracopy.php&quot;&gt;http://www.codesector.com/teracopy.php&lt;/a&gt; – I love this tool.&amp;nbsp; It also queues copying requests so you don’t end up with a hard drive going back and forth like a scratch record.&lt;/p&gt; &lt;p&gt;Precompiling Razor views: &lt;a title=&quot;http://odetocode.com/blogs/scott/archive/2011/02/16/notes-on-building-razor-views.aspx&quot; href=&quot;http://odetocode.com/blogs/scott/archive/2011/02/16/notes-on-building-razor-views.aspx&quot;&gt;http://odetocode.com/blogs/scott/archive/2011/02/16/notes-on-building-razor-views.aspx&lt;/a&gt; – this is awesome.&amp;nbsp; Set up your Debug version to not precompile views, and set up an automated build to precompile views in Release mode at a regular interval to catch any issues in your views caused by refactoring.&lt;/p&gt; &lt;p&gt;PNGOUT: &lt;a title=&quot;http://advsys.net/ken/utils.htm&quot; href=&quot;http://advsys.net/ken/utils.htm&quot;&gt;http://advsys.net/ken/utils.htm&lt;/a&gt; – this is a FREE tool that reduces the size of PNG files by 5 – 30%.&amp;nbsp; Running this on all images for presentations, blog posts and web sites is a pretty good idea!&lt;/p&gt; &lt;p&gt;Dapper: &lt;a title=&quot;http://code.google.com/p/dapper-dot-net/&quot; href=&quot;http://code.google.com/p/dapper-dot-net/&quot;&gt;http://code.google.com/p/dapper-dot-net/&lt;/a&gt; – this looks SO useful for smaller projects.&amp;nbsp; It’s being used on stackoverflow.com though – maybe not such small projects too!&lt;/p&gt; &lt;p&gt;IIS Compression: Excellent post by Rick Strahl with regards to setting up compression in IIS7: &lt;a title=&quot;http://www.west-wind.com/weblog/posts/2011/May/05/Builtin-GZipDeflate-Compression-on-IIS-7x&quot; href=&quot;http://www.west-wind.com/weblog/posts/2011/May/05/Builtin-GZipDeflate-Compression-on-IIS-7x&quot;&gt;http://www.west-wind.com/weblog/posts/2011/May/05/Builtin-GZipDeflate-Compression-on-IIS-7x&lt;/a&gt;&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/8786880730622988334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2011/05/odds-and-ends.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8786880730622988334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8786880730622988334'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2011/05/odds-and-ends.html' title='Odds and Ends'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-8685934706555576806</id><published>2011-01-27T12:24:00.010+02:00</published><updated>2011-01-27T12:39:15.280+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="WCF"/><title type='text'>WCF Quick and Dirty</title><content type='html'>&lt;p&gt;I added some WCF services to an existing project today, and I found I had completely forgotten the easy way of setting this stuff up.&amp;nbsp; So, here goes.&amp;nbsp; Note that you will usually split your host and consumer between separate projects – this is just an outline of the basics when working with Visual Studio 2010 and isn’t really concerned with actual implementation.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Create the DataContract Classes&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;These are the classes that will be serialized and submitted by WCF.&amp;nbsp; For example, if you are creating a service to add two numbers, you would have a class like so:&lt;/p&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;background-color:rgb(240,240,240);&quot;&gt;
[DataContract] 
public class ExampleDataContract 
{ 
 [DataMember] 
 public int Num1 { get; set; } 

 [DataMember] 
 public int Num2 { get; set; } 
} 
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Create the Service&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Now that we have the data contract, we can create the actual service.&amp;nbsp; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Navigate to the location in your solution where the service will sit, and add a new item (a &lt;em&gt;WCF Data Service&lt;/em&gt;). 
&lt;li&gt;The service is now created.&amp;nbsp; The interface should be decorated with a &lt;em&gt;ServiceContract&lt;/em&gt; attribute. 
&lt;li&gt;Any methods added to the interface will need to be decorated with an &lt;em&gt;OperationContract&lt;/em&gt; attribute. 
&lt;li&gt;In terms of the contract implementation, you will need to decorate your class with a &lt;em&gt;ServiceBehavior&lt;/em&gt; attribute.&amp;nbsp; For example: &lt;/li&gt;&lt;/ol&gt;
&lt;pre class=&quot;prettyprint&quot; style=&quot;background-color:rgb(240,240,240);&quot;&gt;[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, AddressFilterMode = AddressFilterMode.Any)] &lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Configure the Service&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can manually configure your service in your App.config file, but there is actually a GUI that makes this a lot easier.&amp;nbsp; All you need to do is righ-click your config file and there will be an option to &lt;em&gt;Edit WCF Configuration&lt;/em&gt; – click this to launch the editor.&lt;/p&gt;
&lt;p&gt;Note that if your project is not a WCF project, this may not be available in the context menu.&amp;nbsp; There’s an easy work-around for this though:&lt;/p&gt;
&lt;ul&gt;
&lt;ol&gt;
&lt;li&gt;Select &lt;em&gt;Tools-&amp;gt;WCF Configuration Editor&lt;/em&gt; from the Visual Studio menu, and click &lt;em&gt;WCF Configuration Editor&lt;/em&gt; 
&lt;li&gt;Close the &lt;em&gt;WCF Configuration Editor&lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ul&gt;
&lt;p&gt;Now when you right-click the App.config the &lt;em&gt;Edit WCF Configuration&lt;/em&gt; option should be available.&lt;/p&gt;
&lt;p&gt;Usually there shouldn’t be too much to change here unless you’re manually creating your endpoints/services.&amp;nbsp; If you’re just wanting the basic endpoints, you can give the endpoints names (e.g. AddNumbersHttp for the wsHttpBinding) and continue.&lt;/p&gt;
&lt;p&gt;We now have enough set up to host and test the service.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Test the Service&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio 2010 makes testing WCF apps really simple.&amp;nbsp; If you’re working with a WCF project, when you run the project Visual Studio will fire up the WCF test client by itself.&lt;/p&gt;
&lt;p&gt;If you’re developing a web project, this won’t work, so you will need to fire up the client manually by opening a Visual Studio Command Prompt and typing the following:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;wcftestclient &lt;a href=&quot;http://yoursite/Services/YourService.svc&quot;&gt;http://yoursite/Services/YourService.svc&lt;/a&gt;. &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;If you get errors here, you may need to configure your web site.&amp;nbsp; There are two possible issues:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;IIS has not been configured to handle the .svc extension.&amp;nbsp; This is easily fixed by running the registration tool that comes with .NET – run &lt;em&gt;ServiceModelReg.exe -i&lt;/em&gt; from the &quot;%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation&quot; directory 
&lt;li&gt;If you are getting an error that the service cannot be activated because it does not support ASP.NET compatibility you can either configure your application for compatibility mode, or mark your service implementation with the following attribute: &lt;br&gt;&lt;code&gt;[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] &lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Create the Client&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can now create the client that will consume the services created above.&amp;nbsp; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Right-click your project’s &lt;em&gt;References&lt;/em&gt;, and click &lt;em&gt;Add Service Reference&lt;/em&gt; 
&lt;li&gt;If you want to use a service within another project in your solution, you can click the &lt;em&gt;Discover&lt;/em&gt; button and select &lt;em&gt;Services in Solution&lt;/em&gt; 
&lt;li&gt;Select the service, and enter a namespace that will be used within the client project to refer to the service 
&lt;li&gt;You can now use the service like any other C# class, for example: &lt;pre class=&quot;prettyprint&quot; style=&quot;background-color:rgb(240,240,240);&quot;&gt;MyServiceNamespace.MyServiceClient client = new MyServiceNamespace.MyServiceClient();
client.AddNumbers(1, 2);
client.Close();
&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Resources&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://msdn.microsoft.com/en-us/netframework/dd939784&quot;&gt;http://msdn.microsoft.com/en-us/netframework/dd939784&lt;/a&gt; 
&lt;li&gt;&lt;a href=&quot;http://channel9.msdn.com/shows/Endpoint/Endpoint-Screencasts-Creating-Your-First-WCF-Service/&quot;&gt;http://channel9.msdn.com/shows/Endpoint/Endpoint-Screencasts-Creating-Your-First-WCF-Service/&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/8685934706555576806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2011/01/wcf-quick-and-dirty.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8685934706555576806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8685934706555576806'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2011/01/wcf-quick-and-dirty.html' title='WCF Quick and Dirty'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-8679075867836051343</id><published>2010-11-17T13:31:00.001+02:00</published><updated>2010-11-17T13:49:39.273+02:00</updated><title type='text'>Determining the target .NET Framework version of a .NET assembly</title><content type='html'>&lt;p&gt;To determine which version of the .NET framework an assembly supports, you can use &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/f7dy01k1%28VS.80%29.aspx&quot;&gt;ILDASM&lt;/a&gt;. &lt;/p&gt; &lt;p&gt;Open up a visual studio command prompt, and type the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ildasm.exe C:\Yourdll.dll /metadata[=MDHEADER] /text /noil&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You’ll get a large amount of indecipherable data, but right at the top, you’ll see something to the effect of&lt;/p&gt;
&lt;p&gt;// Metadata section: 0x424a5342, version: 1.1, extra: 0, version len: 12, version: &lt;strong style=&quot;color: orange&quot;&gt;v4.0.30319&lt;/strong&gt; 
&lt;p&gt;where the highlighted piece gives you the supported version.&lt;/p&gt;
&lt;p&gt;Alternatively, you can just open ildasm (just type ildasm at the command prompt), and open up the dll – you can see the metadata version right at the top by double-clicking “MANIFEST”:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://lh3.ggpht.com/_mRZGgx0QDv0/TOO_aJjj6FI/AAAAAAAADNI/N3xk2pe2vcQ/Mainfest%5B17%5D.png?imgmax=800&quot;&gt;&lt;img style=&quot;border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px&quot; title=&quot;Mainfest&quot; border=&quot;0&quot; alt=&quot;Mainfest&quot; src=&quot;http://lh3.ggpht.com/_mRZGgx0QDv0/TOPBS02EzZI/AAAAAAAADNM/f2yK39WDoJ8/Mainfest_thumb%5B13%5D.png?imgmax=800&quot; width=&quot;244&quot; height=&quot;155&quot;&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Useful!&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/8679075867836051343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/11/determining-target-net-framework.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8679075867836051343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8679075867836051343'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/11/determining-target-net-framework.html' title='Determining the target .NET Framework version of a .NET assembly'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/_mRZGgx0QDv0/TOPBS02EzZI/AAAAAAAADNM/f2yK39WDoJ8/s72-c/Mainfest_thumb%5B13%5D.png?imgmax=800" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-845034378335771586</id><published>2010-11-16T12:05:00.002+02:00</published><updated>2010-11-16T12:10:06.376+02:00</updated><title type='text'>Moq BadImageFormatException with NUnit</title><content type='html'>I ran into an issue today running a unit test where I kept getting a System.BadImageFormatException on the test dll.  I incorrectly assumed this was NUnit - after digging around a bit I worked out it was actuall Moq that was the source of the problem.  
&lt;br /&gt;&lt;br /&gt;
The return value of the object being verified existed in an assembly that was not being referenced by my test project, and Moq was falling over.  Adding the reference sorted out the problem.  
&lt;br /&gt;&lt;br /&gt;
The exact error I encountered was:    
&lt;br /&gt;&lt;br /&gt;
Test.MyLongNamespace.MyTestmethod:
System.BadImageFormatException : [C:\Users\matt salmon\AppData\Local\Temp\nunit20\ShadowCopyCache\9748_634255057586445703\Tests_64256578\assembly\dl3\5181e02b\57ddb865_7585cb01\MyAssembly.DLL] The signature is incorrect.</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/845034378335771586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/11/moq-badimageformatexception-with-nunit.html#comment-form' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/845034378335771586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/845034378335771586'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/11/moq-badimageformatexception-with-nunit.html' title='Moq BadImageFormatException with NUnit'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-8270860335074221666</id><published>2010-11-12T10:03:00.001+02:00</published><updated>2010-11-12T10:03:51.825+02:00</updated><title type='text'>Rebuilding SQL Server Indexes</title><content type='html'>I&#39;ve always used cursors to rebuild indexes in SQL Server, like so:  &lt;pre&gt;
&lt;code&gt;
USE YourDatabase

DECLARE @tableName varchar(255)
DECLARE cur CURSOR FOR

SELECT table_schema + &#39;.&#39; + table_name 
FROM information_schema.tables
WHERE table_type = &#39;base table&#39;

OPEN cur

FETCH NEXT FROM cur INTO @tableName
WHILE @@FETCH_STATUS = 0
BEGIN
	DBCC DBREINDEX(@tableName,&#39; &#39;,90)
	FETCH NEXT FROM cur INTO @tableName
END

CLOSE cur
DEALLOCATE cur
&lt;/code&gt;
&lt;/pre&gt;

However, I discovered a much easier way to do it today:

&lt;pre&gt;
&lt;code&gt;
sp_MSforeachtable @command1=&quot;print &#39;?&#39; DBCC DBREINDEX (&#39;?&#39;)&quot;
&lt;/code&gt;
&lt;/pre&gt;

This is an undocumented stored procedure that I didn&#39;t even know existed until this morning.  The cursor route is still useful for when you want to exclude tables, but dang....I wish I&#39;d known of this earlier.  </content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/8270860335074221666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/11/rebuilding-sql-server-indexes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8270860335074221666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8270860335074221666'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/11/rebuilding-sql-server-indexes.html' title='Rebuilding SQL Server Indexes'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-988919506712380035</id><published>2010-10-13T09:29:00.001+02:00</published><updated>2010-10-13T09:29:30.717+02:00</updated><title type='text'>Playing with the TPL</title><content type='html'>&lt;p&gt;I did a quick investigation on the &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/dd460717.aspx&quot;&gt;Task Parallel Library (TPL)&lt;/a&gt; this morning (part of the System.Threading library which comes included in the .NET 4.0 framework or is available as a download from 3.5), and I’m really amazed at how easy it was to implement, and the apparent benefits of using it.&amp;nbsp; Basically, this library allows you to benefit from the multiple cores found in modern computers, without the pain of actually coding for multiple cores yourself.&amp;nbsp; &lt;/p&gt; &lt;p&gt;I wrote a very simple C# application that fired off 1,000 web requests to a web application on my local machine and read the response stream.&amp;nbsp; This was done in three ways: &lt;/p&gt; &lt;ol&gt; &lt;li&gt;sequentially making the web request in a for loop&lt;/li&gt; &lt;li&gt;using a thread pool to make the web requests&lt;/li&gt; &lt;li&gt;using Parallel.Invoke to make the web requests with the TPL library&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Well, option 1 was obviously very simple to implement, but it was SLOW.&amp;nbsp; 1,000 requests took in the region of 20 seconds to run.&lt;/p&gt; &lt;p&gt;Option 2 was the most difficult to implement, but obviously far more efficient.&amp;nbsp; I always find coding for multiple threads a little tricky, as I don’t do it often and I never remember offhand where to put the wait handlers.&amp;nbsp; Anyway, it resulted in 1,000 requests being done in approximately 11 seconds.&lt;/p&gt; &lt;p&gt;Option 3 was, to my pleasant surprise, a piece of cake to implement.&amp;nbsp; Create an Action list, and call Parallel.Invoke – that was it.&amp;nbsp; Incredibly, this took approximately 6.5 seconds to run on my 4-core machine.&amp;nbsp; I’ve pasted the code below, and hopefully my implementation is correct, but it’s so easy to use I don’t see why you wouldn’t use it when you have a large number of tasks to do at one time.&lt;/p&gt; &lt;pre&gt;&lt;code&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Net;
using System.IO;
using System.Threading;

namespace TplSample
{
    class Program
    {
        static string url = &quot;http://dev.mysite.co.za/&quot;;
        static int testCount = 1000;

        static void Main(string[] args)
        {


            // fire off one request so we aren&#39;t skewed by a sleeping application pool
            SendWebRequest();

            // fires off requests in sequential fashion
            SingleRequests();
            // fires off requests using a thread pool
            MultiThreaded();
            // fires off requests using parallel processing
            ParallelRequests();

            Console.WriteLine(&quot;Done.&quot;);
            Console.ReadLine();
        }

        static void SingleRequests()
        {
            // fire off the web request 1,000 times, and time it
            Stopwatch sw = new Stopwatch();
            sw.Start();
            for (int i = 0; i &lt; testCount; i++)
            {
                SendWebRequest();
            }
            sw.Stop();
            Console.WriteLine(&quot;Single requests: {0} seconds&quot;, sw.Elapsed.TotalSeconds);

        }

        static void ParallelRequests()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            List&lt;Action&gt; actions = new List&lt;Action&gt;();
            for (int i = 0; i &lt; testCount; i++)
            {
                Action a = new Action(SendWebRequest);
                actions.Add(a);
            }
            Parallel.Invoke(actions.ToArray());
            sw.Stop();
            Console.WriteLine(&quot;Parallel requests: {0} seconds&quot;, sw.Elapsed.TotalSeconds);
        }

        static void MultiThreaded()
        {
            // ThreadPool.SetMaxThreads(10, 10);
            Stopwatch sw = new Stopwatch();
            sw.Start();

            List&lt;ManualResetEvent&gt; doneEvents = new List&lt;ManualResetEvent&gt;();
            for (int i = 0; i &lt; testCount; i++)
            {
                ManualResetEvent resetEvent = new ManualResetEvent(false);
                doneEvents.Add(resetEvent);
                ThreadWrapper tw = new ThreadWrapper(resetEvent);
                WaitCallback callBack = new WaitCallback(tw.ThreadPoolCallback);
                ThreadPool.QueueUserWorkItem(callBack);

                if (doneEvents.Count == 64)
                {
                    WaitHandle.WaitAll(doneEvents.ToArray());
                    doneEvents.Clear();
                }
            }

            if (doneEvents.Count &gt; 0)
            {
                WaitHandle.WaitAll(doneEvents.ToArray());
            }
            sw.Stop();
            Console.WriteLine(&quot;Thread pool requests: {0} seconds&quot;, sw.Elapsed.TotalSeconds);
        }

        static void SendWebRequest()
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = &quot;GET&quot;;

            HttpWebResponse webResponse = (HttpWebResponse)req.GetResponse();
            using (StreamReader responseStream = new StreamReader(webResponse.GetResponseStream()))
            {
                string response = responseStream.ReadToEnd();
                responseStream.Close();
            }
            webResponse.Close();
            //Console.WriteLine(&quot;1&quot;);
        }

        public class ThreadWrapper
        {

            private ManualResetEvent doneEvent;


            public ThreadWrapper(ManualResetEvent doneEvent)
            {
                this.doneEvent = doneEvent;
            }

            public void ThreadPoolCallback(Object threadContext)
            {
                SendWebRequest();
                this.doneEvent.Set();
            }


        }
    }
}
&lt;/code&gt;&lt;/pre&gt;  </content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/988919506712380035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/10/playing-with-tpl.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/988919506712380035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/988919506712380035'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/10/playing-with-tpl.html' title='Playing with the TPL'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-6637695467712679381</id><published>2010-09-21T09:56:00.001+02:00</published><updated>2010-09-21T09:56:53.225+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="prettify"/><category scheme="http://www.blogger.com/atom/ns#" term="syntax highlighter"/><title type='text'>Prettify</title><content type='html'>&lt;p&gt;Following &lt;a href=&quot;http://stackoverflow.com&quot;&gt;stackoverflow’s&lt;/a&gt; example, I’ve started using &lt;a href=&quot;http://code.google.com/p/google-code-prettify/&quot;&gt;prettify&lt;/a&gt; for syntax highlighting on this blog.&amp;nbsp; I’ve used the &lt;a href=&quot;http://code.google.com/p/syntaxhighlighter/&quot;&gt;Google syntax highlighter&lt;/a&gt; in the past, but prettify just seems easier as I don’t need to mark it with class names or anything – all I need to do is wrap code in &amp;lt;pre&amp;gt; and &amp;lt;code&amp;gt; tags, and it just works.&amp;nbsp; It’s clever enough to work out the language.&lt;/p&gt; &lt;p&gt;Getting it working was really simple.&amp;nbsp; I downloaded the source, combined all the .js files into one using &lt;a href=&quot;http://closure-compiler.appspot.com/home&quot;&gt;Google’s Closure Compiler&lt;/a&gt;, and update the .css file to the styles I like (stolen without shame from stackoverflow – I love that site).&lt;/p&gt; &lt;p&gt;To get the styles to apply to my blog, I also added an initialisation script to make the prettify call, and it works.&amp;nbsp; Hopefully this should save me some time in the future.&lt;/p&gt; &lt;p&gt;I found a &lt;a href=&quot;http://www.codingthewheel.com/archives/syntax-highlighting-stackoverflow-google-prettify&quot;&gt;really good article here&lt;/a&gt; that showed me how to set this all up.&amp;nbsp; I’ll update old blog posts at some stage, for now they’re going to appear without styling.&lt;/p&gt;  </content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/6637695467712679381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/09/prettify.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/6637695467712679381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/6637695467712679381'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/09/prettify.html' title='Prettify'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-1688416233866317717</id><published>2010-09-08T16:39:00.002+02:00</published><updated>2010-09-21T09:37:03.809+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><title type='text'>.NET – Detecting Modem COM Ports</title><content type='html'>&lt;p&gt;We have a project at the moment where we’re using GSM modems attached to the local machine to send an SMS.&amp;nbsp; One of the issues we’ve had is when the modem is not actually connected before our service starts up: our service sometimes attaches to the COM Port that is required by the modem, and this prevents the modem from ever connecting.&lt;/p&gt; &lt;p&gt;There is a simple way to detect which COM ports are assigned to modems installed on your machine:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;using System.Management;

ManagementObjectSearcher mos = new ManagementObjectSearcher(&quot;SELECT * FROM Win32_POTSModem&quot;);
foreach (ManagementObject mo in mos.Get())
{
    string s= mo[&quot;AttachedTo&quot;].ToString();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Other properties available can be looked up here: &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa394360%28VS.85%29.aspx&quot;&gt;http://msdn.microsoft.com/en-us/library/aa394360%28VS.85%29.aspx&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/1688416233866317717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/09/net-detecting-modem-com-ports.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1688416233866317717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1688416233866317717'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/09/net-detecting-modem-com-ports.html' title='.NET – Detecting Modem COM Ports'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-5271810797804203716</id><published>2010-08-31T15:18:00.001+02:00</published><updated>2010-08-31T15:18:49.701+02:00</updated><title type='text'>Using the WiX Installer</title><content type='html'>&lt;p&gt;I’ve been playing with the &lt;a href=&quot;http://wix.sourceforge.net/&quot;&gt;Wix Installer&lt;/a&gt; for the last few days, and I’m absolutely amazed by it.&amp;nbsp; It’s a real bastard to get into, but once you’re up and running it’s pretty incredible how much can be customised.&amp;nbsp; There is a LOT of documentation out there, but the most useful link I found was &lt;a href=&quot;http://www.tramontana.co.hu/wix/index.php#TOC&quot;&gt;this tutorial&lt;/a&gt; – it really is worth your while to read the entire tutorial BEFORE trying to create your own installation project.&lt;/p&gt; &lt;p&gt;Instead of creating another tutorial, I thought I’d list the items that tripped me up.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Visual Studio 2010 Integration&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;I downloaded Wix 3.0 (64 bit), and after installation, it wasn’t available as a project within Visual Studio.&amp;nbsp; Download the beta version of 3.5 – it seems pretty stable and integrates with Visual Studio,.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;No Wizard&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;No wizard!?&amp;nbsp; WTF!?&amp;nbsp; It turns out it’s XML-based – you end up doing a lot of the setup by hand.&amp;nbsp; Deal with it.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;References in Visual Studio&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;You will probably require extensions so you can customise the UI, or perhaps ensure the user has a .NET Framework installed.&amp;nbsp; I’m working in Visual Studio 2010, and I wasn’t sure how to do this so I added compiler and linker options in the project properties.&amp;nbsp; You do not need to do this.&amp;nbsp; All you need to do is click “Add Reference” on the project, and select the extension from the list that appears.&amp;nbsp; For example, if you want to add the .NET Framework prerequisites, right-click References, and select WixNetFxExtension.&amp;nbsp; That is all you need to do.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Default UI&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;The default installation dialog really sucked, and it took me a while to work out that you need to specify a different UI type.&amp;nbsp; That’s what you get for not reading the above tutorial before creating your project.&amp;nbsp; You need to create a &amp;lt;UI&amp;gt; element, and specify the UIRef you want to use.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Dialog Sequence&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Creating custom dialogs is pretty easy once you get the hang of it, but I struggled a little with navigation between dialogs.&amp;nbsp; Eventually I found the reference on the Wix site to a full list of Wix dialogs that you can navigate between at &lt;a href=&quot;http://wix.sourceforge.net/manual-wix3/WixUI_dialogs.htm&quot;&gt;http://wix.sourceforge.net/manual-wix3/WixUI_dialogs.htm&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Using the IIS Extension (For deploying web sites)&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This foxed me a little too.&amp;nbsp; Mostly, using the extensions just worked in Visual Studio, but the IIS extension doesn’t.&amp;nbsp; You need to add the namespace reference, something along the lines of:&lt;/p&gt;&lt;pre class=&quot;brush: xml&quot; name=&quot;code&quot;&gt;&amp;lt;wix xmlns=&quot;http://schemas.microsoft.com/wix/2006/wi&quot; xmlns:iis=&quot;http://schemas.microsoft.com/wix/IIsExtension&quot; xmlns:netfx=&quot;http://schemas.microsoft.com/wix/NetFxExtension&quot;&amp;gt;
&lt;/pre&gt;
&lt;p&gt;You can then use the extension elements as follows:&lt;/p&gt;&lt;pre class=&quot;brush: xml&quot; name=&quot;code&quot;&gt;&amp;lt;iis:WebSite Id=&#39;DefaultWebSite&#39; Description=&#39;Default Web Site&#39;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;iis:WebAddress Id=&#39;AllUnassigned&#39; Port=&#39;80&#39; /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/iis:WebSite&amp;gt;&lt;/pre&gt;  </content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/5271810797804203716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/08/using-wix-installer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5271810797804203716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5271810797804203716'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/08/using-wix-installer.html' title='Using the WiX Installer'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-4173769595023421239</id><published>2010-08-26T11:51:00.002+02:00</published><updated>2010-09-21T09:57:44.142+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="unit testing"/><title type='text'>Unit Testing and DateTime Comparisons</title><content type='html'>&lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;One thing I’ve found annoying for the long time, is trying to assert DateTime equality when unit testing, particularly when the DateTimes have been parsed from strings in the underlying method.&amp;nbsp; Two DateTime constructs, despite being identical in terms of their values, often won’t assert as being equal and your unit test fails.&amp;nbsp; As such, you end up doing other sorts of tests, for example checking the individual values.&lt;/p&gt; &lt;p&gt;To help test dates, what I’ve done is created a helper class for asserting two dates are “equal”, to a specifed level of precision:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;public static class AssertHelper
    {
        /// &lt;summary&gt;
        /// Asserts that two dates are equal by checking the year, month, day, 
        /// hour, minute, second and millisecond components.
        /// &lt;/summary&gt;
        /// &lt;param name=&quot;current&quot;&gt;The current date&lt;/param&gt;
        /// &lt;returns&gt;&lt;/returns&gt;
        public static void AreDatesEqual(DateTime expected, DateTime actual, DateTimePrecision precision)
        {
            if (precision &amp;gt;= DateTimePrecision.Year &amp;amp;&amp;amp; expected.Year != actual.Year)
            {
                throw new NUnit.Framework.AssertionException(&quot;Year in dates do not match as expected.&quot;);
            }
            if (precision &amp;gt;= DateTimePrecision.Month &amp;amp;&amp;amp; expected.Month != actual.Month)
            {
                throw new NUnit.Framework.AssertionException(&quot;Month in dates do not match as expected.&quot;);
            }
            if (precision &amp;gt;= DateTimePrecision.Day &amp;amp;&amp;amp; expected.Day != actual.Day)
            {
                throw new NUnit.Framework.AssertionException(&quot;Day in dates do not match as expected.&quot;);
            }
            if (precision &amp;gt;= DateTimePrecision.Hour &amp;amp;&amp;amp; expected.Hour != actual.Hour)
            {
                throw new NUnit.Framework.AssertionException(&quot;Hour in dates do not match as expected.&quot;);
            }
            if (precision &amp;gt;= DateTimePrecision.Minute &amp;amp;&amp;amp; expected.Minute != actual.Minute)
            {
                throw new NUnit.Framework.AssertionException(&quot;Minute in dates do not match as expected.&quot;);
            }
            if (precision &amp;gt;= DateTimePrecision.Second &amp;amp;&amp;amp; expected.Second != actual.Second)
            {
                throw new NUnit.Framework.AssertionException(&quot;Second in dates do not match as expected.&quot;);
            }
            if (precision &amp;gt;= DateTimePrecision.Millisecond &amp;amp;&amp;amp; expected.Millisecond != actual.Millisecond)
            {
                throw new NUnit.Framework.AssertionException(&quot;Millisecond in dates do not match as expected.&quot;);
            }


        }
    }

    public enum DateTimePrecision
    {
        Year = 0,
        Month = 1,
        Week = 2,
        Day = 3,
        Hour = 4,
        Minute = 5,
        Second = 6,
        Millisecond = 7
    }
&lt;/code&gt;&lt;/pre&gt;

This effectively allows me to unit test that the dates were close enough, without worrying to much about the exact equality. 

This solution, although working, somehow feels dirty.  I&#39;d love to know if anyone else has any better solutions for unit testing date equality in .NET.</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/4173769595023421239/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/08/unit-testing-and-datetime-comparisons.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4173769595023421239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4173769595023421239'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/08/unit-testing-and-datetime-comparisons.html' title='Unit Testing and DateTime Comparisons'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-7745027806663264277</id><published>2010-08-03T11:32:00.006+02:00</published><updated>2010-08-03T11:38:37.231+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="ILMerge"/><title type='text'>ILMerge</title><content type='html'>I Used &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?familyid=22914587-b4ad-4eae-87cf-b14ae6a939b0&amp;displaylang=en&quot;&gt;ILMerge&lt;/a&gt; today for the first time, and it&#39;s great. &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/bb397866.aspx&quot;&gt;Aspnet_merge.exe&lt;/a&gt; is actually based on this tool, and it allows you to combine all your assemblies into a single exe or dll - great for simple deployment.
&lt;br /&gt;&lt;br /&gt;
It gets installed by default to C:\Program Files (x86)\Microsoft\ILMerge, with fairly decent documentation.  To consolidate a fairly simple Windows exe with three dlls into a single exe, all I did was the following:
&lt;br /&gt;&lt;br /&gt;
ILMerge.exe /t:winexe /out:Output.exe /ndebug Program.exe Lib1.dll Lib2.dll Lib3.dll</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/7745027806663264277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/08/ilmerge.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/7745027806663264277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/7745027806663264277'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/08/ilmerge.html' title='ILMerge'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-5539192553850564180</id><published>2010-07-28T15:58:00.005+02:00</published><updated>2010-07-28T16:04:13.843+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MSBuild"/><category scheme="http://www.blogger.com/atom/ns#" term="Powershell"/><title type='text'>Running MSBuild using Powershell Script</title><content type='html'>I wanted to build a Visual Studio solution using MSBuild using a Powershell script.  Surprisingly, I couldn&#39;t find a reference on the web that actually worked for me.  I thought I&#39;d post it here for future reference, as it applies to the execution of any executable from within Powershell.  It was &quot;Invoke-Expression&quot; that I hadn&#39;t used before.

&lt;pre name=&quot;code&quot; class=&quot;brush: text&quot;&gt; 
$baseDir = &quot;C:\Test\&quot;
$outputFolder = $baseDir + &quot;Output&quot;
$msbuild = &quot;C:\Windows\Microsoft.NET\Framework64\v3.5\MSBuild.exe&quot;
$options = &quot;/noconsolelogger /p:Configuration=Release&quot;
$releaseFolder = $baseDir + &quot;MyProject\bin\Release&quot;

# if the output folder exists, delete it
if ([System.IO.Directory]::Exists($outputFolder))
{
 [System.IO.Directory]::Delete($outputFolder, 1)
}

# make sure our working directory is correct
cd $baseDir

# create the build command and invoke it 
# note that if you want to debug, remove the &quot;/noconsolelogger&quot; 
# from the $options string
$clean = $msbuild + &quot; &quot;&quot;MySolution.sln&quot;&quot; &quot; + $options + &quot; /t:Clean&quot;
$build = $msbuild + &quot; &quot;&quot;MySolution.sln&quot;&quot; &quot; + $options + &quot; /t:Build&quot;
Invoke-Expression $clean
Invoke-Expression $build

# move all the files that were built to the output folder
[System.IO.Directory]::Move($releaseFolder, $outputFolder)

&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/5539192553850564180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/07/running-msbuild-using-powershell-script.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5539192553850564180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5539192553850564180'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/07/running-msbuild-using-powershell-script.html' title='Running MSBuild using Powershell Script'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-5950246446192410856</id><published>2010-05-14T14:11:00.008+02:00</published><updated>2010-06-30T21:33:04.589+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="debug"/><category scheme="http://www.blogger.com/atom/ns#" term="log4net"/><title type='text'>Debugging log4net</title><content type='html'>I ran into an issue with log4net today where it just would NOT log to the database.  I knew the database connection settings were fine, and the config file was fine, but some minor changes I had made to field sizes resulted in the whole thing not logging.  
&lt;br /&gt;
The problem is, log4net, for obvious reasons, doesn&#39;t raise exceptions when it fails, so short of downloading the source and debugging, I was at a bit of a loss.  Luckily, those clever fellas have given a way to log internal messages!  It&#39;s pretty straightforward:
&lt;br /&gt;&lt;br /&gt;
Add the following in your App.config/Web.config, under the configuration section:

&lt;pre name=&quot;code&quot; class=&quot;brush: xml&quot;&gt; 
 &amp;lt;system.diagnostics&amp;gt;
    &amp;lt;trace autoflush=&quot;true&quot;&amp;gt;
      &amp;lt;listeners&amp;gt;
        &amp;lt;add
          name=&quot;textWriterTraceListener&quot;
          type=&quot;System.Diagnostics.TextWriterTraceListener&quot;
          initializeData=&quot;C:\temp\log4net.txt&quot; /&amp;gt;
      &amp;lt;/listeners&amp;gt;
    &amp;lt;/trace&amp;gt;
  &amp;lt;/system.diagnostics&amp;gt; 
&lt;/pre&gt;

Then, add the following key to the appSettings section in your web.config:

&lt;pre name=&quot;code&quot; class=&quot;brush: xml&quot;&gt;
  &amp;lt;add key=&quot;log4net.Internal.Debug&quot; value=&quot;true&quot;/&amp;gt;
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/5950246446192410856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/05/debugging-log4net.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5950246446192410856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5950246446192410856'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/05/debugging-log4net.html' title='Debugging log4net'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-7480332304432236153</id><published>2010-04-22T09:28:00.007+02:00</published><updated>2010-06-30T21:34:59.339+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="CruiseControl.NET"/><category scheme="http://www.blogger.com/atom/ns#" term="NCover"/><category scheme="http://www.blogger.com/atom/ns#" term="NUnit"/><title type='text'>NCover and NUnit AppDomainUnloadedException</title><content type='html'>I lost a few chunks of hair this morning.  I needed to set up some kind of code coverage so I could prove to a client that our unit tests were actually doing what we said they were doing.  I chose &lt;a href=&quot;http://ncover.org&quot;&gt;NCover&lt;/a&gt; as I had used it a few years ago - unfortunately I had to opt for the old, free community edition but maybe one day we&#39;ll be able to upgrade to the commercial version.
&lt;br /&gt;&lt;br /&gt;
Anyway, getting ncover wasn&#39;t a big deal, I added the following section to the ccnet.config file for our project:
&lt;br /&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;  
&amp;lt;exec&amp;gt;
 &amp;lt;executable&amp;gt;C:\Program Files\NCover\NCover.Console.exe&amp;lt;/executable&amp;gt;
 &amp;lt;baseDirectory&amp;gt;C:\Builds\myproject\Source&amp;lt;/baseDirectory&amp;gt;
 &amp;lt;buildArgs&amp;gt;&quot;C:\Program Files\NUnit 2.5.2\bin\net-2.0\nunit-console-x86.exe&quot; MyProjectUnitTests.nunit /xml:..\Artifacts\nunit.xml //x ..\Artifacts\ncover.xml //a Assembly.1;Assembly.2;Assembly.3&amp;lt;/buildArgs&amp;gt;
 &amp;lt;buildTimeoutSeconds&amp;gt;360&amp;lt;/buildTimeoutSeconds&amp;gt;
&amp;lt;/exec&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
This worked first shot.  The unit tests ran, and the code in the assemblies I&#39;d defined was analysed and added to the CruiseControl report (make sure you include the output xml files in your publisher/merge section too).  All fine and well, except now my builds were failing.  Looking at the logs, the unit tests were ALL passing, everything was fine, except there was an unhandled AppDomain exception being raised by NUnit.  Running this on my machine didn&#39;t produce the same result - it was only happening on the build server.  The exact exception message was:
&lt;br /&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: plain&quot;&gt;System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain.&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
It turns out, this is strange bug in NUnit 2.5.2, and as of now, there is no fix.  Fortunately, this doesn&#39;t happen with version 2.4.7 - so for this project all I did was point to a different version of NUnit, and the errors went away.  The older version does seem siginificantly slower than version 2.5.2 so it&#39;s not optimal, but until a newer version comes out with a fix, it&#39;s good enough for me.</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/7480332304432236153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/04/ncover-and-nunit-appdomainunloadedexcep.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/7480332304432236153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/7480332304432236153'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/04/ncover-and-nunit-appdomainunloadedexcep.html' title='NCover and NUnit AppDomainUnloadedException'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-246857437453386783</id><published>2010-03-30T07:28:00.002+02:00</published><updated>2010-03-30T07:28:53.836+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="favicon"/><title type='text'>Online Favicon Creation</title><content type='html'>Need a favicon for your site?  Look no further than &lt;a href=&quot;http://www.favicon.cc/&quot;&gt;http://www.favicon.cc/&lt;/a&gt;.
&lt;br /&gt;&lt;br /&gt;
Nice!</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/246857437453386783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/03/online-favicon-creation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/246857437453386783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/246857437453386783'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/03/online-favicon-creation.html' title='Online Favicon Creation'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-2554161580586754792</id><published>2010-03-10T23:49:00.004+02:00</published><updated>2010-03-11T00:05:28.330+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Encoding"/><category scheme="http://www.blogger.com/atom/ns#" term="FFMpeg"/><category scheme="http://www.blogger.com/atom/ns#" term="Handbrake"/><title type='text'>FFMPeg and the XBox 360</title><content type='html'>I&#39;ve got a pile of old MPEGs on my PC from an old Sony camcorder of mine, that I wanted to play on my XBox 360.  My XBox isn&#39;t connected to my home network, and I wanted to be able to convert the mpegs into something the XBox could read from an external drive.
&lt;br /&gt;&lt;br /&gt;
I&#39;ve been using &lt;a href=&quot;http://handbrake.fr/&quot;&gt;Handbrake&lt;/a&gt; to do conversions, and it works.  Handbrake is an excellent piece of software, but it isn&#39;t quite what I need, as I wanted to do batch conversions and the HandbrakeCLI is a little clunky and too slow for what I want. 
&lt;br /&gt;&lt;br /&gt;
I&#39;ve been trying for ages to convert the files to .mp4 with &lt;a href=&quot;http://ffmpeg.org/&quot;&gt;ffmpeg&lt;/a&gt;, but the damn things just wouldn&#39;t play.  I finally worked it out today.  The mpegs have 5 channel Dolby audio - the XBox 360 doesn&#39;t support that.  All I needed to do was restrict the audion channels to 2 on the output, and it worked!  I haven&#39;t seen this anywhere on the web, so here goes:
&lt;br /&gt;
&lt;pre&gt;
ffmpeg.exe -i input.mpg -sameq -ac 2 -aspect 16:9 output.mp4
&lt;/pre&gt;
&lt;br /&gt;
The &lt;code&gt;-sameq&lt;/code&gt; tag forces the quality to be the same as the source.  The &lt;code&gt;-aspect&lt;/code&gt; is required for my files as the mpegs had a strange 2.34 aspect on them that made the resulting video play in a stretched mode (no idea why).  The &lt;code&gt;-ac 2&lt;/code&gt; was the piece I was missing - this restricts the audio channels to 2, and my mp4 files now work on my XBox (which, incidentally, has the optional media pack applied).  So now, I can just batch convert all my files to .mp4 using FFMPeg, which is REALLY fast, and I&#39;m done.</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/2554161580586754792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/03/ffmpeg-and-xbox-360.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/2554161580586754792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/2554161580586754792'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/03/ffmpeg-and-xbox-360.html' title='FFMPeg and the XBox 360'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-5382706772429659954</id><published>2010-02-26T08:29:00.003+02:00</published><updated>2010-02-26T08:33:24.476+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="nServiceBus"/><title type='text'>NServiceBus error &quot;Parameter name: meth&quot;</title><content type='html'>It&#39;s been a while since I used NServiceBus and I got this annoyingly cryptic error message this morning:
&lt;br /&gt;&lt;br /&gt;
&lt;code&gt;
Value cannot be null. &lt;br /&gt;
Parameter name: meth
&lt;/code&gt;
&lt;br /&gt;&lt;br /&gt;
I finally &lt;a href=&quot;http://tech.groups.yahoo.com/group/nservicebus/message/3219&quot;&gt;found this post&lt;/a&gt; about it and it&#39;s actually a fairly obvious mistake - I had added property without a setter on one of the objects that needed to be serialized as part of my message.  The error message was unfortunately cryptic enough for me to take a while to find it.  I thought I&#39;d post this on here for my own future reference.</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/5382706772429659954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/02/nservicebus-error-parameter-name-meth.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5382706772429659954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5382706772429659954'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/02/nservicebus-error-parameter-name-meth.html' title='NServiceBus error &quot;Parameter name: meth&quot;'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-2502817383210959216</id><published>2010-02-19T07:37:00.001+02:00</published><updated>2010-02-19T07:38:33.329+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C#"/><category scheme="http://www.blogger.com/atom/ns#" term="HTTP"/><title type='text'>HTTP Pre-Authentication</title><content type='html'>Rick Strahl posted &lt;a href=&quot;http://west-wind.com/Weblog/posts/243915.aspx&quot;&gt;this excellent article&lt;/a&gt; on pre-authenticating HTTP requests - this is something that&#39;s caught me in the past but he explains the whole concept so well here I thought this was worth noting for my own future reference.</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/2502817383210959216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/02/http-pre-authentication.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/2502817383210959216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/2502817383210959216'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/02/http-pre-authentication.html' title='HTTP Pre-Authentication'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-4567148169098163204</id><published>2010-01-29T15:52:00.003+02:00</published><updated>2010-06-30T21:37:09.250+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="sql server"/><category scheme="http://www.blogger.com/atom/ns#" term="T-SQL"/><title type='text'>SQL Server: Updating varbinary fields</title><content type='html'>I&#39;m working on a development database with a lot of varbinary fields - these are great once you have your admin screens but they&#39;re a pain in the initial development phase when there is no GUI for loading data.  This little T-SQL snippet can be used to update varbinary fields - or adapt it to insert new data into varbinary fields.
&lt;br /&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: sql&quot;&gt;
update [schema].[table] set Column = (
 SELECT * 
        FROM OPENROWSET(BULK N&#39;E:\Share\Temp\myfile.jpg&#39;, SINGLE_BLOB) AS BinaryFile
)
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/4567148169098163204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/01/sql-server-updating-varbinary-fields.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4567148169098163204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4567148169098163204'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/01/sql-server-updating-varbinary-fields.html' title='SQL Server: Updating varbinary fields'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-9010103185583364364</id><published>2010-01-22T09:33:00.001+02:00</published><updated>2010-01-22T09:35:34.831+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET"/><title type='text'>Page LifeCycle Events Listed</title><content type='html'>&lt;a href=&quot;http://misfitgeek.com/&quot;&gt;Joe Stagner&lt;/a&gt; posted &lt;a href=&quot;http://misfitgeek.com/blog/aspnet/unwinding-the-page-lifecycle-events/&quot;&gt;this useful list&lt;/a&gt; of the entire ASP.NET page lifecycle events as they occur, in order.  
&lt;br /&gt;&lt;br /&gt;
Now if only you could get people to actually use these things correctly....</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/9010103185583364364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/01/page-lifecycle-events-listed.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/9010103185583364364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/9010103185583364364'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/01/page-lifecycle-events-listed.html' title='Page LifeCycle Events Listed'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-8980077785345019219</id><published>2010-01-15T08:57:00.004+02:00</published><updated>2010-07-01T11:49:23.298+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Macro"/><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio"/><title type='text'>Locate File in Solution Explorer - Visual Studio Macro</title><content type='html'>A colleague found &lt;a href=&quot;http://www.brianschmitt.com/2010/01/locate-file-in-solution-explorer-visual.html&quot;&gt;this blog post by Brian Schmitt&lt;/a&gt;, which is one of the most useful little tips I&#39;ve seen in ages.
&lt;br /&gt;&lt;br /&gt;
I&#39;m currently working on a solution with 30+ projects in it: and the Visual Studio items tracking REALLY annoys me when trying to navigate to files between projects that are far apart in the solution explorer tree.  I&#39;ve been wanting to turn this off for ages, but I also do like being able to locate the current file quickly in the solution explorer, so I just haven&#39;t got around to doing it.  This Macro solves my problem perfectly.
&lt;br /&gt;&lt;br /&gt;
To get this working:
&lt;ol&gt;
&lt;li&gt;Switch of auto tracking: Tools, Options, Projects and Solutions, turn off Track Active Items&lt;/li&gt;
&lt;li&gt;Open the Macro Explorer: Tools, Macros, Macro Explorer&lt;/li&gt;
&lt;li&gt;Under MyMacros, right-click Module1 (you can rename this if you like) and click New Macro&lt;/li&gt;
&lt;li&gt;Replace the code of the Macro with the following:
&lt;pre class=&quot;brush: text&quot;&gt;
    Public Sub LocateFileInSolutionExplorer()
        DTE.ExecuteCommand(&quot;View.TrackActivityinSolutionExplorer&quot;)
        DTE.ExecuteCommand(&quot;View.TrackActivityinSolutionExplorer&quot;)
        DTE.ExecuteCommand(&quot;View.SolutionExplorer&quot;)
    End Sub
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Save and close the Macro Explorer&lt;/li&gt;
&lt;li&gt;Go to Tools, Options, Environment Keyboard, and in the &quot;Show commands containing&quot; type in the macro name until it appears in the list below&lt;/li&gt;
&lt;li&gt;Select the file in the list, focus on the &quot;Press shortcut keys&quot; input field and enter the key strokes you want to assign to the Macro.  Like Brain, I used Alt+L,Alt+L.  Assign it, and that&#39;s it.  &lt;/li&gt;
&lt;li&gt;Watch productivity soar.&lt;/li&gt;
&lt;/ol&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/8980077785345019219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2010/01/locate-file-in-solution-explorer-visual.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8980077785345019219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8980077785345019219'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2010/01/locate-file-in-solution-explorer-visual.html' title='Locate File in Solution Explorer - Visual Studio Macro'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-3607499833715350368</id><published>2009-12-10T12:57:00.004+02:00</published><updated>2009-12-10T13:12:19.470+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="SVN"/><category scheme="http://www.blogger.com/atom/ns#" term="VisualSVN Server"/><title type='text'>Visual SVN :: Setting up Subversion the easy way</title><content type='html'>I had to install a subversion repository on a server today, and I thought it was going to be a headache because the last time I dealt with Subversion was years ago and I was a rather uninterested spectator at the time.  I had seen &lt;a href=&quot;http://www.rohland.co.za/&quot;&gt;Rohland&lt;/a&gt; using VisualSVN before, so I thought I&#39;d give it a try.
&lt;br /&gt;&lt;br /&gt;
It was so simple to install, there&#39;s barely anything worth mentioning.  &lt;a href=&quot;http://www.visualsvn.com/server/&quot;&gt;Download the file&lt;/a&gt;, &lt;a href=&quot;http://www.visualsvn.com/server/doc/server-config/&quot;&gt;load up the documentation&lt;/a&gt;, follow the steps and there you go.  I created an administrators group, a user to slot into that group, and removed access to &quot;Everyone&quot;, and that was the access side done.  I created a repository, let the tool create the default structure, and that was pretty much the sum total of the installation. 
&lt;br /&gt;&lt;br /&gt;
Note that any settings you apply during creation are not cast in stone - once the installation is complete you can always change your configuration by loading up the VisualSVN Server snap-in, right clicking &quot;VisualSVN Server&quot; and clicking &quot;Properties&quot;.
&lt;br /&gt;&lt;br /&gt;
The only difference in my configuration was changing the port - instead of using 443 I wanted to use a different port number.  I stopped the VisualSVN service, changed the value in the configuration (see previous paragraph), and restarted the service.  My repository was then available via https://myserver:7443/svn/myrepo/trunk/.
&lt;br /&gt;&lt;br /&gt;
A total learning curve of about 3 minutes.  Fantastic.</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/3607499833715350368/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/12/visual-svn-setting-up-subversion-easy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3607499833715350368'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3607499833715350368'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/12/visual-svn-setting-up-subversion-easy.html' title='Visual SVN :: Setting up Subversion the easy way'/><author><name>Matt Salmon</name><uri>http://www.blogger.com/profile/16337580189902073323</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>