MSBuild Community Tasks Project releases version v1.0.0.29

Announcement

The MSBuild Community Tasks Project releases version v1.0.0.29. The following is a list of tasks.

Current Community Tasks

Task Description
AssemblyInfo Generates an AssemblyInfo file using the attributes given.
FtpUpload Uploads a file using File Transfer Protocol (FTP).
Mail Sends an email message.
Math.Add Add numbers.
Math.Divide Divide numbers.
Math.Multiple Multiple numbers.
Math.Subtract Subtract numbers.
NDoc Runs NDoc V1.3.1 to create documentation.
NUnit Runs tests using the NUnit V2.2 framework.
RegistryRead Reads a value from the Registry.
RegistryWrite Writes a value to the Registry.
SvnCheckout Checkout files from Subversion
SvnClient Subversion Client
SvnCommit Commit files to Subversion
SvnExport Export files from Subversion
SvnUpdate Update files from Subversion
SvnVersion Get Subversion revision number of a local copy
Unzip Unzip a file to a target directory.
Version Increments a four-part version number stored in a text file
XmlRead Reads a value from a XML document using a XPath.
XmlWrite Updates a XML document using a XPath.
Zip Create a zip file with the files specified.

Join Project

Please join the MSBuild Community Tasks Project and help contribute in building the tasks. 

http://msbuildtasks.tigris.org/

Get The Source

You can get a local copy of the repository for MSBuild Community Tasks via Subversion. The following command will do the trick:

svn checkout http://msbuildtasks.tigris.org/svn/msbuildtasks/trunk

Download The Latest

The latest binaries, source and installer for Windows can be found in this directory of the Tigris file-sharing area.


MSBuild Community Task Collaboration Project

I’d like to announce the MSBuild Community Task Collaboration Project. The project was started by me to form a directory of MSBuild Tasks for use in your build scripts. The project is also an open source collection of tasks. The project is broke into 2 web sites.

The first is http://msbuildtasks.com/ which is a community server install with forums and a directory of MSBuild tasks. The goal of msbuildtasks.com is to provide a common place to find tasks. Please help improve this directory by adding links to tasks that you know about.

The second site is an open source project hosted at http://msbuildtasks.tigris.org/. The goal of this site is to build a collection of tasks that is open source for the community. Please create an account on Tigris.org and join the project to help build out the tasks.

Thanks for contributing to the MSBuild community.

~ Paul


Generics at Runtime

Here is a little test code that demonstrates how to use Generics at runtime. The code has two tests. The first test shows how to create a Generic Class at runtime. The second shows how to call a Generic method. Keep in mind that when using generics at runtime, there will be a reflection performance hit.

using System;  
using System.Collections.ObjectModel;  
using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;  
using System.Reflection;  
using System.Diagnostics;  
  
namespace GenericTest  
{  
    [TestClass]  
    public class GenericTest  
    {  
        [TestMethod]  
        public void CreateGenericAtRuntime()  
        {  
            Stopwatch watch = Stopwatch.StartNew();  
            // define the generic class at runtime  
            Type genericType = typeof(Collection<>).MakeGenericType(typeof(DateTime));  
            // create an instance of the generic type  
            object instance = Activator.CreateInstance(genericType);  
            watch.Stop();  
  
            Console.WriteLine("Dynamic Create Time: {0} ms", watch.Elapsed.TotalMilliseconds);  
  
            Assert.IsNotNull(instance, "instance is Null");  
            Assert.IsTrue(instance is Collection<DateTime>);  
  
            Collection<DateTime> dates = instance as Collection<DateTime>;  
  
            Assert.IsNotNull(dates, "dates is Null");  
  
            watch = Stopwatch.StartNew();  
            Collection<DateTime> d = new Collection<DateTime>();  
            watch.Stop();  
  
            Console.WriteLine("Normal Create Time: {0} ms", watch.Elapsed.TotalMilliseconds);  
        }  
  
        public Collection<T> GetCollection<T>()  
        {   
            return new Collection<T>();   
        }  
  
