Silverlight Alpha 1.1 TextBox

I managed to extend the SilverLightControls samples that are part of the SDK to make a TextBox.

At the moment it's pretty barebones. It has a moving cursor (or is it a caret, I never know), you click on it to focus, you can type text into it, you can get/set text with the Text property and that's about it.

It still needs:
- position the cursor
- resizing
- move the start of the text to the left if it becomes too long for the box
- selecting text
- enable Ctrl-V and Ctrl-C etc...
- enable text styles
- ...

How to make it work:
1. include the files in the SilverLightControls project in the SDK (freely downloadable from silverlight.net)
2. make sure the xaml files are 'embedded resources'
3. replace Page.xaml and Page.xaml.cs in the TestApp project (also in the SDK) with the ones below
4. rebuild TestApp and run
5. click on the textboxes to type
6. click on submit

The code for the controls

Replacement Page.xaml

Replacement Page.xaml.cs

Indirect package configuration in Sql Server Integration Services (SSIS)

Today I was struggling with package configurations in SSIS. I wanted to use a Sql Server store to configure an SSIS package, but I needed the configuration filter to be dynamic. A colleague pointed me in the right direction: use the indirect 'environment variable' technique in the Configuration Package manager.

In SSIS it is possible to store configuration values in an Xml file, environment variable or Sql Server table. Every time your package is executed, the values are loaded first (e.g. into your user-variables). With the SqlServer store, it is also possible to use the same table in a database to store configuration data for more than one package by using a Configuration Filter to select the right records. It's a bit counter-intuitive in the UI for creating package configurations though, so I thought I'd post a short howto.

1. Create a (direct) Sql Server package configuration from the SSIS > Package Configurations... menu.
2. 'Add' a configuration, and select Sql Server.
3. Select a database and create a table with the 'New' button.
4. Fill in a key for the Configuration Filter value (it doesn't matter what).
5. Now click 'Next' and select the variables you want to store in the configuration. (Note: notice how you can click the '+' sign in front of a user variable to deselect stuff that you don't need. In most cases you just need the value of the variable and not wether it was changed or not...).
6. Finish and you have a new configuration. Yay!

And now for the neat trick: create another configuration.
7. Choose Sql Server this time as well, but select the 'Configuration location is stored in an environment variable' option.
8. Fill in a name for the environment variable and click Next till you finish.

On the over view screen you now have 2 package configurations. A (direct) Sql Server config and an indirect sql server config.

Next you need to create an environment variable with the right content to point SSIS to your configuration package. (Right-click on 'My Computer' > Properties > Advanced > Environment Variables). Now take a good look at the package configurations list in the screen you had open before. In the entry for the (direct) SqlServer config, there is a column 'Configuration String'. This is the value you need to use for your environment variable. It is something like "SSIS_CONNECTION_MANAGER_NAME";"TABLE_NAME";"CONFIGURATION_FILTER".

By changing the CONFIGURATION_FILTER part of the environment variable's value, you can now point different packages (or different instances of the same package) to different configuration values.

The obvious next step is to run DTexec.exe and change the value of the environment variable every time.

Why oh why do you need to create the direct one first, you may ask? Well, this way it will create the rows for you in the database for all the variables you select, and you can simply copy them with a new ConfigurationFilter value. If you create an indirect one from the start, you need to create the table and add the rows yourself. It helps to use the direct way until your set of variables is pretty stable, that way you benefit from the automatic adding of the variables to the table.

Thanks for your help, Robert!

Enable Intellisense for NAnt and Wix files in VS2005 Beta1

Edit: This still works for VS2005 Beta2

Since Beta 2 is still a month off or so, I think this could still be relevant :-)

This blog tells you how to enable intellisense for NAnt .build files in VS2003.
This blog does the same for Wix .wxs files.

Both should be slightly altered to work with VS2005 beta1.

1) copy the schema files (.xsd) to the following folder: C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas

