To quote or not to quote – that's the question

Since I’m using NAnt to build my solution I include all steps needed to get a build up and running. So recently I added the fantastic WSPBuilder to my lastest build file:

<target name="build.wsp" description="Packages the WSP file">
<exec program="${dir_buildtools}\wspbuilder\wspbuilder.exe">
<arg value="-BuildCAS false"/>
<arg value="-DeploymentTraget BIN" />
<arg value="-TraceLevel verbose"/>
</exec>
<move todir="${build.dir}" overwrite="true">
<fileset>
<include name="**.wsp"/>
</fileset>
</move>
</target>

But this didn’t work out as expected, for some strange reason the command line args added with the arg element where just ignored!

OK, let’s examine what is going on here. If you look closely, you’ll notice that the actuall command being executed looks like: wspbuider.exe "-BuildCAS false" "-DeploymentTraget BIN" "-TraceLevel verbose". But apparently wspbuilder doesn’t like the arguments enclosed in quotes, because the whole arg is being interpreted as just a single string. So parsing for -BuildCAS fails, because the actual string is longer (when using space for tokenizing!).

So what next? This does the trick:

<target name="build.wsp" description="Packages the WSP file">
<exec program="${dir_buildtools}\wspbuilder\wspbuilder.exe" commandline="-BuildCAS false -DeploymentTraget BIN" >
</exec>
<move todir="${build.dir}" overwrite="true">
<fileset>
<include name="**.wsp"/>
</fileset>
</move>
</target>

In this case I supply the complete commandline arguments

Parsing enumerations

Once in a while I need to convert an integer or text to some enum-value (usually when reading some settings from somewhere, where the actual value is limited int thus being represented by an enum …).

But I always keep forgetting how to do it … so now, here it is, once and for all:

// 1. option
RecipientTypeEnum rte = (RecipientTypeEnum) Enum.Parse(
typeof(RecipientTypeEnum),
1);
// 2. option
RecipientTypeEnum rte = (RecipientTypeEnum) Enum.Parse(
typeof(RecipientTypeEnum),
"To");

Both options will return a valid enum-value ๐Ÿ™‚

Integrated WSPBuilding

So after figuring, that the WSPBuilder is actually representing the good I fully embraced it.

To take it to the next level, I installed the Visual-Studio extensions (not only to increase the number of plugins, but this is a nice side-effect; [pluginCount++]). Unfortunately this wasn’t very cooperative to work with my german version of Visual Studio.

So after some frustration I came across an according issue and tried the proposed alternative WSPTools.VisualStudio.VSAddIn.dll – and what should I say – it actually works!

So now I’m actually waiting for this to be merged into the release of the WSPBuilder.

(happy WSPBuilding …)

Attaching a database the express way

Are you also stuck with that stupid limited express edition of SQL Server 2005, which has no GUI whatsoever?

Well, I already tried the hassle of installing the Management Studio of the full blown SEL Server once – and I don’t feel like doing that any time again. So there has to be a better way.

OK – so check out the SSEUtil and with just:

SSEUtil.exe -s .\SQLEXPRESS -attach Northwnd.mdf

we get our beloved Northwind Database in SQL Express!

Wow – this is slick!

UPDATE:

OK, the excitment settled pretty quick – seems like I cannot access that attached Database from anywhere. This makes attaching databases kinda useless.

Anyway, I figured another approach – and this time it’s for real. Try:

%ProgramFiles%\Microsoft SQL Server\90\Tools\Binn>SQLCMD.EXE -S.\sqlexpress -E -iattach.sql

where ‘attach.sql” contains the SQL to attache a database:

use master go exec sp_attach_db @dbname=’northwind’,@filename1=’C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data\northwnd.mdf’ go

Show them keys

If you’re a keyboard-shortcut-junkie just like me, you want to have all your currently assign keybindings memorized … but there’s a way to supply you some kind of cheat.

With this little macro you can list all currently active keybinding of visual studio:

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics
Public Module KeyboardShortcuts
Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane
Dim window As Window
Dim outputWindow As OutputWindow
Dim outputWindowPane As OutputWindowPane
window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
If show Then window.Visible = True
outputWindow = window.Object
Try
outputWindowPane = outputWindow.OutputWindowPanes.Item(Name)
Catch e As System.Exception
outputWindowPane = outputWindow.OutputWindowPanes.Add(Name)
End Try
outputWindowPane.Activate()
Return outputWindowPane
End Function
Sub ListCommands()
Dim outwin As OutputWindowPane = GetOutputWindowPane("List Commands", True)
outwin.Clear()
For Each cmd As Command In DTE.Commands
Dim bindings() As Object
bindings = cmd.Bindings
For Each binding As String In bindings
outwin.OutputString(cmd.Name.ToString() + vbTab + binding + vbCrLf)
Next
Next
End Sub
End Module

Logging with log4net in NUnit

There seems to be quite some confusion when logging with your favorite log4net logger while testing you code with NUnit (especially when using the NUnit GUI Runner).

Well, I just stumpled once again over some code where I not only wanted to look at my asserts, but also check the debug-logging. So added a log4net.config to my testing assembly and I also added the obligatory assembly configuration attribute to the testing assembly:

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]

But there was no logfile to be found ๐Ÿ™ I later figured, that the first logger is not being called in my testing assembly, but in my core assembly, which is the code under test. And because this assembly had no log4net config no logging repository was set up.

OK, so just added the config attribute to the core assembly, and off you go to the next round of testing. But still no logging … what the heck?!&%$ร‚ยง”

Taking a closer look at the NUnit 2.4.7 release notes reveals, that NUnit is not using log4net for it’s internal logging anymore, but rather intercepts all logging attempts (via reflection). These are than re-routed to the log tab in the GUI runner. And indeed – at least ERROR messages are being logged (actually, this was done all the time already). But what about my DEBUG-leve I setup in my log4net.config?

Time to do some more digging. The documentation for the configuration files shows how it’s done (just add a app.config to your testing project if you don’t have one already):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="NUnit">
<section name="TestCaseBuilder" type="System.Configuration.NameValueSectionHandler"/>
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>
<NUnit>
<TestRunner>
<add key="DefaultLogThreshold" value="Debug" />
</TestRunner>
</NUnit>
<appSettings>
<add key="log4net.Internal.Debug" value="false"/>
</appSettings>
</configuration>

This will instruct the interceptor of log4net to also watch out for Debug messages and add them to the log-tab. Just for the heck of it, I enabled the log4net internal logging in the app-settings (well actually I did turn it off, but I had it enabled in some point in time).