        [TestMethod()]  
        public void CallGenericMethodAtRuntime()  
        {  
            Stopwatch watch = Stopwatch.StartNew();  
            MethodInfo methodInfo = typeof(GenericTest).GetMethod("GetCollection");  
            MethodInfo genericInfo = methodInfo.MakeGenericMethod(typeof(DateTime));  
              
            object instance = genericInfo.Invoke(this, null);  
            watch.Stop();  
  
            Console.WriteLine("Dynamic Invoke Time: {0} ms", watch.Elapsed.TotalMilliseconds);  
  
            Assert.IsNotNull(instance, "instance is Null");  
            Assert.IsTrue(instance is Collection<DateTime>);  
  
            Collection<DateTime> dates = instance as Collection<DateTime>;  
  
            Assert.IsNotNull(dates, "dates is Null");  
  
            watch = Stopwatch.StartNew();  
            Collection<DateTime> d = this.GetCollection<DateTime>();  
            watch.Stop();  
  
            Console.WriteLine("Normal Invoke Time: {0} ms", watch.Elapsed.TotalMilliseconds);  
        }  
    }  
}

Google Toolbar Spell Check API

I saw in this post that the Google toolbar could be extracted and looked at. So, I spend an afternoon reverse engineering the spell checker api. The api ends up to be very easy to use. Checking is done with an HTTP post to https://www.google.com/tbproxy/spell?lang=en&hl=en.

The xml structure looks like this…

<?xml version="1.0" encoding="utf-8" ?>  
<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">  
    <text>Ths is a tst</text>  
</spellrequest>  

The response look like …

<?xml version="1.0" encoding="UTF-8"?>  
<spellresult error="0" clipped="0" charschecked="12">  
    <c o="0" l="3" s="1">This Th's Thus Th HS</c>  
    <c o="9" l="3" s="1">test tat ST St st</c>  
</spellresult>  
Tag Description
o The offset from the start of the text of the word
l Length of misspelled word
s Confidence of the suggestion
text Tab delimited list of suggestions

I created a complete C# GoogleSpell library as a demo. The library can be download at http://www.loresoft.com/files/uploads/GoogleSpell.zip

Here is an example on how to use GoogleSpell …

string text = "ths is a tst";  
SpellRequest request = new SpellRequest(text);  
  
SpellResult result = SpellCheck.Check(request);  
  
foreach (SpellCorrection correction in result.Corrections)  
{  
    Console.WriteLine("Misspelled: {0} ({1}:{2})",   
        text.Substring(correction.Offset, correction.Length),   
        correction.Offset, correction.Length);  
  
    foreach(string suggestion in correction.Suggestions)  
    {  
        Console.WriteLine("    {0}", suggestion);  
    }  
}  

I plan to develop an ajax web client for the google spell api. This will be really sweet as it won’t require anything to be installed on the sever other then a js file. I’ll post again when I have the web client complete.


Stopwatch class from .net 2.0 framework ported .net 1.1

Here is the handy Stopwatch class from .net 2.0 framework back ported .net 1.1. Enjoy…