2) the registry key with which Wix (.wxs) and NAnt (.build) files can be registered as being xml is now:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Editors\{412B8852-4F21-413B-9B47-0C9751D3EBFB}\Extensions]"wxs"=dword:00000029
(replace the "wxs" by "build" for NAnt)
Note the subtle difference: dword value is 0x29 and not 0x28, which is ".htm" in vs2005b1, and the guid is different.

 

Reader-annotated edition of Neal Stephenson's "Command Line"

For those of you who don't read BoingBoing.net:
'In the beginning was the command-line' is a really good essay that touches upon the different cultures that OS'es have become. We all feel like we belong to some sort of tribe, but ours isn't called 'The Comanches' or 'The BlackFoot', but instead it's called .NET, java, Mac, Windows, Linux, GNU, ...

Read it online (via BoingBoing.net)

With Neal Stephenson's permission, this guy has annotated In the Beginning was the Command line and posted it online for everyone to see. I think this is a great example of how works can evolve and be improved upon. Unfortunately, In the Command Line has not been 'set free', but it's great that the author was able and willing to give permission for this development.

http://home.earthlink.net/~android606/commandline/index.html

Another interesting read by Neal Stephenson is 'Mother earth, mother board', about global communication backbones in the internet-age. You can read it online here: http://www.wired.com/wired/archive/4.12/ffglass.html

Virtual PC - 'NTLDR is missing' error

I was playing around with a VPC image for windows 2003 server. I created a 'blank' image and wanted to copy this, do I wouldn't have to go through the install each time I wanted to try out some new server stuff. I copied both the config file (.vmc) and the hard disk file (.vhd) for the vpc to another location and tried to re-start this new copy. Instead of the usual bootscreen I was confronted by a "NTLDR is missing. Press any key to restart..." message. I almost freaked and switched to using VMWare ;-)

