April 2006 - Posts

For those of you who have been living on Mars (no, that's not the abbreviation of Multiple Active Result Sets in ADO.NET 2.0): Monad aka MSH has been renamed to Windows PowerShell and last week the RC1 release of the product became available on http://www.microsoft.com/downloads/details.aspx?FamilyId=2B0BBFCD-0797-4083-A817-5E6A054A85C9&displaylang=en. The documentation pack for RC1 is also available via http://www.microsoft.com/downloads/details.aspx?familyid=B4720B00-9A66-430F-BD56-EC48BFCA154F&displaylang=en. Have fun!

My only annoyance with this release is the more difficult name to type in order to launch the shell: msh.exe became powershell.exe which requires a bit more typing (also compared to cmd.exe). Maybe psh.exe would be a better choice? Notice the logo still has the letters MSH in it.

I'll post some stuff on the Windows PowerShell later on my blog.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

During the preparation of the MSDN Security Evenings (first one is tonight in Ostend) I ran into this nice piece of security-related software called "Microsoft Anti-Cross Site Scripting Library V1.0" which is a free download at Microsoft Download (download the library here). Basically the library comes as a .NET assembly with a couple of functions to do safe encoding etc to protect agaist XSS attacks. A couple of examples:

using Microsoft.Security.Application {

  • AntiXSSLibrary.UrlEncode(...);
  • AntiXSSLibrary.HtmlEncode(...);

}

That's basically it. The key takeaway however is that this library is a safer variant of Server.HtmlEncode() which only encodes <, >, & and ".

A version 1.5 has already been announced, which will have additional functionality on top of the existing base functionality set.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

A couple of great downloads have become available recently. Time for some links:

  • SQL Server 2005 Books Online (April 2006) contains new information on SQL Server 2005 up to the SP1 level of the product. There are links for documentation on Express too.
  • Internet Explorer 7 Beta 2 is now available too, also for Windows Server 2003 users (finally!). I recommend you to try this new version (on a non-production machine) in order to test your websites' compatibility with the new improved browser and of course to have more fun browsing the internet. Check out the release notes for known issues with this beta.
Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

This evening a friend of mine pinged me on MSN about a problem, with the scary nickname "XYZ starting to hate the microsoft office suite". Apparently, Word (and other Office applications) stopped to respond when he tried to open or save a document through the File/Open or File/Save dialog, navigating through the folder hierarchy.

So I suggested to open a remote assistance session to take a look at it. Some KB articles later without a solution I decided to download RegMon from SysInternals on his pc (download here), entered a filter for winword.exe and started to capture events. Jumped back to Word to do File, Open and clicked on some folder causing Word to hang and (after > 9000 registry events) RegMon to stop capturing events. And there it was, the latest registry read operation telling something about verclsid.exe. What's next? The KB at http://support.microsoft.com happened to be the solution, pointing me to KB article 918165, released to the web one day ago.

When I saw this KB article, I knew it was the latest Microsoft Update patch cycle that caused the problem, more specifically the MS06-015 patch that conflicts with HP Share-to-Web which was installed on the machine. Some quotes from the KB article:

Microsoft Office applications stop responding when you try to save or to open Office files in the "My Documents" folder.

There have been reported issues where software that was previously distributed by Hewlett Packard (HP) causes the Verclsid.exe program to stop responding. The specific component that causes problems is the Share-to-Web namespace daemon (Hpgs2wnd.exe). This software is no longer distributed by HP ...

Security update 908531 includes an "allow list." The Verclsid.exe program does not scan any file that has an extension that appears in this list. ... To resolve this problem, you can add the HP shell extension to the list. To you do this, you must follow these steps to modify the registry ...

So, check out the KB article for instructions on how to resolve this issue.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Superb news hitting the road: the Visual Studio 2005 Express Tools (including Visual Basic 2005 Express, Visual C# 2005 Express, Visual C++ 2005 Express, Visual J# 2005 Express and Visual Web Developer Express) will remain available for free. Earlier Microsoft announced that the tools would be free to the first year, but due to the big success plans have changed. Read the full story on Dan's blog.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Another of those "start downloading immediately" kind-a-posts. About 5.5 months after the initial release of SQL Server 2005, its first Service Pack has arrived including database mirroring support and a bunch of other features which didn't make it in the RTM release. For an extensive list of those, see http://support.microsoft.com/default.aspx/kb/916940. For more information about the bugfixes included in SP1, take a look at http://support.microsoft.com/kb/913090/.

So, start downloading the SP1 binaries now. An updated version of Books Online will be available soon, for now you can stick with either the December 2005 version or the March 2006 BOL CTP.

SQL Server 2005 Express users will find a complete new release over here. Have fun!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Introduction

I guess most of my blog readers are familiar with the new build system in .NET 2.0 and Visual Studio 2005. In the past, project files were only consumable by Visual Studio .NET. Today, project files (which are XML-based) are VS-independent and can be used to build the project using MSBuild at the command line. To do this, you only need to have the .NET Framework 2.0 SDK on your machine. A typical MSBuild session looks as follows:

C:\temp\ReflectionDemo\ReflectionDemo>dir
 Volume in drive C is Windows XP Professional MCE
 Volume Serial Number is 3003-9177

 Directory of C:\temp\ReflectionDemo\ReflectionDemo

04/11/2006  09:03 PM    <DIR>          .
04/11/2006  09:03 PM    <DIR>          ..
04/11/2006  09:01 PM    <DIR>          bin
04/11/2006  08:55 PM    <DIR>          obj
04/11/2006  09:02 PM               600 Program.cs
04/11/2006  08:52 PM    <DIR>          Properties
04/11/2006  09:01 PM             2,112 ReflectionDemo.csproj
04/11/2006  09:03 PM               168 ReflectionDemo.csproj.user
04/11/2006  08:53 PM               257 ReflectionDemo.csproj.vspscc
               4 File(s)          3,137 bytes
               5 Dir(s)  28,914,020,352 bytes free

C:\temp\ReflectionDemo\ReflectionDemo>msbuild
Microsoft (R) Build Engine Version 2.0.50727.42
[Microsoft .NET Framework, Version 2.0.50727.42]
Copyright (C) Microsoft Corporation 2005. All rights reserved.

Build started 4/13/2006 12:06:58 AM.
__________________________________________________
Project "C:\temp\ReflectionDemo\ReflectionDemo\ReflectionDemo.csproj" (default targets):

Target CoreCompile:
  Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
Target CopyFilesToOutputDirectory:
    ReflectionDemo -> C:\temp\ReflectionDemo\ReflectionDemo\bin\Debug\Reflection
Demo.exe

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.06

Notice that the output is colored in reality, indicating the success or failure of something (among other status indicator colors and highlighting colors), leveraging the richness of the new System.Console class in .NET 2.0.

Now, let's take a look at the project file for this:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.50727</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{0C53AE2F-B541-4A05-9B75-A4A0CB0B0156}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>ReflectionDemo</RootNamespace>
    <AssemblyName>ReflectionDemo</AssemblyName>
    <SccProjectName>SAK</SccProjectName>
    <SccLocalPath>SAK</SccLocalPath>
    <SccAuxPath>SAK</SccAuxPath>
    <SccProvider>SAK</SccProvider>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
  -->
</Project>

When executing MSBuild, the system looks for a project file (if not specified) and uses that to perform the build. The way it works is by crawling through a tree of tasks that have to be performed, based on the specified target (or the default one). The default targets can be found in %windir%\Microsoft.NET\Framework\v2.0.50727 and are XML-files with the extension .targets. An example is Microsoft.Common.targets, a 3757 lines file with target definitions. Check it out to get a good idea of what targets are and how those work.

 

Building custom tasks

Last week I had to write a custom task to run as part of daily builds in Team Foundation Server. TFS also uses MSBuild files to drive automatic builds, so my job came down to writing a new MSBuild task to perform the work. In my case, I needed to create a SCP copy task to copy binaries from the build server to a *nix based machine running Mono (actually I'm not promoting Mono at all; this was just the project case I was involved in and I needed to show the power and richness of MSBuild - in this case by writing a task to perform a file copy over SSH/SCP).

Luckily I found an SSH/SCP client implementation for C# on Code Project, called SharpSSH. Download it and build it if you're interested in this.

Now, how to create a custom MSBuild task. An overview:

  1. Create a new class library project (in my case in C#, but VB or other languages will do as well).
  2. Add any references you might need (in my case I needed references to Tamir.sharpSsh which contains the SCP implementation I want to use).
  3. Add references to Microsoft.Build.Framework and Microsoft.Build.Utilities.
  4. Implement Microsoft.Build.Framework.ITask either by implementing the interface directly or by inheriting from Microsoft.Build.Utilities.Task. Sample code can be found below.
  5. Add properties to the class which will be used as parameters to the task.
  6. Write the core code in the method Execute().

Sample code (for SCP file copy):

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

public class ScpUpload : Task
{
    private string user;

    [Required]
    public string User
    {
        get { return user; }
        set { user = value; }
    }

    private string password;

    [Required]
    public string Password
    {
        get { return password; }
        set { password = value; }
    }

    private string host;

    [Required]
    public string Host
    {
        get { return host; }
        set { host = value; }
    }

    private ITaskItem[] sourceFiles;

    [Required]
    public ITaskItem[] SourceFiles
    {
        get { return sourceFiles;}
        set { sourceFiles = value;}
    }
 
    private string destinationFolder;

    [Required]
    public string DestinationFolder
    {
        get { return destinationFolder;}
        set { destinationFolder = value;}
    }

    public override bool Execute()
    {
        Tamir.SharpSsh.Scp scp = new Tamir.SharpSsh.Scp();

        foreach (ITaskItem item in sourceFiles)
        {
            if (item.ItemSpec.Length > 0)
            {
                string source = item.ItemSpec;
                Log.LogMessage(item.ItemSpec);
                string target = destinationFolder + "/" + System.IO.Path.GetFileName(item.ItemSpec);

                try
                {
                    scp.To(source, host, target, user, password);
                }
                catch (Exception ex)
                {
                    Log.LogError(ex.Message);
                }
            }
        }

        return !Log.HasLoggedErrors;
    }
}

Actually I've stripped down my code because I have slightly more complex - but for this post irrelevant - code. Notice that required parameters are marked with the attribute Required. Now compile the code which will result in a .dll assembly file.

 

Using custom tasks

Now, how to use our new task? Go to a csproj or vbproj or ... project file and modify it as follows:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <UsingTask TaskName="ScpUpload" AssemblyFile="C:\temp\DemoTask\DemoTask\bin\Debug\scpupload.dll"/>

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.50727</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{0C53AE2F-B541-4A05-9B75-A4A0CB0B0156}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>ReflectionDemo</RootNamespace>
    <AssemblyName>ReflectionDemo</AssemblyName>
    <SccProjectName>SAK</SccProjectName>
    <SccLocalPath>SAK</SccLocalPath>
    <SccAuxPath>SAK</SccAuxPath>
    <SccProvider>SAK</SccProvider>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  -->
  <Target Name="AfterBuild">
<ScpUpload Host="somemachine" User="someuser" Password="somepwd" DestinationFolder="www" SourceFiles="bin\Debug\ReflectionDemo.exe" />

  </Target>
</Project>

You have to do two things:

  1. Add a <UsingTask> reference to the project file (you can do this in .targets files as well. The tag has two parameters: a TaskName and an AssemblyFile or AssemblyName attribute. The former one defines a friendly name (in this case ScpUpload), the latter one points to the assembly (if you're using AssemblyFile, specify a path; if you're using AssemblyName, use an assembly name, e.g. to point to a strongly-named assembly in the GAC).

    <UsingTask TaskName="ScpUpload" AssemblyFile="C:\temp\DemoTask\DemoTask\bin\Debug\scpupload.dll"/>
  2. Use the task somewhere in a target. In this case, I'm just using AfterBuild and specifying the to-be-copied file manually (you could use build variables as well using $(...) syntax):

    <ScpUpload Host="somemachine" User="someuser" Password="somepwd" DestinationFolder="www" SourceFiles="bin\Debug\ReflectionDemo.exe" />

    In here, you have to specify every [Required] parameter.

Now, when executing MSBuild on the project, the output will be copied to the server over SCP. Just a little demo to show how you can extend MSBuild with your own custom tasks. I'm not putting the sources online because it relies on 3rd party components (see SharpSSH) and because it hasn't been tested thoroughly. However, using the code mentioned in this post, you can create a similar MSBuild task yourself. Enjoy!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

I'm in the middle of preparing the MSDN Security Evening sessions over here in Belgium, which will be just fantastic (hope to see you there). Currently I'm messing around with buffer overruns, one of my favorite topics on the field of security. Instead of just doing the silly "call another function using strcpy stuff", I'm creating a slightly more complex attack that's really inserting malicious assembler code to the stack. A good resource to aid in this kind of attack creation is http://www.metasploit.com which has a lot of useful payloads to construct this kind of demos.

I'm not going to post any code over here, neither am I going to explain how to construct an attack. If you want to see it in action, come to one of my sessions and see how a faulty strcpy can open the door for an attacker to add a local administrator on the machine or to shutdown the machine using some malicious input. The good news is that the Visual C++ 2003 and 2005 compiler makes this kind of attack much harder to do thanks to the /GS flag.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Just upgraded my blog to Telligent's Community Server v2.0, which works like a charm. It's great to see the large number of new features available in this new release and the much smoother administration interface. For the blog entries you now have:

  • Support for attachments (I'm trying this right now by including a silly photograph of myself with this post).
  • Possibility to post videos (opens the door to webcasts).
  • Tabs to toggle between different "property pages" for the entry you're creating.
  • Cool dialogs instead of long series of postbacks.

I'm writing this post from IE7, which didn't work properly with Community Server v1.1 (actually the primary trigger to perform the upgrade for me). If you're managing a blogging site, I'd recommend CS 2.0 to everyone!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Today I ran across CodeKeep, an online repository with tons of code snippets. Actually I was reviewing my blog post view numbers + referrers and noticed that my Wake On Lan in C# was linked to on CodeKeep. Check it out over here. You can find a snippet of mine on how to use the StopWatch in .NET 2.0 over there as well.

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

More Posts Next page »