dotnet thoughts 

a dotnet developer's technical blog

How to create your own custom Accelerator for Internet Explorer

The Accelerator feature of the IE helps to quickly perform everyday browsing tasks without leaving the website. Simply highlight the text, click on the blue Accelerator icon that appears above your selection, it will popup the different Accelerator options. For example, with the “Map with Bing” Accelerator in Internet Explorer, you can get an in-place view of a map displayed directly on the page.

In this example, I am creating an Accelerator for searching StackOverflow.com. The Accelerator is simply an XML file, you can find more details about this XML specification here

Here is the implementation

<?xml version="1.0" encoding="UTF-8" ?>
<openServiceDescription xmlns="http://www.microsoft.com/schemas/openservicedescription/1.0">
<homepageUrl>http://www.stackoverflow.com/</homepageUrl>
<display>
	<name>Search with Stackoverflow</name>
	<icon>http://sstatic.net/stackoverflow/img/favicon.ico</icon>
    <description>Search with Stackoverflow</description>
</display>  

<activity category="Search">
	<activityAction context="selection">
		<execute method="get" action="http://stackoverflow.com/search?q=">
			<parameter name="q" value="{selection}" type="text" />
		</execute>
	</activityAction>
</activity>
</openServiceDescription>

Also you require a HTML file to install the Accelerator to IE. It will use window.external.AddService method. Here is the HTML file.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
    <title>Add SO Search Accelerator</title>
    <meta content="text/html; charset=windows-1255" http-equiv="Content-Type"/>
    <meta name="GENERATOR" content="MSHTML 8.00.6001.18372"/>
</head>
<body>
    <button id="myButton"
   onclick="window.external.AddService('http://localhost/installs/search_so.xml')">
                        Press to add SO Search Accelerator</button>
</body>
</html>

Pressing on the button will popup, an Add Accelerator dialog, click on Add button, which will add the accelerator to your browser.

Add Accelerator Dialog

Add Accelerator Dialog

And here is the Accelerator in action.

Accelerator in Action

Accelerator in Action

Happy Coding :)

How to write an NUnit Addin

From version 2.2.x NUnit supports AddIns. Addins can customize NUnit’s internal behavior such as the creation of tests and their execution. An Addin should to implement the interface NUnit.Core.Extensibility.IAddin, which can be found in the assembly nunit.core.interfaces. Also the NUnit.Core.Extensibility.NUnitAddinAttribute must be applied to Addin class. The attribute parameters Name and Description represent the name of the extension and a description of what it does. The NUnit.Core.Extensibility.IAddin has only one method, Install(). The Install method is called by each host for which the addin has specified an ExtensionType. The addin should check that the necessary extension points are available and install itself, returning true for success or false for failure to install. The method will be called once for each extension host and – for Core extensions – each time a new test domain is loaded. Here is a minimal addin.

namespace SampleAddIn
{
    using NUnit.Core.Extensibility;

    [NUnitAddin(Name = "SampleAddIn", Description = "This is a Sample AddIn")]
    public class SampleNUnitAddin : IAddin
    {
        #region IAddin Members

        public bool Install(IExtensionHost host)
        {
            return true;
        }

        #endregion
    }
}

You can install the Addin, by copying the assembly to bin\Addins folder, relative to NUnit installation directory. You can verify your addin by starting NUnit, Tools > Addins menu.

Registered AddIns Dialog

Registered AddIns Dialog

This Addin does nothing. It simply registers itself to NUnit. You can more details about NUnit Addins here
If you are using VS2010, then please make sure your target framework is .Net 2.0. Otherwise Addin won’t work.

How to add MEX endpoints programmatically

The Metadata Exchange Endpoint (MEX) is a special endpoint in WCF that exposes metadata used to describe a service.Without the MEX, you will not be able to use svcutil.exe to automatically generate a proxy class. Fortunately, it is a simply process to enable the MEX for your service. Here is the code which will add Mex endpoint programmatically.