The solution to this error is simple: instead of copying both files, just copy the hard disk file (.vhd) and create a new virtual pc configuration on top of this copied hard disk. The cause is probably some name or path settings in the vmc file that ar no longer in synch with its location. Creating a new vpc config is as easy as starting up the vpc console, clicking 'New' and following the wizard. (this even works after you get the error, there's nothing wrong with the hard disk file)

EDIT: turns out I was wrong. The VPC tried to boot from a USB stick I had left in one of the slots and didn't find a boot sector. Removing the USB stick removed the problem

Creating custom MSBuild tasks

Let's pick up where we left off.

If you go to the MSBuild wiki, you'll see that the topic  "How do I write a task?" is still blank. There is an MSDN article (in a 3 part series) that explains this, so I'll start from another perspective: I have some existing NAnt tasks and I want to use these in MSBuild.

Let's start with a simple one: Version (actually, it's a nantcontrib task, but that's the same, right?). In NAnt this task reads a version number from a file, increments it and uses it as a NAnt property.

Change the using statements

using NAnt.Core;
using NAnt.Core.Attributes;
using NAnt.Core.Util;

To their MSBuild equivalents:

using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;

Also, don't forget to set the namespace to something more appropriate.

Next, you should rename the task not to include the 'Task' suffix. In NAnt, the taskname you use in the buildfile is set with a custom attribute on the class [TaskName("name")], but MSBuild uses the classname. The good way to do this imo, is to leave off the 'Task' suffix, as this is the way the standard MSBuild tasks are named.

You will see something like the above with the public properties exposed by the task. In both NAnt and MSBuild, you can set/get these in xml. NAnt uses the technique of marking these properties wit the [TaskAttribute("name")] custom attribute, and MSBuild just uses the correct name of the property. So remove the attributes on the properties.

On some properties, in the NAnt version you will see the attribute [StringValidator(AllowEmpty=false)]. Replace this with the MSBuild [Required] attribute.

NAnt also contains a package called "StringUtils". Unless you want to re-use this, you're going to have to remove any references to this package, e.g.

StringUtils.ConvertEmptyToNull(value)

becomes

(string.IsNullOrEmpty(value)) ? null : value;

Also, the BuildException class is NAnt-specific. Replace these with generic Exceptions for the time being.

Next we come to the body of the implementation. Replace the NAnt ExecuteTask() method with its MSBuild Execute() equivalent. The first difference you'll notice is that the MSBuild version returns a boolean value, true if the task succeeded, so you'll need a mechanism (combined with try/catch) that determines the outcome.

Replace the logging mechanism with the MSBuild Log class:

Log(Level.Info, "Build number '{0}'.", buildNumber);

becomes

Log.LogMessage(BuildEventImportance.Low, "Build number '{0}'.", _buildNumber);

The rest of the implementation is the same, the compiler will help you with any NAnt-specific things (mostly BuildExceptions).

When you look at the code that comes with this post, you'll see that I added a method called "WriteVersionInfoFile" and that this is executed if the corresponding property is set to true in the buildfile.  This is used to create a VersionInfo.cs file that you can use in your solution to represent the version information for the assemblies. If you want all assemblies in a solution to have the same version number, you need to remove all AssemblyVersion attributes from the AssemblyInfo.cs files, and put this information in a solution file called "VersionInfo.cs". You can then add this file as a link to all projects in the solution (not as file, because then it is copied) and it will be used to set the version number for the assemblies.

A quick recap:

1. replace the "using" statements
2. remove the NAnt [TaskXXX] attributes and name the class and its properties correctly
3. replace the NAnt [StringValidator(XXX)] attributes with MSBuild or other equivalents
4. solve the StringUtils issue (either remove it or import it)
5. remove all references to BuildException
6. replace the logging mechanism

You can find the source here.

You can find the original 'VersionTask.cs' file in the nantcontrib source redistributable. I used the one from v0.84, but the 0.85RC1 version is the same.

Now for some licensing issues. I don't know if the above was entirely legal. I haven't removed the header stating that this class is 'free software under the GPL', but I've changed the name and the NAnt (c) statement. If this is in some way wrong, let me know.

[Edit] I forgot to mention how to start using this task. See the previous post on MSBuild for instructions on how to make this task available in MSBuild buildfiles. An example of the task in action is below:

<Version
   BuildType="increment"
   RevisionType="increment"
   Path="$(BuildNumberFile)"
   WriteVersionInfo="true"
   VersionInfoPath="$(VersionInfoFile)">
      <Output TaskParameter="BuildNumber" PropertyName="BuildNumber"/>
</Version>

Custom tool to generate code from XSD in VS2005 beta 1

Chris Sells posted a VS.NET (2002 & 2003) custom add-in to generate code (C#, VB and J#) from xsd quite some time ago. I stumbled upon it while looking for a way to do this in VS2005B1.

With minor changes, the add-in works in VS2005B1 as well. The only thing that stumped me for a while there is that in VS2005B1 the generated code is created as 'dependent' upon the xsd, and is thus hidden until you enable 'Show all files' on the project and you click on the little '+' sign next to your xsd. I can't seem to remember if this happens in previous versions of VS as well.

You can find the changed file here.

Creating GUIDs in VS 2005 B1

In VS.NET 2003 there is an external tool called 'GuidGen' to generate GUIDs. I can't seem to find this in VS 2005 so I made my own:

class Program
{
    public const string ARG_BYTES = "/b";
    public const string ARG_CSHARP = "/cs";
    public const string ARG_HELP = "/?";

    static void Main(string[] args)
    {
        StringBuilder builder = new StringBuilder();

        if (args.Length > 0)
        {
            switch (args[0])
            {
                case ARG_BYTES:
                    foreach (byte b in Guid.NewGuid().ToByteArray())
                    {
                        builder.Append(b.ToString("X2"));
                        builder.Append(" ");
                    }
                    break;
                case ARG_CSHARP:
                    builder.Append("new byte [] { ");
                    foreach (byte b in Guid.NewGuid().ToByteArray())
                    {
                        builder.Append("0x");
                        builder.Append(b.ToString("X2"));
                        builder.Append(", ");
                    }
                    builder.Remove(builder.Length - 2, 2);
                    builder.Append(" }");
                    break;
                case ARG_HELP:
                default:
                    builder.Append(string.Format("Usage: no arguments for a hexString representation, {0} for a byteArray representation, {1} for a C# byte array, {2} for this help message", ARG_BYTES, ARG_CSHARP, ARG_HELP));
                    break;
            }
           
        }
        else
        {
            builder.Append(Guid.NewGuid().ToString());
        }

        Console.Write(builder.ToString());
    }
}

 

At the command line type:

"GuidGen" for output like "ab04c0a1-ebb7-4996-914f-2a16ca9212f4"

"GuidGen /b" for output like: "31 34 37 18 5F 5B 2A 45 BC 8C 32 06 37 BF E9 B6"

"GuidGen /cs" for output like "new byte [] { 0x38, 0x39, 0xC0, 0xBD, 0xCE, 0xD4, 0xEC, 0x41, 0x8C, 0x90, 0x7C, 0x96, 0x37, 0x35, 0x83, 0x1C }"

Using the Microsoft SDC MSbuild tasks

Microsoft Research UK has released a number of 'extra' tasks for MSBuild on gotdotnet. You can find the workspace here. These tasks include a number of common things, like file management, source control etc... You can find a complete list of tasks at Jamie Cansdale's NunitAddin weblog here.

The mechanism for using custom tasks in MSBuild is with an <Import/> statement in your build file.

<Import Project="C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\Microsoft.Sdc.Tasks"/>

After that, you can use the tasks in your build file and msbuild will recognize them.

Of course, you still need to create the '.tasks' file that points the msbuild framework to the assembly that contains the task. This mechanism is widely used by the msbuild framework and in itself, its just a build file that uses the <UsingTask> task :-). It looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="
http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask AssemblyName="Microsoft.Sdc.Tasks, Version=2.0.5000.0, Culture=neutral, PublicKeyToken=e24a7ed7109b7e39" TaskName="Microsoft.Sdc.Tasks.ActiveDirectory.Group.AddUser" />
  <UsingTask AssemblyName="Microsoft.Sdc.Tasks, Version=2.0.5000.0, Culture=neutral, PublicKeyToken=e24a7ed7109b7e39" TaskName="Microsoft.Sdc.Tasks.ActiveDirectory.Group.Create" />
  <UsingTask AssemblyName="Microsoft.Sdc.Tasks, Version=2.0.5000.0, Culture=neutral, PublicKeyToken=e24a7ed7109b7e39" TaskName="Microsoft.Sdc.Tasks.ActiveDirectory.User.Create" />
...
</Project>

Next, you put this file and the assembly in the .NET framework folder (c:\windows\microsoft.net\framework\v2.0.40607).

I was getting errors running the SDC tasks because they seemed to overlap tasks already present in the basic MSBuild framework (I don't know if this was related to my desktop install or something else). Just renaming the '.tasks' file that came with the SDC tasks to '.tasks2' and updating my import statement above made the errors go away. (spooky :))

By doing these three simple things, you can start using custom tasks in your build files:
1. create a '.tasks' file that lists the custom tasks in an assembly
2. copy the '.tasks' file and the assembly somewhere msbuild will find them (the framework dir is the easiest)
3. use an <import> statement to reference the tasks in your build file

How to use the SDC tasks:
When you extract the zipfile from the gotdotnet workspace, you should look in the following folder:
<zipfile>\Microsoft.Sdc.Tasks\MainTempGDN\Framework2.0

In this folder, you will find another zipfile, called 'GDN2.0.041008.124.zip'. Extract this zipfile and look in the following folder:
<new zipfile>\Microsoft.Sdc.Tasks\MainTempGDN\Install

This folder contains everything you need to get started (apart from the docs :-)). Copy everything in this folder to your .NET framework folder (the v2.0.40607 one). You might experience the same 'overlap' problem I explained above, but that can be solved easy :-).

