<?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: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>2012-01-26T13:18:46.678+02:00</updated><category term='Visual Studio'/><category term='Mocking'/><category term='MVC'/><category term='javascript'/><category term='ILMerge'/><category term='Powershell'/><category term='Encoding'/><category term='NCover'/><category term='Sandcastle'/><category term='Moq'/><category term='selenium'/><category term='sql server express'/><category term='ASP.NET'/><category term='HTTP'/><category term='Automated testing'/><category term='restore'/><category term='encryption'/><category term='FxCop'/><category term='favicon'/><category term='MSDTC'/><category term='Macro'/><category term='performance'/><category term='Obfuscation'/><category term='Documentation'/><category term='windows services'/><category term='backup'/><category term='NUnit'/><category term='debug'/><category term='WatIn'/><category term='Web services'/><category term='VisualSVN Server'/><category term='MSBuild'/><category term='prettify'/><category term='sql server'/><category term='publishing'/><category term='C#'/><category term='CruiseControl.NET'/><category term='nServiceBus'/><category term='WCF'/><category term='sql'/><category term='unit testing'/><category term='log4net'/><category term='T-SQL'/><category term='Handbrake'/><category term='syntax highlighter'/><category term='SVN'/><category term='FFMpeg'/><category term='PerfMon'/><category term='.NET'/><title type='text'>Matt Salmon'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?max-results=100'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><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='http://img2.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>100</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="prettyprint" style="background-color: rgb(240, 240, 240);"&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;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-5592011527234040660?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='0 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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</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;"Cannot redirect after HTTP headers have been sent."&lt;/code&gt;&lt;/pre&gt;&lt;font face="Arial"&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="Courier New"&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;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-4608143094771684766?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='2 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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</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='MVC'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><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 "Copy Local".  &lt;p&gt;&lt;a href="http://www.tugberkugurlu.com/archive/deployment-of-asp-net-mvc-3-rc-2-application-on-a-shared-hosting-environment-without-begging-the-hosting-company"&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 'WebMatrix' 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 "using WebMatrix" references in them. As such, even though you don'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 "WebSecurity.InitializeDatabaseFile" or "WebSecurity.InitializeDatabaseConnection" method before you call any other method of the "WebSecurity" 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="background-color: rgb(240,240,240)" class="prettyprint"&gt;namespace WebMatrix.Data { internal class Ignore { } }
namespace WebMatrix.WebData { internal class Ignore { } }
&lt;/pre&gt;
&lt;p&gt;Reference: &lt;a title="http://stackoverflow.com/questions/4146545/razor-helper-in-mvc-3-rc" href="http://stackoverflow.com/questions/4146545/razor-helper-in-mvc-3-rc"&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. 
  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-9144577819885006285?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='1 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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</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="http://technet.microsoft.com/en-us/library/cc753194(WS.10).aspx"&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="http://www.codesector.com/teracopy.php"&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="http://odetocode.com/blogs/scott/archive/2011/02/16/notes-on-building-razor-views.aspx" href="http://odetocode.com/blogs/scott/archive/2011/02/16/notes-on-building-razor-views.aspx"&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="http://advsys.net/ken/utils.htm" href="http://advsys.net/ken/utils.htm"&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="http://code.google.com/p/dapper-dot-net/" href="http://code.google.com/p/dapper-dot-net/"&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="http://www.west-wind.com/weblog/posts/2011/May/05/Builtin-GZipDeflate-Compression-on-IIS-7x" href="http://www.west-wind.com/weblog/posts/2011/May/05/Builtin-GZipDeflate-Compression-on-IIS-7x"&gt;http://www.west-wind.com/weblog/posts/2011/May/05/Builtin-GZipDeflate-Compression-on-IIS-7x&lt;/a&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-8786880730622988334?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='http://img2.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="prettyprint" style="background-color:rgb(240,240,240);"&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="prettyprint" style="background-color:rgb(240,240,240);"&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="http://yoursite/Services/YourService.svc"&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 "%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation" 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="prettyprint" style="background-color:rgb(240,240,240);"&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="http://msdn.microsoft.com/en-us/netframework/dd939784"&gt;http://msdn.microsoft.com/en-us/netframework/dd939784&lt;/a&gt; 
&lt;li&gt;&lt;a href="http://channel9.msdn.com/shows/Endpoint/Endpoint-Screencasts-Creating-Your-First-WCF-Service/"&gt;http://channel9.msdn.com/shows/Endpoint/Endpoint-Screencasts-Creating-Your-First-WCF-Service/&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-8685934706555576806?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='http://img2.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="http://msdn.microsoft.com/en-us/library/f7dy01k1%28VS.80%29.aspx"&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="color: orange"&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="http://lh3.ggpht.com/_mRZGgx0QDv0/TOO_aJjj6FI/AAAAAAAADNI/N3xk2pe2vcQ/Mainfest%5B17%5D.png?imgmax=800"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="Mainfest" border="0" alt="Mainfest" src="http://lh3.ggpht.com/_mRZGgx0QDv0/TOPBS02EzZI/AAAAAAAADNM/f2yK39WDoJ8/Mainfest_thumb%5B13%5D.png?imgmax=800" width="244" height="155"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Useful!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-8679075867836051343?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='http://img2.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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-845034378335771586?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='3 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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</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'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 + '.' + table_name 
FROM information_schema.tables
WHERE table_type = 'base table'

OPEN cur

