This blog has moved, permanently, to http://software.safish.com.

Wednesday, November 17, 2010

Determining the target .NET Framework version of a .NET assembly

To determine which version of the .NET framework an assembly supports, you can use ILDASM.

Open up a visual studio command prompt, and type the following:

ildasm.exe C:\Yourdll.dll /metadata[=MDHEADER] /text /noil

You’ll get a large amount of indecipherable data, but right at the top, you’ll see something to the effect of

// Metadata section: 0x424a5342, version: 1.1, extra: 0, version len: 12, version: v4.0.30319

where the highlighted piece gives you the supported version.

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”:

Mainfest

Useful!

Tuesday, November 16, 2010

Moq BadImageFormatException with NUnit

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.

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.

The exact error I encountered was:

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.

Friday, November 12, 2010

Rebuilding SQL Server Indexes

I've always used cursors to rebuild indexes in SQL Server, like so:

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

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

sp_MSforeachtable @command1="print '?' DBCC DBREINDEX ('?')"

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.

Wednesday, October 13, 2010

Playing with the TPL

I did a quick investigation on the Task Parallel Library (TPL) 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.  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. 

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.  This was done in three ways:

  1. sequentially making the web request in a for loop
  2. using a thread pool to make the web requests
  3. using Parallel.Invoke to make the web requests with the TPL library

Well, option 1 was obviously very simple to implement, but it was SLOW.  1,000 requests took in the region of 20 seconds to run.

Option 2 was the most difficult to implement, but obviously far more efficient.  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.  Anyway, it resulted in 1,000 requests being done in approximately 11 seconds.

Option 3 was, to my pleasant surprise, a piece of cake to implement.  Create an Action list, and call Parallel.Invoke – that was it.  Incredibly, this took approximately 6.5 seconds to run on my 4-core machine.  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.


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 < testCount; i++)
            {
                SendWebRequest();
            }
            sw.Stop();
            Console.WriteLine("Single requests: {0} seconds", sw.Elapsed.TotalSeconds);

        }

        static void ParallelRequests()
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            List actions = new List();
            for (int i = 0; i < 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 doneEvents = new List();
            for (int i = 0; i < 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 > 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();
            }


        }
    }
}

Tuesday, September 21, 2010

Prettify

Following stackoverflow’s example, I’ve started using prettify for syntax highlighting on this blog.  I’ve used the Google syntax highlighter 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 <pre> and <code> tags, and it just works.  It’s clever enough to work out the language.

Getting it working was really simple.  I downloaded the source, combined all the .js files into one using Google’s Closure Compiler, and update the .css file to the styles I like (stolen without shame from stackoverflow – I love that site).

To get the styles to apply to my blog, I also added an initialisation script to make the prettify call, and it works.  Hopefully this should save me some time in the future.

I found a really good article here that showed me how to set this all up.  I’ll update old blog posts at some stage, for now they’re going to appear without styling.

Wednesday, September 8, 2010

.NET – Detecting Modem COM Ports

We have a project at the moment where we’re using GSM modems attached to the local machine to send an SMS.  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.

There is a simple way to detect which COM ports are assigned to modems installed on your machine:

using System.Management;

ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_POTSModem");
foreach (ManagementObject mo in mos.Get())
{
    string s= mo["AttachedTo"].ToString();
}

Other properties available can be looked up here: http://msdn.microsoft.com/en-us/library/aa394360%28VS.85%29.aspx

Tuesday, August 31, 2010

Using the WiX Installer

I’ve been playing with the Wix Installer for the last few days, and I’m absolutely amazed by it.  It’s a real bastard to get into, but once you’re up and running it’s pretty incredible how much can be customised.  There is a LOT of documentation out there, but the most useful link I found was this tutorial – it really is worth your while to read the entire tutorial BEFORE trying to create your own installation project.

Instead of creating another tutorial, I thought I’d list the items that tripped me up.

Visual Studio 2010 Integration

I downloaded Wix 3.0 (64 bit), and after installation, it wasn’t available as a project within Visual Studio.  Download the beta version of 3.5 – it seems pretty stable and integrates with Visual Studio,.

No Wizard

No wizard!?  WTF!?  It turns out it’s XML-based – you end up doing a lot of the setup by hand.  Deal with it.

References in Visual Studio

You will probably require extensions so you can customise the UI, or perhaps ensure the user has a .NET Framework installed.  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.  You do not need to do this.  All you need to do is click “Add Reference” on the project, and select the extension from the list that appears.  For example, if you want to add the .NET Framework prerequisites, right-click References, and select WixNetFxExtension.  That is all you need to do.

Default UI

The default installation dialog really sucked, and it took me a while to work out that you need to specify a different UI type.  That’s what you get for not reading the above tutorial before creating your project.  You need to create a <UI> element, and specify the UIRef you want to use.

Dialog Sequence

Creating custom dialogs is pretty easy once you get the hang of it, but I struggled a little with navigation between dialogs.  Eventually I found the reference on the Wix site to a full list of Wix dialogs that you can navigate between at http://wix.sourceforge.net/manual-wix3/WixUI_dialogs.htm.

Using the IIS Extension (For deploying web sites)

This foxed me a little too.  Mostly, using the extensions just worked in Visual Studio, but the IIS extension doesn’t.  You need to add the namespace reference, something along the lines of:

<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">

You can then use the extension elements as follows:

<iis:WebSite Id='DefaultWebSite' Description='Default Web Site'>
       <iis:WebAddress Id='AllUnassigned' Port='80' />
     </iis:WebSite>

Thursday, August 26, 2010

Unit Testing and DateTime Comparisons

 

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.  Two DateTime constructs, despite being identical in terms of their values, often won’t assert as being equal and your unit test fails.  As such, you end up doing other sorts of tests, for example checking the individual values.

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:

public static class AssertHelper
    {
        /// 
        /// Asserts that two dates are equal by checking the year, month, day, 
        /// hour, minute, second and millisecond components.
        /// 
        /// The current date
        /// 
        public static void AreDatesEqual(DateTime expected, DateTime actual, DateTimePrecision precision)
        {
            if (precision >= DateTimePrecision.Year && expected.Year != actual.Year)
            {
                throw new NUnit.Framework.AssertionException("Year in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Month && expected.Month != actual.Month)
            {
                throw new NUnit.Framework.AssertionException("Month in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Day && expected.Day != actual.Day)
            {
                throw new NUnit.Framework.AssertionException("Day in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Hour && expected.Hour != actual.Hour)
            {
                throw new NUnit.Framework.AssertionException("Hour in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Minute && expected.Minute != actual.Minute)
            {
                throw new NUnit.Framework.AssertionException("Minute in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Second && expected.Second != actual.Second)
            {
                throw new NUnit.Framework.AssertionException("Second in dates do not match as expected.");
            }
            if (precision >= DateTimePrecision.Millisecond && 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
    }
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.

Tuesday, August 3, 2010

ILMerge

I Used ILMerge today for the first time, and it's great. Aspnet_merge.exe 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.

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:

ILMerge.exe /t:winexe /out:Output.exe /ndebug Program.exe Lib1.dll Lib2.dll Lib3.dll

Wednesday, July 28, 2010

Running MSBuild using Powershell Script

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.
 
$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)

Friday, May 14, 2010

Debugging log4net

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.
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:

Add the following in your App.config/Web.config, under the configuration section:
 
 <system.diagnostics>
    <trace autoflush="true">
      <listeners>
        <add
          name="textWriterTraceListener"
          type="System.Diagnostics.TextWriterTraceListener"
          initializeData="C:\temp\log4net.txt" />
      </listeners>
    </trace>
  </system.diagnostics> 
Then, add the following key to the appSettings section in your web.config:
  <add key="log4net.Internal.Debug" value="true"/>

Thursday, April 22, 2010

NCover and NUnit AppDomainUnloadedException

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 NCover 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.

Anyway, getting ncover wasn't a big deal, I added the following section to the ccnet.config file for our project:
  
<exec>
 <executable>C:\Program Files\NCover\NCover.Console.exe</executable>
 <baseDirectory>C:\Builds\myproject\Source</baseDirectory>
 <buildArgs>"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</buildArgs>
 <buildTimeoutSeconds>360</buildTimeoutSeconds>
</exec>

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:

System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain.


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.

Tuesday, March 30, 2010

Online Favicon Creation

Need a favicon for your site? Look no further than http://www.favicon.cc/.

Nice!

Wednesday, March 10, 2010

FFMPeg and the XBox 360

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.

I've been using Handbrake 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.

I've been trying for ages to convert the files to .mp4 with ffmpeg, 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:
ffmpeg.exe -i input.mpg -sameq -ac 2 -aspect 16:9 output.mp4

The -sameq tag forces the quality to be the same as the source. The -aspect 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 -ac 2 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.

Friday, February 26, 2010

NServiceBus error "Parameter name: meth"

It's been a while since I used NServiceBus and I got this annoyingly cryptic error message this morning:

Value cannot be null.
Parameter name: meth


I finally found this post 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.

Friday, February 19, 2010

HTTP Pre-Authentication

Rick Strahl posted this excellent article 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.

Friday, January 29, 2010

SQL Server: Updating varbinary fields

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.

update [schema].[table] set Column = (
 SELECT * 
        FROM OPENROWSET(BULK N'E:\Share\Temp\myfile.jpg', SINGLE_BLOB) AS BinaryFile
)

Friday, January 22, 2010

Page LifeCycle Events Listed

Joe Stagner posted this useful list of the entire ASP.NET page lifecycle events as they occur, in order.

Now if only you could get people to actually use these things correctly....

Friday, January 15, 2010

Locate File in Solution Explorer - Visual Studio Macro

A colleague found this blog post by Brian Schmitt, which is one of the most useful little tips I've seen in ages.

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.

To get this working:
  1. Switch of auto tracking: Tools, Options, Projects and Solutions, turn off Track Active Items
  2. Open the Macro Explorer: Tools, Macros, Macro Explorer
  3. Under MyMacros, right-click Module1 (you can rename this if you like) and click New Macro
  4. Replace the code of the Macro with the following:
        Public Sub LocateFileInSolutionExplorer()
            DTE.ExecuteCommand("View.TrackActivityinSolutionExplorer")
            DTE.ExecuteCommand("View.TrackActivityinSolutionExplorer")
            DTE.ExecuteCommand("View.SolutionExplorer")
        End Sub
    
  5. Save and close the Macro Explorer
  6. Go to Tools, Options, Environment Keyboard, and in the "Show commands containing" type in the macro name until it appears in the list below
  7. 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.
  8. Watch productivity soar.