You can find a sample build file that uses some of the SDC tasks (mostly file & folder mgmt) here.

Next time, I'll talk about how to create a custom task yourself, and how to port a Nant or NantContrib task to MSBuild. I needed it because I couldn't get the source control tasks in the SDC build to work, so I ported the Nant VSS tasks.

CruiseControl.NET and MSBuild

Hi all,

This is my first post to this blog, and I wanted to make it a more memorable one than 'this is a test' ;-)

This blog is (among other more worldly things I hope) going to be about automated builds. I'm currently working on a project that is in a proof-of-concept stage and is using Visual Studio 2005 Beta 1 and, by extension, the version of MSBuild that comes with it (v2.0.40607.16). In itself, that's not that unusual, but we also started out with the idea of automating builds and incorporating a number of good software practices or concepts in the build process (unit testing, static analysis, outputting reports to developers etc...).

If you start looking around the web for an automated build solution for .NET that can also function apart from Visual Studio, you'll probably end up with a combination of NAnt on the one side and CruiseControl.NET, Hippo.NET or Draco.NET on the other side. NAnt is the answer to scripting the real work behind your build process, and the other tools provide you with (a.o.) a way to schedule those builds (or execute on-demand builds) and a nice overview of past and current build results and reports.

What you don't get is a way to combine one of these tools with MSBuild. Of course, you can do this with NAnt by using the <exec> task to start msbuild.exe, but I wanted to cut out the middle man. Note: I do NOT want to start a religious war here and i don't consider MSBuild to be better than NAnt (or vice versa). Let's just say I wanted to make it more challenging by veering away from the path most travelled :-).