FETCH NEXT FROM cur INTO @tableName
WHILE @@FETCH_STATUS = 0
BEGIN
	DBCC DBREINDEX(@tableName,' ',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="print '?' DBCC DBREINDEX ('?')"
&lt;/code&gt;
&lt;/pre&gt;

This is an undocumented stored procedure that I didn'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'd known of this earlier.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-8270860335074221666?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='http://img2.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="http://msdn.microsoft.com/en-us/library/dd460717.aspx"&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 = "http://dev.mysite.co.za/";
        static int testCount = 1000;

        static void Main(string[] args)
        {


            // fire off one request so we aren'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("Done.");
            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("Single requests: {0} seconds", 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("Parallel requests: {0} seconds", 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("Thread pool requests: {0} seconds", sw.Elapsed.TotalSeconds);
        }

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

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

        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;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-988919506712380035?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='http://img2.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='syntax highlighter'/><category scheme='http://www.blogger.com/atom/ns#' term='prettify'/><title type='text'>Prettify</title><content type='html'>&lt;p&gt;Following &lt;a href="http://stackoverflow.com"&gt;stackoverflow’s&lt;/a&gt; example, I’ve started using &lt;a href="http://code.google.com/p/google-code-prettify/"&gt;prettify&lt;/a&gt; for syntax highlighting on this blog.&amp;nbsp; I’ve used the &lt;a href="http://code.google.com/p/syntaxhighlighter/"&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="http://closure-compiler.appspot.com/home"&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="http://www.codingthewheel.com/archives/syntax-highlighting-stackoverflow-google-prettify"&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;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-6637695467712679381?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='http://img2.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("SELECT * FROM Win32_POTSModem");
foreach (ManagementObject mo in mos.Get())
{
    string s= mo["AttachedTo"].ToString();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Other properties available can be looked up here: &lt;a href="http://msdn.microsoft.com/en-us/library/aa394360%28VS.85%29.aspx"&gt;http://msdn.microsoft.com/en-us/library/aa394360%28VS.85%29.aspx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-1688416233866317717?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='http://img2.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="http://wix.sourceforge.net/"&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="http://www.tramontana.co.hu/wix/index.php#TOC"&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="http://wix.sourceforge.net/manual-wix3/WixUI_dialogs.htm"&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="brush: xml" name="code"&gt;&amp;lt;wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension"&amp;gt;
&lt;/pre&gt;
&lt;p&gt;You can then use the extension elements as follows:&lt;/p&gt;&lt;pre class="brush: xml" name="code"&gt;&amp;lt;iis:WebSite Id='DefaultWebSite' Description='Default Web Site'&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;iis:WebAddress Id='AllUnassigned' Port='80' /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/iis:WebSite&amp;gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-5271810797804203716?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='http://img2.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='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><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="current"&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("Year in dates do not match as expected.");
            }
            if (precision &amp;gt;= DateTimePrecision.Month &amp;amp;&amp;amp; expected.Month != actual.Month)
            {
                throw new NUnit.Framework.AssertionException("Month in dates do not match as expected.");
            }
            if (precision &amp;gt;= DateTimePrecision.Day &amp;amp;&amp;amp; expected.Day != actual.Day)
            {
                throw new NUnit.Framework.AssertionException("Day in dates do not match as expected.");
            }
            if (precision &amp;gt;= DateTimePrecision.Hour &amp;amp;&amp;amp; expected.Hour != actual.Hour)
            {
                throw new NUnit.Framework.AssertionException("Hour in dates do not match as expected.");
            }
            if (precision &amp;gt;= DateTimePrecision.Minute &amp;amp;&amp;amp; expected.Minute != actual.Minute)
            {
                throw new NUnit.Framework.AssertionException("Minute in dates do not match as expected.");
            }
            if (precision &amp;gt;= DateTimePrecision.Second &amp;amp;&amp;amp; expected.Second != actual.Second)
            {
                throw new NUnit.Framework.AssertionException("Second in dates do not match as expected.");
            }
            if (precision &amp;gt;= DateTimePrecision.Millisecond &amp;amp;&amp;amp; expected.Millisecond != actual.Millisecond)
            {
                throw new NUnit.Framework.AssertionException("Millisecond in dates do not match as expected.");
            }


        }
    }

    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'd love to know if anyone else has any better solutions for unit testing date equality in .NET.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-4173769595023421239?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='0 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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</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="http://www.microsoft.com/downloads/details.aspx?familyid=22914587-b4ad-4eae-87cf-b14ae6a939b0&amp;displaylang=en"&gt;ILMerge&lt;/a&gt; today for the first time, and it's great. &lt;a href="http://msdn.microsoft.com/en-us/library/bb397866.aspx"&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&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-7745027806663264277?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='http://img2.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't find a reference on the web that actually worked for me.  I thought I'd post it here for future reference, as it applies to the execution of any executable from within Powershell.  It was "Invoke-Expression" that I hadn't used before.

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

# 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 "/noconsolelogger" 
# from the $options string
$clean = $msbuild + " ""MySolution.sln"" " + $options + " /t:Clean"
$build = $msbuild + " ""MySolution.sln"" " + $options + " /t:Build"
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;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-5539192553850564180?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='3 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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</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'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'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="code" class="brush: xml"&gt; 
 &amp;lt;system.diagnostics&amp;gt;
    &amp;lt;trace autoflush="true"&amp;gt;
      &amp;lt;listeners&amp;gt;
        &amp;lt;add
          name="textWriterTraceListener"
          type="System.Diagnostics.TextWriterTraceListener"
          initializeData="C:\temp\log4net.txt" /&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="code" class="brush: xml"&gt;
  &amp;lt;add key="log4net.Internal.Debug" value="true"/&amp;gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-5950246446192410856?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='http://img2.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='NUnit'/><category scheme='http://www.blogger.com/atom/ns#' term='NCover'/><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="http://ncover.org"&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'll be able to upgrade to the commercial version.
&lt;br /&gt;&lt;br /&gt;
Anyway, getting ncover wasn't a big deal, I added the following section to the ccnet.config file for our project:
&lt;br /&gt;
&lt;pre class="brush: xml"&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;"C:\Program Files\NUnit 2.5.2\bin\net-2.0\nunit-console-x86.exe" 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'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'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="brush: plain"&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'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's not optimal, but until a newer version comes out with a fix, it's good enough for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-7480332304432236153?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='http://img2.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="http://www.favicon.cc/"&gt;http://www.favicon.cc/&lt;/a&gt;.
&lt;br /&gt;&lt;br /&gt;
Nice!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-246857437453386783?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='http://img2.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='FFMpeg'/><category scheme='http://www.blogger.com/atom/ns#' term='Encoding'/><category scheme='http://www.blogger.com/atom/ns#' term='Handbrake'/><title type='text'>FFMPeg and the XBox 360</title><content type='html'>I'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'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've been using &lt;a href="http://handbrake.fr/"&gt;Handbrake&lt;/a&gt; to do conversions, and it works.  Handbrake is an excellent piece of software, but it isn'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've been trying for ages to convert the files to .mp4 with &lt;a href="http://ffmpeg.org/"&gt;ffmpeg&lt;/a&gt;, but the damn things just wouldn't play.  I finally worked it out today.  The mpegs have 5 channel Dolby audio - the XBox 360 doesn't support that.  All I needed to do was restrict the audion channels to 2 on the output, and it worked!  I haven'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'm done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-2554161580586754792?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='http://img2.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 "Parameter name: meth"</title><content type='html'>It'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="http://tech.groups.yahoo.com/group/nservicebus/message/3219"&gt;found this post&lt;/a&gt; about it and it'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'd post this on here for my own future reference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-5382706772429659954?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='http://img2.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='HTTP'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>HTTP Pre-Authentication</title><content type='html'>Rick Strahl posted &lt;a href="http://west-wind.com/Weblog/posts/243915.aspx"&gt;this excellent article&lt;/a&gt; on pre-authenticating HTTP requests - this is something that'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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-2502817383210959216?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='http://img2.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'm working on a development database with a lot of varbinary fields - these are great once you have your admin screens but they'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="brush: sql"&gt;
update [schema].[table] set Column = (
 SELECT * 
        FROM OPENROWSET(BULK N'E:\Share\Temp\myfile.jpg', SINGLE_BLOB) AS BinaryFile
)
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-4567148169098163204?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='http://img2.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="http://misfitgeek.com/"&gt;Joe Stagner&lt;/a&gt; posted &lt;a href="http://misfitgeek.com/blog/aspnet/unwinding-the-page-lifecycle-events/"&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....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-9010103185583364364?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='http://img2.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='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='Macro'/><title type='text'>Locate File in Solution Explorer - Visual Studio Macro</title><content type='html'>A colleague found &lt;a href="http://www.brianschmitt.com/2010/01/locate-file-in-solution-explorer-visual.html"&gt;this blog post by Brian Schmitt&lt;/a&gt;, which is one of the most useful little tips I've seen in ages.
&lt;br /&gt;&lt;br /&gt;
I'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'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'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="brush: text"&gt;
    Public Sub LocateFileInSolutionExplorer()
        DTE.ExecuteCommand("View.TrackActivityinSolutionExplorer")
        DTE.ExecuteCommand("View.TrackActivityinSolutionExplorer")
        DTE.ExecuteCommand("View.SolutionExplorer")
    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 "Show commands containing" 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 "Press shortcut keys" 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's it.  &lt;/li&gt;
&lt;li&gt;Watch productivity soar.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-8980077785345019219?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&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='1 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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</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="http://www.rohland.co.za/"&gt;Rohland&lt;/a&gt; using VisualSVN before, so I thought I'd give it a try.
&lt;br /&gt;&lt;br /&gt;
It was so simple to install, there's barely anything worth mentioning.  &lt;a href="http://www.visualsvn.com/server/"&gt;Download the file&lt;/a&gt;, &lt;a href="http://www.visualsvn.com/server/doc/server-config/"&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 "Everyone", 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 "VisualSVN Server" and clicking "Properties".
&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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-3607499833715350368?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-8018874829700911071</id><published>2009-11-23T12:56:00.007+02:00</published><updated>2010-07-01T11:51:00.640+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='nServiceBus'/><title type='text'>nServiceBus - The Good and the Bad</title><content type='html'>We've been using &lt;a href="http://www.nservicebus.com"&gt;nServiceBus&lt;/a&gt; at work for the last week or two to send messages between a client and server in a (hopefully) robust fashion.
&lt;br /&gt;&lt;br /&gt;
As a tool, I really like nServiceBus.  Once you have it up and running, the use of MSMQ is just brilliant - force a crash in your application and when you start up again they're just there still, ready to be processed - right out the box.  Wrap them in a transaction (MSMQ supports MSDTC) and anything goes wrong, the sending of the message gets rolled back.  Awesome stuff - it's definitely something I will use again.  
&lt;br /&gt;&lt;br /&gt;
But that's not the point of this post.  I'm going to point out all the BAD stuff - in the hope that someone else doesn't have the same fights I did.  Let me say upfront that I recommend using it - just be aware that the document isn't just bad, it's DISMAL.  The author seems to assume that we all understand how the bus works and how to use it - methods are undocumented and even the documentation on how to get it up and running is hopelessly inadequate.  So, here goes.
&lt;br /&gt;&lt;br /&gt;
&lt;b&gt;Configuration&lt;/b&gt;
&lt;br /&gt;&lt;br /&gt;
The nServiceBus site does have some documentation regarding publish/subscribe scenarios at &lt;a href="http://www.nservicebus.com/PubSubApiAndConfiguration.aspx"&gt;http://www.nservicebus.com/PubSubApiAndConfiguration.aspx&lt;/a&gt;.  However, the way it's worded just didn't make sense to me, and it was &lt;a href="http://www.rohland.co.za/"&gt;Rohland &lt;/a&gt;who finally worked out what the hell they mean.
&lt;br /&gt;&lt;br /&gt;
&lt;i&gt;Exhibit A&lt;/i&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;pre class="brush: xml"&gt;
&amp;lt;MsmqTransportConfig
    InputQueue="myqueue"
    ErrorQueue="errors"
    NumberOfWorkerThreads="1"
    MaxRetries="5"
  /&amp;gt;
&lt;/pre&gt;

The above configuration specifies the INPUT to your assembly's message handler.  In this example, the application using this configuration will listen for messages on the MSMQ "myqueue" on the local machine.  It will NOT place messages on that queue - this is the queue it will pick messages up from.
&lt;br /&gt;&lt;br /&gt;
&lt;i&gt;Exhibit B&lt;/i&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;pre class="brush: xml"&gt;
  &amp;lt;UnicastBusConfig DistributorControlAddress="" DistributorDataAddress=""&amp;gt;
    &amp;lt;MessageEndpointMappings&gt;
      &amp;lt;add Messages="My.Messages" Endpoint="somequeue" /&amp;gt;
    &amp;lt;/MessageEndpointMappings&amp;gt;
  &amp;lt;/UnicastBusConfig&amp;gt;
&lt;/pre&gt;
This configuration specifies where your application will publish messages TO!  In this example, any messages in the "My.Messages" assembly will be placed on the "somequeue" MSMQ on the local machine.  You can specify message types instead of assemblies if you want to.  I quite like this - it makes it very easy to publish different messages to different queues, and it's all configurable.  Also note that the end point doesn't have to be local - you can specify remote machines as per the nServiceBus documentation.
&lt;br /&gt;&lt;br /&gt;
&lt;b&gt;Message Handlers&lt;/b&gt;
&lt;br /&gt;&lt;br /&gt;
In order to receive messages, your assembly that handles those messages needs to incorporate a message handler class, with support for the message types you want to receive.  For example, if you want to subscribe to message types "A" and B", you can create a message handler like so:

&lt;pre class="brush: csharp"&gt;
public class MessageHandler : IMessageHandler&amp;lt;A&amp;gt;, IMessageHandler&amp;lt;B&amp;gt;
{
    public void Handle(A message)
    {
        // handle messages of type A
    }

    public void Handle(B message)
    {
        // handle messages of type B
    }

}
&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
You don't hook this class up anywhere - nServiceBus will find it and instantiate it.  I don't like that.  It makes it really easy to make mistakes - make a typo on your namespace and your event handler is never invoked, and you sit there scratching your head wondering why until you finally realise your config is fine, and your typing sucks.  Another downer is that this is running on a separate thread to your application, so you need to invoke a delegate on appplication's main thread to handle the code, which can be a little iffy in forms development - you need to write code like the following to get a handle on the form that you want to use, like so:
&lt;pre class="brush: csharp"&gt;
FormMain fm = FormMain.GetInstance();
fm.Invoke(fm.AddInboundMessageHandler, message);
&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;b&gt;Enumerations and/or More Complex Data Structures&lt;/b&gt;
&lt;br /&gt;&lt;br /&gt;
One problem I found, when using version 1.9, was when sending an enumeration of custom objects via a message.  My message class contained an array of custom objects, which themselves had two properties: a string property and a byte array property.  Nothing complex here.  However, when I picked up the message on the subscriber, the collection was there, with the correct number, but the properties of the objects in the array were always null.  I just couldn't get this to work at all.   Converting the array to a dictionary was even worse - I got exceptions from nServiceBus, which seemed to fall over on some rather dodgy reflection code.  
&lt;br /&gt;&lt;br /&gt;
One thing I did find out is that your sub-entities do need to have a default, parameterless constructor, which makes sense as nServiceBus needs to recreate the serialized objects from the queue on the other end.  However, try as I might, I never got this working on 1.9.  Upgrading to version 2.0, however, and it all started working.  I did try converting my array into a typed list for convenience, but this didn't work off the bat and wasn't that important to me so I reverted back to an array.
&lt;br /&gt;&lt;br /&gt;
That's all I can think of for now - I'm sure I'll update this post in the future.
&lt;br /&gt;&lt;br /&gt;
&lt;b&gt;References&lt;/b&gt;
When I started looking at this there was NOTHING out there - but people are certainly using it.  Her are some decent articles on nServiceBus:
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://mookid.dk/oncode/archives/711"&gt;http://mookid.dk/oncode/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-8018874829700911071?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/8018874829700911071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/11/nservicebus-good-and-bad.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8018874829700911071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8018874829700911071'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/11/nservicebus-good-and-bad.html' title='nServiceBus - The Good and the Bad'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-6696047950197139502</id><published>2009-11-16T08:46:00.004+02:00</published><updated>2009-11-16T08:53:51.373+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MSDTC'/><title type='text'>MS DTC Timeout error</title><content type='html'>I had a very frustrating Friday evening fighting with MSDTC.  I made a one-line, 10 second change to a page I was working on.  It was one of those things that you really don't even need to test usually, but I always test, no matter how small the change, and 2.5 hours later I was still pulling my hair out.  I just kept getting MSDTC timeout exceptions.
&lt;br /&gt;&lt;br /&gt;
Now, this was a page that had been working literally hours before, with no other code changes.  The ONLY difference I could think of, was that I had applied windows updates to my machine - but this turned out to be a red herring.  The same page, with the same code, worked on a colleague's machine.  I checked settings, triple checked settings, flushed my DNS cache, restarted my machine, all to no avail.  Comment out the TransactionScope - it all worked fine, put it back in, boom!  
&lt;br /&gt;&lt;br /&gt;
Anyway, in case this happens to anyone else ever - this turned out to be a DNS issue on the SERVER.  Logging into the server I could ping my machine by IP, but pinging by host name failed.  Finally, I was getting somewhere.  It turned out there was a dodgy DNS entry - flushing the DNS cache on the server worked and everything returned to normal.  What a waste of 2.5 hours.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-6696047950197139502?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/6696047950197139502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/11/ms-dtc-timeout-error.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/6696047950197139502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/6696047950197139502'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/11/ms-dtc-timeout-error.html' title='MS DTC Timeout error'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-3367520714865448062</id><published>2009-11-13T08:41:00.006+02:00</published><updated>2010-07-01T11:52:59.933+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='Moq'/><title type='text'>Moq :: Ignoring Arguments</title><content type='html'>I've always used &lt;a href="http://www.ayende.com/projects/rhino-mocks.aspx"&gt;Rhino Mocks&lt;/a&gt; as a mocking framework, but at work we recently made the decision to give &lt;a href="http://code.google.com/p/moq"&gt;Moq&lt;/a&gt; a try.  
&lt;br /&gt;&lt;br /&gt;
My initial reaction is: WOW!  It is just SO much easier to use.  I've always found the setting up of mocks and verification of method calls a tedious task, but using Moq I've actually found it's really simple.  It's a far more intuitive framework, and once I've got around my Rhino Mock habits, I've really found that the amount of code required for mocking is drastically reduced.
&lt;br /&gt;&lt;br /&gt;
One very simple thing that stumped me today though, was trying to verify a method was called, but telling Moq to ignore the argument that was passed.  In this case Rhino Mocks is a little more intuitive - it has an IgnoreArguments() method that chains off the setup.  In the end though, the Moq implementation is actually easier - you just make your Setup or Verify call and use the "It" class to generate your stub.
&lt;br /&gt;&lt;br /&gt;
In my example:

&lt;pre class="brush: csharp"&gt;
  myMockedClass.Verify(x =&amp;gt; x.Connect(It.IsAny&amp;lt;MyArgumentType&amp;gt;()));
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-3367520714865448062?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/3367520714865448062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/11/moq-ignoring-arguments.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3367520714865448062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3367520714865448062'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/11/moq-ignoring-arguments.html' title='Moq :: Ignoring Arguments'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-1798975940884257138</id><published>2009-10-06T13:37:00.005+02:00</published><updated>2009-10-06T13:44:04.711+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='publishing'/><title type='text'>.NET Assembly Probing</title><content type='html'>I hate the way Windows Forms applications get built with all their binaries in a single folder.  I also hate the publish options in Visual Studio - those crappy .application files stink in so many ways.  I prefer to just deploy the executable and related assemblies using some kind of packaging tool.
&lt;br /&gt;&lt;br /&gt;
The problem here is all the dll's by default need to be in the base appdomain directory, which can end up being a horrible mess in the base install directory.  There is a configuration option you can use with your application, though, to tell it to search in other folders for required assemblies, like so:
&lt;pre name="code" class="xml:nocontrols"&gt;&lt;configuration&gt;
  &lt;runtime&gt;
    &lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&gt;
      &lt;probing privatePath="bin;anotherbin\subfolder;yetanotherbin" /&gt;
    &lt;/assemblyBinding&gt;
  &lt;/runtime&gt;
&lt;/configuration&gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-1798975940884257138?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/1798975940884257138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/10/net-assembly-probing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1798975940884257138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1798975940884257138'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/10/net-assembly-probing.html' title='.NET Assembly Probing'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-1035049066954133705</id><published>2009-10-06T10:10:00.004+02:00</published><updated>2009-10-06T10:19:49.720+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CruiseControl.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Automated testing'/><category scheme='http://www.blogger.com/atom/ns#' term='WatIn'/><title type='text'>WatiN with CruiseControl running as a service</title><content type='html'>We've started using &lt;a href="http://watin.sourceforge.net/"&gt;WatiN&lt;/a&gt; for our automated tests: nice and easy to use and integrates easily, but I did hit one stumbling block: CruiseControl.NET.  When running tests locally, there were no issues - check the code in and bang, the tests fail.  It was immediately apparent that it was a security thing - the CruiseControl.NET service runs by default with the SYSTEM user, but I could find little to no help anywhere on how to set this up correctly.  
&lt;br /&gt;&lt;br /&gt;
One solution was to just tick the service option to "Allow service to interact with the desktop", but this didn't work for me - the failure remained the same when the browser instance was being created.
&lt;br /&gt;&lt;br /&gt;
It took a few hours of testing (I ended up using a local Scheduled Task to test this out) and I finally found a fairly easy way to get it to work - on your build server you need to use a local account that the service runs under.  I used a local admin account - you might not be able to do this in which case you're on your own (it'll still work - you'll just need to be more careful about how you apply permissions), but the steps to set this up are as follows:
&lt;ul type="square"&gt;
&lt;li&gt;Create a local admin account (e.g. CCAdmin) - make sure you set it so the password does not need to be changed and does not expire 
&lt;li&gt;Log out, and log back in using the new account 
&lt;li&gt;Open up IE (or whatever your testing browser is) and go through all the dialog screens. Set the home page to blank.  If you're using Firefox, make sure all the required plugins are installed. &lt;/li&gt;
&lt;li&gt;Open up services.msc (Start...Run....services.msc), and stop the CruiseControl.NET service. Right-click and go to Properties &lt;/li&gt;
&lt;li&gt;Go to the Log On tab, and instead of a Local System account, set it so the service uses your new account &lt;/li&gt;
&lt;li&gt;If you have not created an admin account, make sure the account has all necessary security permissions &lt;/li&gt;
&lt;li&gt;Click OK, and fire up the service again &lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-1035049066954133705?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/1035049066954133705/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/10/watin-with-cruisecontrol-running-as.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1035049066954133705'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1035049066954133705'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/10/watin-with-cruisecontrol-running-as.html' title='WatiN with CruiseControl running as a service'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-3708541050732683437</id><published>2009-09-29T14:50:00.004+02:00</published><updated>2009-09-29T15:33:06.245+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='WatIn'/><title type='text'>WatIn</title><content type='html'>I've been fighting with Selenium and automated testing lately, and I just couldn't shake the feeling that it just wasn't the right tool for the job.  The IDE is flakey in terms of files you save (making changes to the project often results in JS errors in the tests), the server is a java server which I had to jump through hoops to get running as a Windows service, and the loading of a browser for the tests is hellishly slow.  
&lt;br /&gt;&lt;br /&gt;
It really is a great tool, and I love it's ease of use for development (I use it to autocomplete forms instead of typing all that crap in over and over again), but as an automated testing suite on a Windows technology stack, I'm just not a huge fan.
&lt;br /&gt;&lt;br /&gt;
So today, I &lt;a href="http://watin.sourceforge.net/"&gt;downloaded WatIn&lt;/a&gt; and gave it a run.  I had the automated nUnit side up and running in a matter of minutes - the tests ran fast and the API is intuitive and easy to use.  
&lt;br /&gt;&lt;br /&gt;
The test recorder is not as good as Selenium's, but it's decent enough, and there is a beta version out that is supposed to be a vast improvement.  I did download and try the Beta version, but it wouldn't even run for me, so I guess it's REALLY in Beta.  Anyway, I'm more interested in the CruiseControl automated side of testing than visual testing, so it's easy, understandable unit test code that I want to be able to produce - and for this WatIn wins hands down.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-3708541050732683437?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/3708541050732683437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/09/watin.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3708541050732683437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3708541050732683437'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/09/watin.html' title='WatIn'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-861282375837165719</id><published>2009-09-18T11:28:00.003+02:00</published><updated>2009-09-18T11:38:22.822+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows services'/><category scheme='http://www.blogger.com/atom/ns#' term='selenium'/><title type='text'>Running Selenium RC as a Windows Service</title><content type='html'>We've recently started using &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; as a testing tool at work.   The IDE is great, particularly for filling in forms during development, but I'm a stickler for automated testing. 
&lt;br /&gt;&lt;br /&gt;
Selenium does off Selenium RC, which combined with nUnit allows for this in a variety of programming languages.  The problem here, is that the server is a jar file, and I wanted it running as a windows service on our build server.
&lt;br /&gt;&lt;br /&gt;
Anyway, I found a &lt;a href="http://www.tacktech.com/display.cfm?ttid=197"&gt;great article on tacktech.com&lt;/a&gt; that shows how to run just about anything as a windows service - and I successfully used that article to get Selenium RC running as windows service on our build server.  Here are the steps:
&lt;ol&gt;
&lt;li&gt;Install the latest Java runtime if you don't have it installed already&lt;/li&gt;
&lt;li&gt;Install the Selenium server (e.g. C:\Selenium\selenium-server-1.0.1&lt;/li&gt;
&lt;li&gt;Download srvany.exe and instsrv.exe (these are part of the Microsoft Windows Resource Kit - you will need to download the correct version for your OS) and copy these files to a location on your server (e.g. C:\reskit)&lt;/li&gt;
&lt;li&gt;Browse to this folder, and type: instsrv "Selenium RC" "C:\reskit\srvany.exe" - this will create the windows service named "Selenium RC", which will now be installed as a Windows service, although it won't start up yet&lt;/li&gt;
&lt;li&gt;Open up regedit, and browse to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Selenium RC&lt;/li&gt;
&lt;li&gt;Right-click "Selenium RC" in the tree, and click New - Key, and add a key called "Parameters"&lt;/li&gt;
&lt;li&gt;Open Parameters, and create a new string value called "Application"&lt;/li&gt;
&lt;li&gt;Add the following to the data value for the new string value: "C:\Program Files (x86)\Java\jre6\bin\java.exe" -jar "C:\Selenium\selenium-server-1.0.1\selenium-server.jar", substituting paths to the java exe and the selenium server jar file where appropriate&lt;/li&gt;
&lt;li&gt;Load up the windows services console (services.msc) and start the service &lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-861282375837165719?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/861282375837165719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/09/running-selenium-rc-as-windows-service.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/861282375837165719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/861282375837165719'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/09/running-selenium-rc-as-windows-service.html' title='Running Selenium RC as a Windows Service'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-1211471653803206556</id><published>2009-09-10T14:36:00.004+02:00</published><updated>2010-07-01T11:53:47.967+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><title type='text'>SQL Server: Finding tables by column</title><content type='html'>Assuming you use a decent naming convention in your database, it's sometimes useful to be able to find a list of tables with a common column - for example if you want to write a script to clean out all data related to a specific item, referenced by foreign key columns of the same or a similar name.

&lt;pre class="brush: sql"&gt; 
SELECT distinct
    c.table_name,
    c.table_schema,
    c.column_name
  FROM 
    information_schema.columns c
    INNER JOIN information_schema.tables t 
      ON c.table_name = t.table_name 
  WHERE
    c.column_name LIKE '%my_column_name%'
    AND t.table_type = 'BASE TABLE'
  ORDER BY 
    c.table_name,
    c.column_name
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-1211471653803206556?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/1211471653803206556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/09/sql-server-finding-tables-by-column.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1211471653803206556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1211471653803206556'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/09/sql-server-finding-tables-by-column.html' title='SQL Server: Finding tables by column'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-9139746157651981228</id><published>2009-08-27T09:22:00.003+02:00</published><updated>2009-08-27T09:26:49.813+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><title type='text'>Roll on ASP.4</title><content type='html'>Scott Guthrie &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/08/26/starter-project-templates-vs-2010-and-net-4-0-series.aspx"&gt;has started creating posts&lt;/a&gt; about the upcoming features of VS 2010 and .NET 4.
&lt;p&gt;
I've never been a Microsoft fanboy, but you have to give it to them, they really seem to have listened to their users the last few years as they continue to change all the issues people have griped about.  The first two posts indicate more good things to come - the web.config files have been cleaned up (at last!) and now it appears there are some great project templates coming.  What I am really excited about though is the complete control of client IDs that's coming - the whole UniqueID/ClientID pain in the ass has always bothered me about ASP.NET, and it looks like that has finally been addressed in .NET 4.  Flubba dubba.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-9139746157651981228?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/9139746157651981228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/08/roll-on-asp4.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/9139746157651981228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/9139746157651981228'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/08/roll-on-asp4.html' title='Roll on ASP.4'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-3817832294324600093</id><published>2009-08-21T10:58:00.004+02:00</published><updated>2010-07-01T11:54:23.117+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><title type='text'>SQL Server: Currently Executing Queries</title><content type='html'>I found this &lt;a href="http://www.sqlservercentral.com/articles/DMV/64425/"&gt;great article by Ian Stirk&lt;/a&gt; on &lt;a href="http://www.sqlservercentral.com/"&gt;SQLServerCentral.com&lt;/a&gt;, regarding finding queries that are currently executing on SQL Server.  The article contains the following VERY useful query:

&lt;pre class="brush: sql"&gt;
    -- Do not lock anything, and do not get held up by any locks.
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

    -- What SQL Statements Are Currently Running?
    SELECT [Spid] = session_Id
 , ecid
 , [Database] = DB_NAME(sp.dbid)
 , [User] = nt_username
 , [Status] = er.status
 , [Wait] = wait_type
 , [Individual Query] = SUBSTRING (qt.text, 
             er.statement_start_offset/2,
 (CASE WHEN er.statement_end_offset = -1
        THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
  ELSE er.statement_end_offset END - 
                                er.statement_start_offset)/2)
 ,[Parent Query] = qt.text
 , Program = program_name
 , Hostname
 , nt_domain
 , start_time
    FROM sys.dm_exec_requests er
    INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
    CROSS APPLY sys.dm_exec_sql_text(er.sql_handle)as qt
    WHERE session_Id &gt; 50              -- Ignore system spids.
    AND session_Id NOT IN (@@SPID)     -- Ignore this current statement.
    ORDER BY 1, 2
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-3817832294324600093?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/3817832294324600093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/08/sql-server-currently-executing-queries.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3817832294324600093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3817832294324600093'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/08/sql-server-currently-executing-queries.html' title='SQL Server: Currently Executing Queries'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-5171854553243795969</id><published>2009-08-14T09:55:00.005+02:00</published><updated>2010-07-01T11:54:42.725+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><title type='text'>SQL Server: Changing Object Schema</title><content type='html'>I'd forgotten the syntax for moving an object to a different schema:

&lt;pre class="brush: sql"&gt;
alter schema NewSchema transfer OldSchema.ObjectName
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-5171854553243795969?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/5171854553243795969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/08/sql-server-changing-object-schema.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5171854553243795969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/5171854553243795969'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/08/sql-server-changing-object-schema.html' title='SQL Server: Changing Object Schema'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-2388216171723506984</id><published>2009-08-13T07:49:00.007+02:00</published><updated>2010-07-01T11:56:16.722+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><title type='text'>SQL Server: Finding and Killing Database Connections</title><content type='html'>This is a query I use often to check what active connections exist for a specified database:
&lt;pre class="brush: sql"&gt;
select  spid, sp.cmd, sp.hostname, sp.loginame, sp.nt_domain, sp.nt_username, sp.program_name
from    master.dbo.sysprocesses sp
where   db_name(dbid) = 'mydatabase'
and DBID &lt;&gt; 0  
and spid &lt;&gt; @@spid 
&lt;/pre&gt;
&lt;p&gt;
If I want to take the database offline I'll then kill these processes using the spid.
&lt;/p&gt;
&lt;p&gt;
I also &lt;a href="http://blog.tech-cats.com/2008/01/kill-all-database-connections-to-sql.html"&gt;found a great post today&lt;/a&gt; that had a nice way of killing ALL active connections, by running the following sql:
&lt;pre class="brush: sql"&gt;
alter database dbName set single_user with rollback immediate  
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
This can then be reverted out with
&lt;pre class="brush: sql"&gt;
alter database dbName set multi_user with rollback immediate 
&lt;/pre&gt;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-2388216171723506984?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/2388216171723506984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/08/sql-server-finding-and-killing-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/2388216171723506984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/2388216171723506984'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/08/sql-server-finding-and-killing-database.html' title='SQL Server: Finding and Killing Database Connections'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-8391992894760037006</id><published>2009-08-07T15:08:00.004+02:00</published><updated>2010-07-01T11:55:41.472+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><category scheme='http://www.blogger.com/atom/ns#' term='restore'/><category scheme='http://www.blogger.com/atom/ns#' term='backup'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Backing up and Restoring SQL Server Databases with .NET</title><content type='html'>I need to create a tool that would do some backing up and restoring of databases as part of a long-running job this week.  I had heard it was fairly simple C# code, but I was pleasantly surprised when I realised just HOW simple it is.
&lt;p&gt;
The namespaces of the SMO libraries required changed between 2005 and 2008, so if you're using the SQL Server 2008 objects, you need to reference the following libraries (usually located in C:\Program Files\Microsoft SQL Server\100\SDK\Assemblies\).  If you're using SQL Server 2005 you only need the first two.
&lt;/p&gt;
&lt;p&gt;
Microsoft.SqlServer.ConnectionInfo
Microsoft.SqlServer.Smo
Microsoft.SqlServer.SmoExtended
Microsoft.SqlServer.Management.Sdk.Sfc
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-weight:bold;"&gt;Backing Up Code&lt;/span&gt;
&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
SqlConnection conn = new SqlConnection("ConnectionString!");
Server dbServer = new Server(new ServerConnection(conn));
Backup backupMgr = new Backup();
backupMgr.Devices.AddDevice("E:\Backups\YourFile.bak", DeviceType.File);
backupMgr.Database = conn.Database;
backupMgr.Action = BackupActionType.Database;
backupMgr.SqlBackup(dbServer);
&lt;/pre&gt;
&lt;p&gt;
&lt;span style="font-weight:bold;"&gt;Restoring Code&lt;/span&gt;
&lt;/p&gt;
&lt;pre class="brush: csharp"&gt;
SqlConnection conn = new SqlConnection("ConnectionString!");
Server dbServer = new Server(new ServerConnection(conn));
Restore restoreMgr = new Restore();
restoreMgr.Devices.AddDevice("E:\Backup\MyFile.bak", DeviceType.File);
restoreMgr.Database = conn.Database;
restoreMgr.Action = RestoreActionType.Database;
restoreMgr.SqlRestore(dbServer);
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-8391992894760037006?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/8391992894760037006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/08/backing-up-and-restoring-sql-server.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8391992894760037006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8391992894760037006'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/08/backing-up-and-restoring-sql-server.html' title='Backing up and Restoring SQL Server Databases with .NET'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-7724098159836465701</id><published>2009-08-05T15:09:00.005+02:00</published><updated>2010-07-01T11:56:53.462+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Documentation'/><category scheme='http://www.blogger.com/atom/ns#' term='Sandcastle'/><title type='text'>Building Code Documentation with SandCastle</title><content type='html'>&lt;p&gt;
I've always used nDoc for building code documentation, and then (around 2 years ago) I shifted to &lt;a href="http://shfb.codeplex.com/"&gt;Sandcastle Help File Builder&lt;/a&gt;.  We're wanting to start documenting code at work, so today I downloaded the latest version (along with &lt;a href="http://sandcastle.codeplex.com/"&gt;Sandcastle&lt;/a&gt; to give the latest versions a whirl.
&lt;/p&gt;
&lt;p&gt;
I was presently surprised.  The last version of SHFB was just an nDoc clone, but now it's moved on a lot.  It's got a whole pile of nice features now, including caching of all the stuff that used to make a build really slow; HTMLHelp 2; and more.
&lt;/p&gt;
&lt;p&gt;
The best addition though is the support for static content.  I actually couldn't figure out how to do it at first - in nDoc there used to be an AdditionalContent option (or something to that affect), and I knew the latest version of SHFB had support for this but I couldn't find an option for it.  Google returned pre-2006 results which were incorrect.  It was staring me in the face all along though - the newest version works like a VS solution - all you need to do is add the files to your solution and they get automatically incorporated.  Very nice.   
&lt;/p&gt;
&lt;p&gt;
Overall, I'm very impressed - it's literally hundreds of times faster than the previous verison I used (if you enable the custom build components that come built-in) and it creates a far slicker output file.
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-weight:bold;"&gt;Update: Error Using MSBuild&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
The latest version of SHFB no longer has a console application included - you need to use MSBuild instead.  However, when trying to hook up my project to MSBuild as per the documentation, I kept getting the following error:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class="brush: text"&gt;error MSB4057: The target "Build" does not exist in the project.&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
I think there's a bug in SHFB where it isn't building the project file correctly.  Adding the following line at the bottom of my .shfbproj file sorted the issue out:
&lt;/p&gt;
&lt;p&gt;
&lt;pre class="brush: xml"&gt;
  &amp;lt;Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" /&amp;gt;
&lt;/pre&gt;
(You can add this directly above the closing &amp;lt;/Project&amp;gt; tag.
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-7724098159836465701?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/7724098159836465701/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/08/building-code-documentation-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/7724098159836465701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/7724098159836465701'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/08/building-code-documentation-with.html' title='Building Code Documentation with SandCastle'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-877016086051461097</id><published>2009-07-21T10:08:00.010+02:00</published><updated>2010-07-01T11:43:31.810+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><title type='text'>SQL Server Locking, Blocking and Waiting</title><content type='html'>Being able to see what is blocking or waiting on a SQL Server machine is essential for most developers these days.  I find myself using the following queries almost daily at the moment, so I thought I'd post them here:
&lt;br /&gt;&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;Waiting&lt;/span&gt;
&lt;pre class="brush: sql"&gt;select 
    tx.[text] as ExecutingSQL, 
    wt.session_id, 
    wt.wait_duration_ms, 
    wt.wait_type, 
    wt.resource_address, 
    wt.blocking_session_id, 
    wt.resource_description
from sys.dm_os_waiting_tasks wt
inner join sys.dm_exec_connections ec on wt.session_id = ec.session_id
cross apply 
(
    select * from sys.dm_exec_sql_text(ec.most_recent_sql_handle)
) as tx
where wt.session_id &gt; 50 and wt.wait_duration_ms &gt; 0
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;Blocking&lt;/span&gt;
&lt;pre class="brush: sql"&gt;select 
    Blocked.session_id as Blocked_Session_ID
    ,Blocked_SQL.text as Blocked_SQL
    ,waits.wait_type as Blocked_Resource
    ,Blocking.session_id as Blocking_Session_ID
    ,Blocking_SQL.text as Blocking_SQL
from sys.dm_exec_connections as Blocking
inner join sys.dm_exec_requests as Blocked on Blocked.blocking_session_id = Blocking.session_id
cross apply
(
    select * from sys.dm_exec_sql_text(Blocking.most_recent_sql_handle)
) AS Blocking_SQL
cross apply
(
    select * from sys.dm_exec_sql_text(Blocked.sql_handle)
) as Blocked_SQL
inner join sys.dm_os_waiting_tasks as waits on waits.session_id = Blocked.session_id
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-877016086051461097?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/877016086051461097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/07/sql-server-locking-blocking-and-waiting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/877016086051461097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/877016086051461097'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/07/sql-server-locking-blocking-and-waiting.html' title='SQL Server Locking, Blocking and Waiting'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-386884927906556337</id><published>2009-07-01T16:52:00.004+02:00</published><updated>2010-07-01T11:46:40.106+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><title type='text'>SQL Server IDENTITY Columns</title><content type='html'>IDENTITY columns can be a real pain in the ass when data gets out of sync.  GUIDs are generally a much better option when it comes to replication, but you aren't always in control of data structures and sometimes you inherit old systems that weren't designed to be replicated.
&lt;br /&gt;
&lt;br /&gt;
That being said, here are some tips on how to get around problems with IDENTITY columns and getting data in sync:
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;IDENTITY_INSERT&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
You can temporarily turn identity insertion off with the following statement:
&lt;pre class="brush: sql"&gt;
SET IDENTITY_insert &amp;lt;table&amp;gt; ON
&lt;/pre&gt;
You can now insert the identity values into your table.  Don't forget to run the same statement on the table, substituting ON for OFF!
&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Reseeding the IDENTITY value&lt;/strong&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, if you want to reset the current identity value on a table to 100, you can use the following statement:
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;
DBCC CHECKIDENT
(
 'schema.table', RESEED, 100
)
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-386884927906556337?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/386884927906556337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/07/sql-server-identity-columns.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/386884927906556337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/386884927906556337'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/07/sql-server-identity-columns.html' title='SQL Server IDENTITY Columns'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-6402614691726657666</id><published>2009-06-19T13:34:00.004+02:00</published><updated>2009-06-19T13:47:00.327+02:00</updated><title type='text'>The ASP.NET Page Life Cycle</title><content type='html'>The ASP.NET life cycle is as much a fantastic model for web developers as it is a pain the butt.  Whenever I change jobs, I encounter different approaches to implementation of pages and controls, rarely with any regard to the correct order of doing things and usually with code that is very difficult to maintain as a result.  If you can't rely on your controls to obey the page life cycle in terms of rendering, you've got a problem.  For example, setting presentation properties during page load may cause trouble if developers set that property on events firing or during PreRender.
&lt;br /&gt;
&lt;br /&gt;
So, when should you do things?  As a rule of thumb, I try to do data binding early (OnInit) and presentation setting late (OnPreRender, or in controls that output custom markup in the Render override).  It's a tricky topic and something that seems to catch most developers - the concept of top-down development with classic ASP and PHP just doesn't apply.
&lt;br /&gt;
&lt;br /&gt;
There's an excellent article on MSDN about the order of events here: &lt;a href="http://msdn.microsoft.com/en-us/library/ms178472.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms178472.aspx&lt;/a&gt;.  
&lt;br /&gt;
&lt;br /&gt;
For my future reference, some items to consider:
&lt;ul&gt;
 &lt;li&gt;Init and Load need to be handled carefully: the Init event for controls fires BEFORE the Init event for the Page; the Load event for controls fires AFTER the Load event for the Page.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-6402614691726657666?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/6402614691726657666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/06/aspnet-page-life-cycle.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/6402614691726657666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/6402614691726657666'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/06/aspnet-page-life-cycle.html' title='The ASP.NET Page Life Cycle'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-7184715132775103855</id><published>2009-06-02T14:45:00.003+02:00</published><updated>2009-06-02T14:57:16.981+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql server express'/><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><title type='text'>SQL Server Express Remote Connections</title><content type='html'>I've been doing some work with SQL Server replication over the last few days, and in order to acheive this I was replicating between one of our DB servers and a SQL Server Express instance on my desktop.  To my surprise, setting up remote connections to Express is actually a major pain in the butt, so I thought I'd document it here.
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Firewall&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;
The first step is to ensure that remote connections are allowed through your firewall.  I was using the default Windows firewall, so I set up a new exception: I called it "SQL Server", Port number 1433, Protocol TCP, and I changed the scope to be "My network (subnet) only"
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;SQL Server Configuration&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;
There are some hidden settings that you need to enable before SQL Server express will allow remote connections.  You will need to load up the SQL Server Configuration Manager and do the following:
&lt;ul&gt;
&lt;li&gt; Under SQL Server 2005 Network Configuration, mark the TCP/IP status as Enabled&lt;/li&gt;
&lt;li&gt; Right-click TCP/IP and go to Properties&lt;/li&gt;
&lt;li&gt; Go to the IP Addresses tab, and scroll down to IP All&lt;/li&gt;
&lt;li&gt; Remove the value in TCP Dynamic Ports, and enter "1433" (same value as you used in firewall) in the TCP Port value&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;SQL Server&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;
The next step is to ensure SQL Server itself allows remote connections. From within SQL Server, go to the SQL Server instance, click Properties, Connections, "Allow remote connections to this server").  Finally, restart the express service and you should be able to connect to your machine's SQL Server instance remotely.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-7184715132775103855?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/7184715132775103855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/06/sql-server-express-remote-connections.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/7184715132775103855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/7184715132775103855'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/06/sql-server-express-remote-connections.html' title='SQL Server Express Remote Connections'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-8633728683640927193</id><published>2009-05-21T10:41:00.001+02:00</published><updated>2009-05-21T10:43:25.772+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Obfuscation'/><title type='text'>Protecting .NET Code with Dotfuscator</title><content type='html'>Although .NET compiles into binary .dlls, these assemblies are extremely easy to reverse-engineer using Reflector, or any other decent Reflection tool.  Although it's not completely secure, the simplest way to protect your code is to run it through the free obfuscation tool that comes with Visual Studio: &lt;a href="http://en.wikipedia.org/wiki/Dotfuscator"&gt;Dotfuscator Community Edition&lt;/a&gt;.  This is available on your programs menu under Visual Studio Tools.
&lt;br /&gt;&lt;br /&gt;
All you need to do, is open up the program and load up your assembly.  There are piles of options available, but the default settings are generally fine for most cases.  Under the Input tab you can add all your input assemblies, provide an output folder under the Build tab, and hit the run button - this will build copies of your dll's but the namespaces, classes, methods, etc are obfuscated into code that is extremely difficult to read.  Of course, it is still readable: it can be decompiled and debugged, but it's a LOT harder to use, particularly for larger projects.
&lt;br /&gt;&lt;br /&gt;
Some notes on the tool:
&lt;ul&gt;
&lt;li&gt;when specifying the output directories it sometimes had issues with long folder names - using "C:\Temp" was a simpler option and the build worked flawlessly from there&lt;/li&gt;
&lt;li&gt;the community edition can be upgraded to the Enhanced Edition, just by registering (which is free)&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-8633728683640927193?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/8633728683640927193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/protecting-net-code-with-dotfuscator.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8633728683640927193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8633728683640927193'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/protecting-net-code-with-dotfuscator.html' title='Protecting .NET Code with Dotfuscator'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-4778759780004772458</id><published>2009-05-20T15:24:00.001+02:00</published><updated>2009-05-20T15:25:56.253+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='PerfMon'/><title type='text'>Using Microsoft's Performance Monitor Tool</title><content type='html'>Knowing how to use PerfMon can be absolutely critical when faced with unknown performance problems on large information systems.  When you're faced with a performance bottleneck in a large server farm, it can be very difficult to track down issues as minor hiccups can have knock-on effects that are far more apparent to the user than the server experiencing the source of the error, as other servers in the chain sit waiting for the problem to be resolved.  PerfMon can be used to track hundreds of performance issues, this article purely serves as an introduction on how to use the tool as it isn't apparent when you load it up.
&lt;br /&gt;&lt;br /&gt;
When you run PerfMon, you can see current statistic and current counters running, but it doesn't provide an option to "Save".  It doesn't quite work like most applications.  In order to start your own log, you need to expand the "Performance Logs and Alerts" tree item, and then select either Counter Logs, Alerts, etc, depending on what you want to log.  In the main display area, you can then right-click and create a new log. 
&lt;br /&gt;&lt;br /&gt;
If you are creating a Counter Log, you will see a log file name, and you will have the ability to add Objects or Counters to that log file.  I usually select individual Counters rather than whole objects, so you can zone in onto the exact items you need to check. 
&lt;br /&gt;&lt;br /&gt;
One item to note is that by default, PerfMon will log to a binary file.  You can change it to log directly to a .csv file or even to a database.  However, if you do log to a binary file format, you can always use the command-line "relog" tool to convert it into other formats.  For example, to convert to csv:

&lt;pre&gt;
  relog MyLogFile.blg -f csv MyLogFile.csv
&lt;/pre&gt;

Once you have finished setting logging options, the log is then saved on the machine.  You can stop and start logging by right-clicking on the log and clicking Start/Stop.  The settings can be exported and imported to/from html format, and you can adjust properties of the log.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-4778759780004772458?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/4778759780004772458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/using-microsofts-performance-monitor.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4778759780004772458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4778759780004772458'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/using-microsofts-performance-monitor.html' title='Using Microsoft&apos;s Performance Monitor Tool'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-8998968420867995217</id><published>2009-05-19T13:59:00.003+02:00</published><updated>2010-06-30T21:24:59.694+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='encryption'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Encrypting cookies with ASP.NET</title><content type='html'>I hadn't noticed it before, but ASP.NET provides a really simple way to encrypt your cookies.  Cryptography is a field best left to the expert, but for simple encryption purposes this method is perfectly adequate.
&lt;br /&gt;&lt;br /&gt;
First off, you will need to add an entry to your machine/web.config:

&lt;pre name="code" class="brush: xml"&gt;
  &amp;lt;machineKey
    validationKey="AutoGenerate,IsolateApps"
    decryptionKey="AutoGenerate,IsolateApps"
    validation="SHA1" decryption="AES" /&amp;gt;
&lt;/pre&gt;

You can then encrypt/decrypt as follows:
&lt;pre name="code" class="brush: csharp"&gt;
  // encryption
  var ticket = new FormsAuthenticationTicket(2, "", DateTime.Now, DateTime.Now.AddMinutes(10), false, "mycookievalue");
  var encryptedData = FormsAuthentication.Encrypt(ticket);

  // decryption
  string myValue = FormsAuthentication.Decrypt(encryptedData).UserData.ToString();
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-8998968420867995217?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/8998968420867995217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/encrypting-cookies-with-aspnet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8998968420867995217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/8998968420867995217'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/encrypting-cookies-with-aspnet.html' title='Encrypting cookies with ASP.NET'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-6181601493996768525</id><published>2009-05-19T11:01:00.002+02:00</published><updated>2010-06-30T21:27:01.367+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='sql server'/><title type='text'>SQL Server Query Plans</title><content type='html'>The caching of query plans in SQL Server is extremely important when it comes to application performance. The way this works is not very well understood - I still don't get all the intricacies of it but as a general rule of thumb, it's a good move to either:

&lt;ol&gt;
&lt;li&gt;
Use stored procedures: these get pre-compiled and allow the re-use of execution plans. They allow for parameters, allowing for a "shared" execution plan&lt;/il&gt;
&lt;li&gt;he use of stored procs is not possible or not part of your design, use sp_executesql - do NOT use EXEC when running dynamic sql. sp_executesql, unlike EXEC, can be parameterised and therefore also allows for "shared" execution plans.&lt;/li&gt;
&lt;/ol&gt;

You can analyse the cached execution plans on SQL Server with the following statement:

&lt;pre class="brush: sql" name="code"&gt; 
with CachedPlans as (
select top 100
    objtype,
    p.size_in_bytes,
    left([sql].[text], 100) as [text],
    usecounts
from sys.dm_exec_cached_plans p
outer apply sys.dm_exec_sql_text (p.plan_handle) sql
)
select * from CachedPlans
where text like '%Select * from MyTable%'
order by usecounts desc
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-6181601493996768525?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/6181601493996768525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/sql-server-query-plans.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/6181601493996768525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/6181601493996768525'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/sql-server-query-plans.html' title='SQL Server Query Plans'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-1767420704778986457</id><published>2009-05-15T23:42:00.005+02:00</published><updated>2010-06-30T21:28:23.227+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>JavaScript Dimensions and Element Positioning</title><content type='html'>Now that the main browsers have (sort of) merged in terms of DOM element positioning, it's a lot easier to position your elements on a web page than it used to be.  I still forget off-hand what is what, so here's a table of the document objects and their properties that are useful when writing dynamic element sizing and/or positioning.
&lt;br /&gt;&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;Screen, Document and Element Sizes&lt;/span&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_mRZGgx0QDv0/Sg3iGc8oIoI/AAAAAAAAAoA/bEWcuRf7eaw/s1600-h/Dimensions.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 314px; height: 400px;" src="http://1.bp.blogspot.com/_mRZGgx0QDv0/Sg3iGc8oIoI/AAAAAAAAAoA/bEWcuRf7eaw/s400/Dimensions.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5336169733981479554" /&gt;&lt;/a&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;table border="1" bordercolor="#888888" cellspacing="0" style="border-color:rgb(136, 136, 136);border-width:1px;border-collapse:collapse;width:90%"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style="font-family:courier new,monospace"&gt;screen.width&lt;/span&gt;&lt;br style="font-family:courier new,monospace" /&gt;
&lt;span style="font-family:courier new,monospace"&gt;screen.height&lt;/span&gt;&lt;br /&gt;
&lt;/td&gt;
&lt;td&gt;The width and height of the user's screen e.g. 1440 x 900&lt;br /&gt;

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style="font-family:courier new,monospace"&gt;screen.availWidth&lt;/span&gt;&lt;br style="font-family:courier new,monospace" /&gt;
&lt;span style="font-family:courier new,monospace"&gt;screen.availHeight&lt;/span&gt;&lt;br /&gt;
&lt;/td&gt;
&lt;td&gt;The width and height of the user's screen excluding taskbars.&lt;br /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="font-family:courier new,monospace;width:224px;height:32px"&gt;document.body.scrollWidth&lt;br /&gt;
document.body.scrollHeight&lt;br /&gt;

&lt;/td&gt;
&lt;td&gt;The actual width and height of the document (see blue arrow above).&lt;br /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="font-family:courier new,monospace"&gt;document.body.clientWidth&lt;br /&gt;
document.body.clientHeight&lt;span&gt;   &lt;/span&gt;&lt;br /&gt;
&lt;/td&gt;
&lt;td&gt;The width and height of the document, not taking into account any scrolling (see red line above)&lt;br /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;

&lt;td style="font-family:courier new,monospace"&gt;element.offsetWidth&lt;br /&gt;
element.offsetHeight&lt;br /&gt;
&lt;/td&gt;
&lt;td&gt;The width and height of an element.  All style elements MUST be applied before getting this value, including display, visibility, etc.&lt;br /&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;span style="font-weight:bold;"&gt;Element Positioning&lt;/span&gt;
&lt;br /&gt;&lt;br /&gt;
Unfortunately, getting an element position isn't quite as easy, due to different implementations in the browser.  The following JavaScript function can be used to get the axt co-ordinates of an element within the document.
&lt;br /&gt;&lt;br /&gt;
&lt;pre name="code" class="brush: js"&gt;
// gets the absolute position of an element on the screen
function getAbsolutePosition(element)
{
    var left = 0;
    var top = 0;
    // internet explorer
    if (element.offsetParent)
    {
        while (element.offsetParent)
        {
            left += element.offsetLeft
            top += element.offsetTop;
            element = element.offsetParent;
        }
    }
    // other browsers
    else if (element.x)
    {
        left = element.x;
        top = element.y;
    }
    return { x:left, y:top };
}
&lt;/pre&gt;
For example, if you have an element with id 'myElement':
&lt;pre name="code" class="brush: js"&gt;
var pos = getAbsolutePosition(document.getElementById('myElement'));
var left = pos.x;
var top = pos.y;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-1767420704778986457?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/1767420704778986457/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/javascript-dimensions-and-element.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1767420704778986457'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/1767420704778986457'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/javascript-dimensions-and-element.html' title='JavaScript Dimensions and Element Positioning'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_mRZGgx0QDv0/Sg3iGc8oIoI/AAAAAAAAAoA/bEWcuRf7eaw/s72-c/Dimensions.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-727416512414146582</id><published>2009-05-14T07:57:00.006+02:00</published><updated>2010-06-30T21:29:31.142+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'>Custom Dictionary Sections in .NET Config Files</title><content type='html'>When you need to add complex configuration structures to .NET config files, you will generally create your own custom configuration section classes, and implement them within your application. However, if you just need a standard key/value pair, you don't need a custom configuration type at all. Instead, you can just define a section using the &lt;span style="font-family:courier new;color:#339999;"&gt;System.Configuration.DictionarySectionHandler&lt;/span&gt;, and there you go - no code required.
&lt;br /&gt;&lt;br /&gt;
&lt;strong&gt;Example&lt;/strong&gt;
&lt;br /&gt;&lt;br /&gt;
Say, for instance, you want a list of status codes that get checked by your application:
&lt;br /&gt;&lt;br /&gt;
In the App.config, define the section and implement the required values:

&lt;pre class="brush: xml" name="code"&gt;
&amp;lt;configSections&amp;gt;
&amp;lt;section name="StatusCodes" type="System.Configuration.DictionarySectionHandler"  /&amp;gt;
&amp;lt;/configSections&amp;gt;
&lt;/pre&gt;

...

&lt;pre class="brush: xml" name="code"&gt;
&amp;lt;StatusCodes&amp;gt;
  &amp;lt;clear /&amp;gt;
  &amp;lt;add key="2" value="Two" /&amp;gt;
  &amp;lt;add key="3" value="Three" /&amp;gt;
  &amp;lt;add key="4" value="Four" /&amp;gt;
  &amp;lt;add key="5" value="Five" /&amp;gt;
&amp;lt;/StatusCodes&amp;gt;
&lt;/pre&gt;

To read these values in code, all you need to do is the following, and you have a Hashtable containing all the values defined in the config file:

&lt;pre class="brush: csharp" name="code"&gt;
Hashtable statusCodes = ConfigurationManager.GetSection("StatusCodes") as Hashtable;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-727416512414146582?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/727416512414146582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/custom-dictionary-sections-in-net.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/727416512414146582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/727416512414146582'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/custom-dictionary-sections-in-net.html' title='Custom Dictionary Sections in .NET Config Files'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-2374705658778439127</id><published>2009-05-11T16:29:00.000+02:00</published><updated>2009-05-11T16:30:47.152+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Web services'/><title type='text'>Creating and Consuming .NET Web Services</title><content type='html'>I quite liked this article by Dimitrios Markatos:

&lt;a href="http://dotnetjunkies.com/Tutorial/4D13CEFA-D0FD-44BE-8749-8D17B5757564.dcik"&gt;http://dotnetjunkies.com/Tutorial/4D13CEFA-D0FD-44BE-8749-8D17B5757564.dcik&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-2374705658778439127?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/2374705658778439127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/creating-and-consuming-net-web-services.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/2374705658778439127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/2374705658778439127'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/creating-and-consuming-net-web-services.html' title='Creating and Consuming .NET Web Services'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-3027877268618156193</id><published>2009-05-11T15:04:00.004+02:00</published><updated>2010-06-30T21:30:25.378+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='FxCop'/><title type='text'>FxCop: Excluding rules in code</title><content type='html'>One of the tools we use at my current job to validate code as part of our automated build is &lt;a href="http://en.wikipedia.org/wiki/FxCop"&gt;FxCop&lt;/a&gt;.  It can be a pain, but we've found it very useful in terms of standardising our code and rooting out all those un-used variables that seem to grow to epic proportions with a project of any decent size.
&lt;p&gt;
However, as with all tools, it's not perfect, and sometimes it throws errors that really aren't of any significance and can be safely ignored.  This can be done from within the FxCop project, but it can also be done via code, which means it will be forever ignored, even if the FxCop project file changes.
&lt;/p&gt;
This is a 2-step process:
&lt;ol&gt;&lt;li&gt;Declare conditional compile symbol for your project named CODE_ANALYSIS (In Visual Studio 2005 under the Build Tab of the project properties, there is a "Conditional compilation symbols" input field)&lt;/li&gt;&lt;li&gt;Mark your method or property with a "SuppressMessage" attribute, as follows:&lt;/li&gt;&lt;/ol&gt;
&lt;pre name="code" class="brush: csharp"&gt;
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public string MyProperty
{
  get { return 123; }
}
&lt;/pre&gt;

The first parameter is the category of the error, and the second is the rule code and name split by a colon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-3027877268618156193?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/3027877268618156193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/fxcop-excluding-rules-in-code.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3027877268618156193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3027877268618156193'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/fxcop-excluding-rules-in-code.html' title='FxCop: Excluding rules in code'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-4659467559364064973</id><published>2009-05-09T11:10:00.002+02:00</published><updated>2010-06-30T21:23:02.577+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='syntax highlighter'/><title type='text'>Google syntax highlighter</title><content type='html'>In setting up this blog, I was weighing up my options as to how to highlight code.  You can do it manually by setting the colour of individual words, but that is just a pain in the ass, particularly for larger posts so I considered writing a JavaScript class for doing it.

Fortunately, sense prevailed and I searched the web first, and I came across the &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;Google syntax highlighter&lt;/a&gt;.  This thing is awesome.  It handles a number of different languages, displays line numbers automatically, and even has a number of utility options you can display like printing, clipboard copying, and more.  Great stuff.  Best of all, it's so easy to use.  All you need to do is include the JavaScript files and the css file, and mark your code with some simple attributes:

&lt;pre name="code" class="brush: html"&gt;
 &amp;lt;pre name="code" class="brush: html"&amp;gt;
   ... some code here ...
 &amp;lt;/pre&amp;gt;
&lt;/pre&gt;
Finally, add some JavaScript to the end of your page, and that's it. 
&lt;pre name="code" class="brush: js"&gt;
  SyntaxHighlighter.config.bloggerMode = true;
  SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
  SyntaxHighlighter.all();
&lt;/pre&gt;
You don't need the first two lines of this script unless you're adding it to a blog.  If you ARE adding it to a blog, you'll need to host the .css and .js files on an external site and add them to your blog template.  The rest of the instructions remain the same.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-4659467559364064973?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/4659467559364064973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/google-syntax-highlighter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4659467559364064973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/4659467559364064973'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/google-syntax-highlighter.html' title='Google syntax highlighter'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8111117761365139552.post-3537375173023901231</id><published>2009-05-09T11:00:00.001+02:00</published><updated>2009-05-09T17:47:02.222+02:00</updated><title type='text'>Intro</title><content type='html'>I'm creating this blog as a repository for anything technical I come across.  As a programmer, this will generally involve discussions surrounding code, but I'll use it as a store for anything to do with computers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8111117761365139552-3537375173023901231?l=salmontech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://salmontech.blogspot.com/feeds/3537375173023901231/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://salmontech.blogspot.com/2009/05/intro.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3537375173023901231'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8111117761365139552/posts/default/3537375173023901231'/><link rel='alternate' type='text/html' href='http://salmontech.blogspot.com/2009/05/intro.html' title='Intro'/><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='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