var metadataBehavior = serviceHost.Description.Behaviors.Find<ServiceMetadataBehavior>()
    ?? new ServiceMetadataBehavior();
serviceHost.Description.Behaviors.Add(metadataBehavior);
serviceHost.AddServiceEndpoint(typeof(IMetadataExchange),
    MetadataExchangeBindings.CreateMexHttpBinding(),
    "http://localhost:8080/IService/Mex");

It should be noted that you are not required to enable HttpGet. SvcUtil will still be able to access the MEX without it. However, it is useful if you want to view the WSDL from a browser by going to the address of the service. You cannot do so without enabling the HttpGet.

How to execute ms tests in parallel on multi-cpu / core machines

VS 2010 supports running MS Tests in parallel. Most of the machines available in the market are multi-cpu / core machines. This will help us to increase the number of tests executing in same time, which will reduce total test time. But while writing tests, developers should make sure the tests are thread safe, if it is not, it may result in incorrect results, deadlocks etc.

You can enable parallel test execution by editing the testsettings file, instead of double click and open the test settings dialog, open the file using Open with option in the context menu, and select XML(Text) Editor option, which open the testsettings file in XML Editor. In the XML, find the Execution element. Add parallelTestCount attribute to the Execution element(By default it will not be there).

Parallel Test count attribute in testsettings file

Parallel Test count attribute in testsettings file

By default it will be 1(if the attribute is not exists), other options are 0 for Auto configure we will use as many tests as we can based on your CPU and core count, and n, the number n of tests to run in parallel. Save the changes. Restart visual studio. And you are done.(Note: You need to restart visual studio, otherwise changes will not reflect.)

Here is a sample unit test

[TestMethod]
public void TestMethod3()
{
    Console.WriteLine(Thread.CurrentThread.Name);
    Thread.Sleep(2000);
}

Now I am running few test cases (11) with no parallelTestCount attribute and here is the Test Results window and summary

Test Results View - No attribute specified

Test Results View - No attribute specified

Test Results summary - No attribute specified

Test Results summary - No attribute specified

Now I added the parallelTestCount attribute, with value of 5 and here is the Test Results window and summary, you can notice the time difference between two executions.

Test Results View - parallelTestCount Attribute specified

Test Results View - parallelTestCount Attribute specified

Test Results Summary - With parallelTestCount attribute specified

Test Results Summary - With parallelTestCount attribute specified

Of course there are many other factors that affect this. There is the cost of starting and tearing down the run, so you will see a lesser effect if you have a few tests. It also depends on the number of CPU/cores you have and of course how fast your tests execute.

Happy unit testing :)

How to queue a new build using TFS API

Another post on TFS API, my last post was related to how to get build Definitions and Build Details from TFS 2010, and this post is about how to queue a new build in TFS 2010 Server.

As earlier you need to add reference of following assemblies

  1. Microsoft.TeamFoundation.dll
  2. Microsoft.TeamFoundation.Client.dll
  3. Microsoft.TeamFoundation.Build.Client.dll

which will be available under – C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\ location.

And here is the code snippet

var tfsName = "http://dotnetthoughts:8080/tfs/defaultcollection";
var tfs = new TeamFoundationServer(tfsName, new UICredentialsProvider());
tfs.EnsureAuthenticated();
if (tfs.HasAuthenticated)
{
	var buildServer = tfs.GetService(typeof(IBuildServer)) as IBuildServer;
	var buildDefinition = buildServer.GetBuildDefinition("", "");
	buildServer.QueueBuild(buildDefinition);
}
catch (Exception exception)
{
    MessageBox.Show(exception.Message);
    throw;
}

Here is how it works, we are connecting and getting the TFS Server, then getting the Build Server using GetService method. And to get the build definition instead of the earlier post(to get all the Build definitions, we are passing “*”), we need to specify the Team project and Build name(Build definitions are unique per team project in TFS). Then we can call QueueBuild() method on Build server object, with build definition as the parameter, which will queue the build definition default values.

Happy coding :)

Older Posts »