/// <summary>Provides a set of methods and properties that you can use to accurately measure elapsed time.</summary>  
public class Stopwatch  
{  
    #region SafeNativeMethods  
    [DllImport("kernel32.dll")]  
    private static extern bool QueryPerformanceFrequency(out long lpFrequency);  
    [DllImport("kernel32.dll")]  
    private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);  
    #endregion //SafeNativeMethods  
    #region Public Fields          
    /// <summary>Gets the frequency of the timer as the number of ticks per second. This field is read-only.</summary>  
    public static readonly long Frequency;  
      
    /// <summary>Indicates whether the timer is based on a high-resolution performance counter. This field is read-only.</summary>  
    public static readonly bool IsHighResolution;  
     
    #endregion //Public Fields  
     
    #region Private Fields  
    private long elapsed;          
    private bool isRunning;  
    private long startTimeStamp;  
      
    private static readonly double tickFrequency;  
    #endregion //Private Fields  
    #region Constructors  
    static Stopwatch()  
    {  
        if (!QueryPerformanceFrequency(out Stopwatch.Frequency))  
        {  
            Stopwatch.IsHighResolution = false;  
            Stopwatch.Frequency = TimeSpan.TicksPerSecond;  
            Stopwatch.tickFrequency = 1;  
        }  
        else  
        {  
            Stopwatch.IsHighResolution = true;  
            Stopwatch.tickFrequency = TimeSpan.TicksPerSecond;  
            Stopwatch.tickFrequency /= ((double)Stopwatch.Frequency);  
        }  
    }  
      
    /// <summary>Initializes a new instance of the Stopwatch class.</summary>  
    public Stopwatch()  
    {  
        this.Reset();  
    }  
    #endregion //Constructors  
     
    #region Private Methods  
    private long GetElapsedDateTimeTicks()  
    {  
        long ticks = this.GetRawElapsedTicks();  
        if (Stopwatch.IsHighResolution)  
        {  
            double highTicks = ticks;  
            highTicks *= Stopwatch.tickFrequency;  
            return (long)highTicks;  
        }  
        return ticks;  
    }  
    private long GetRawElapsedTicks()          
    {  
        long elapsedTimestamp = this.elapsed;  
        if (this.isRunning)  
        {  
            long currentTimestamp = Stopwatch.GetTimestamp();  
            long endTimestamp = currentTimestamp - this.startTimeStamp;  
            elapsedTimestamp += endTimestamp;  
        }  
        return elapsedTimestamp;  
    }  
    #endregion //Private Methods  
    #region Public Methods  
    /// <summary>Gets the current number of ticks in the timer mechanism.</summary>  
    /// <returns>A long integer representing the tick counter value of the underlying timer mechanism.</returns>  
    public static long GetTimestamp()          
    {  
        if (Stopwatch.IsHighResolution)  
        {  
            long ticks = 0;  
            QueryPerformanceCounter(out ticks);  
            return ticks;  
        }  
        return DateTime.UtcNow.Ticks;  
    }  
    /// <summary>Stops time interval measurement and resets the elapsed time to zero.</summary>  
    public void Reset()          
    {  
        this.elapsed = 0;  
        this.isRunning = false;  
        this.startTimeStamp = 0;  
    }  
    /// <summary>Starts, or resumes, measuring elapsed time for an interval.</summary>  
    public void Start()          
    {  
        if (!this.isRunning)  
        {  
            this.startTimeStamp = Stopwatch.GetTimestamp();  
            this.isRunning = true;  
        }  
    }  
    /// <summary>Initializes a new Stopwatch instance, sets the elapsed time property to zero, and starts measuring elapsed time.</summary>  
    /// <returns>A Stopwatch that has just begun measuring elapsed time.</returns>  
    public static Stopwatch StartNew()          
    {  
        Stopwatch stopwatch = new Stopwatch();  
        stopwatch.Start();  
        return stopwatch;  
    }  
    /// <summary>Stops measuring elapsed time for an interval.</summary>  
    public void Stop()          
    {  
        if (this.isRunning)  
        {  
            long currentTimestamp = Stopwatch.GetTimestamp();  
            long endTimestamp = currentTimestamp - this.startTimeStamp;  
            this.elapsed += endTimestamp;  
            this.isRunning = false;  
        }  
    }  
    #endregion //Public Methods  
     
    #region Public Properties  
    /// <summary>Gets the total elapsed time measured by the current instance.</summary>  
    /// <value>A read-only System.TimeSpan representing the total elapsed time measured by the current instance.</value>  
    public TimeSpan Elapsed  
    {  
        get { return new TimeSpan(this.GetElapsedDateTimeTicks()); }  
    }  
      
    /// <summary>Gets the total elapsed time measured by the current instance, in milliseconds.</summary>  
    public long ElapsedMilliseconds  
    {  
        get { return (this.GetElapsedDateTimeTicks() / TimeSpan.TicksPerMillisecond); }  
    }  
    /// <summary>Gets the total elapsed time measured by the current instance, in timer ticks.</summary>  
    public long ElapsedTicks  
    {  
        get { return this.GetRawElapsedTicks(); }  
    }  
      
    /// <summary>Gets a value indicating whether the Stopwatch timer is running.</summary>  
    public bool IsRunning  
    {  
        get { return this.isRunning; }  
    }  
    #endregion //Public Properties  
}