So here's a short overview and a sample of my experiences with running CruiseControl.NET (ccnet for short) with MSBuild instead of NAnt.

First of all, ccnet uses an xml configuration file to drive the build process: ccnet.config. This file is included in every 'server' folder in your ccnet setup. Next, it has a mechanism called 'builders' that delegate the actual build process to a more specialized tool. The <build> node in the ccnet.config xml file will be used to drive the builder.

Out of the box, a builder for NAnt (if you download the source, look for a file called NAntBuilder.cs) is included. When you look at the code, you'll see it's fairly easy to replace the arguments needed to run nant.exe with those needed to run msbuild.exe and hey-presto! - MSBuilder.cs is born.

The first thing you'll notice in the bowels of ccnet is that it uses a component called Exortech.Reflector to map builder properties onto xml. This means that you can decorate .NET properties with attributes that declare which xml nodes are going to be used to fill the properties with data.

This code:
[ReflectorProperty("buildArgs", Required = false)]
  public string BuildArgs;

Will be filled in by the <buildargs> node in the following xml:
    <build type="msbuild">
      <executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\MSBuild.exe</executable>
      <baseDirectory>d:\temp\</baseDirectory>
      <buildArgs>@mybuild.response</buildArgs>
      <buildFile>mybuild.proj</buildFile>
      <targetList>
        <target>Build</target>
      </targetList>
      <buildTimeoutSeconds>300</buildTimeoutSeconds>
    </build>

What you basically have to do is figure out what information you need to pass onto the msbuild executable, translate this into appropriate xml, and provide properties in the 'builder' that read the xml.

Download the MSBuilder.cs file here.

The way you get ccnet to use your custom builder is either by adding it to the ccnet source code and rebuilding it, or by building it into a plugin. You can create a plugin as follows:
- create a VS.NET 2003(!) library project
- add your custom builder to the project
- add the appropriate references (exortech reflector and a number of 'core' ccnet dlls)
- name the output of the project 'ccnet.<insert name here>.plugin.dll
- place the plugin dll in the 'server' folder of your ccnet project

Next, you can replace the standard <build> node in the ccnet.config file with the above 'msbuild' <build> node, write a small msbuild script ('.proj' file) and you're off.

In short:
1. build the custom 'builder' into a plugin dll
2. put the plugin dll in the ccnet server folder
3. put the custom xml in ccnet.config
4. point the custom xml to an appropriate msbuild script
5. force the ccnet project to build through its website (or schedule it) and watch the magic happen :-)

Coming up next on this blog:
- using the Microsoft SDC MSBuild tasks to do lots of stuff (source control, file management, nunit, fxcop, ...)
- creating custom MSBuild tasks yourself (or stealing them from NAnt) (it's not really stealing as long as you re-release them under the (L)GPL, is it ?)
- Whatever you want to hear, as long as its about MSBuild and/or CCNET