Monday, May 27, 2013

Associate protocol with application exe or PowerShell script

First of all let me ask a simple question. Have you tried executing  'http://google.com' in the run command ? If not, just try it now. Use the short cut key Win+R to popup the run dialog. You can see your default browser is opening up and navigating to the google.com web site. Similarly if you try to execute the command 'mailto:joymon@gmail.com' in the run command it will open up your default email client and the 'to' address will be automatically populated as 'joymon@gmail.com'.

Now you might have thinking about your own protocol and your own processing application. Yes the http is a protocol. In a simple sense, its a format for communication. By seeing the word 'http' the consumers can process the remaining part of the message accordingly. Notice that, when we try to run the command which is prefixed with protocol through run dialog in windows, a program is catching the command and its taking actions after that. The program here means an .exe file.

This means if we know, how to link a protocol to an application we can have our own protocol which will be recognized by Windows. That linking is done in windows registry

Protocol to program mapping

If you are not familiar with windows registry, please get a basic idea about it from wiki. Windows registry is basically a configuration store for the Windows operating system. You can use the regedit.exe command to start editing the registry. Basically we need to create a hierarchy of keys in HKEY_CLASSES_ROOT element of registry. The hierarchy is <protocol name> -> shell -> open -> command. Inside the command key, we need to have default string value which is pointing to the application name. %1 denote that the Uri itself should be passed to the exe file as command line argument. Below is the registry entry for associating protocol named 'joymon:' with an application which will invoke TestProtocol.exe when I run the below via Run dialog or include in an HTML file.

joymon://WhateverYouWant/AsParameter - This whole line will be entering to the TestProtocol.exe as paramater


Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\joymon]
@="URL:joymon"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\joymon\shell]

[HKEY_CLASSES_ROOT\joymon\shell\open]

[HKEY_CLASSES_ROOT\joymon\shell\open\command]
@="C:\\TestProtocol.exe  \"%1\""


The above lines of code can be saved to a file with extension .reg and that file can be imported to registry by double clicking. Another thing to note is the @="URL:joymon" and "URL Protocol"="" values. These are used to identify the protocol by the Windows.

If you ask me what is the code for simple C# TestProtocol.exe app to receive the notification, I will suggest a win forms app which obtains and process the command line args as follow.


//-------   C#.Net console program to process command line args ---------

    public class Program
    {
        static void Main(string[] args)
        {           
//Process the commandline string it will be like joymon://Joy's message
            string commandline = Environment.CommandLine;
            //Code to process the received argument
        }
   }

Protocol to PowerShell script / file mapping

We can even run PowerShell script in association with a protocol. But actually we are running the application named PowerShell.exe and passing the script as parameter. Below is the registry entry for the same.


Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\joymon]
@="URL:joymon"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\joymon\shell]

[HKEY_CLASSES_ROOT\joymon\shell\open]

[HKEY_CLASSES_ROOT\joymon\shell\open\command]
@="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell -windowstyle hidden -command \"&{param ([string]$p);[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');[Windows.Forms.Messagebox]::Show($p);}\" \"%1\""


If you are familiar with PowerShell you can easily identify that I am passing a script block prefixes with & to execute it to the PowerShell.exe. The argument will be relayed to the PowerShell script by the PowerShell.exe.

Real time use cases

  1. Short cut to your application's features - You can define your own protocol to create short cuts which are pointing to different screens of your application. So that when the user runs the protocol, your application can start and it can show up the corresponding screen .

    eg: If you are developing 'Address book' application you can have url, which say 'ad://list/1' can directly open the contact whose id is 1.
  2. Interoperability with other applications - If you expose URLs of your applications other apps can easily invoke modules of your app easily.

    eg: In an address book ad://adduser?name=joy&mobile=9544400706 can add a new user without opening up the application itself. This URL can be called by the other apps using Process.Start('ad://adduser?name=joy&mobile=9544400706');

Monday, May 20, 2013

Creating bug work item programatically using TFS 2010 sdk and assign to a user

If you had gone through my previous TFS SDK articles listed below you will be familiar with TFS programming.

http://joymonscode.blogspot.in/2009/05/beginning-tfs-programming.html
http://joymonscode.blogspot.in/2013/04/find-out-name-of-last-checked-in-user.html

As you know using TFS sdk is really simple as knowing how to create the service and basic TFS object model.So what is special about creating TFS bug work item and assign to a developer?

Changing 'Assigned to' field of Work Item object

The speciality is about how you specify the user in the bug. In other words how to set the "Assigned To" field of TFS work item from code? When we list out the bugs in Visual Studio, you might have noticed that the Assigned To column shows the display name. This gives an impression that the TFS is converting the user name to display name for the display purpose. But unfortunately its not.

Hope you know the difference about the username and display name. Username is the unique identification for a user. It didn't allows space in between. But in the display name it allows white spaces as its only for display purpose, not to uniquely identify the user.

Usual user name format - domain\username eg: "companyname\joyg"
Usual display name format - <full name> <last name> eg: "Joy George K"

The point here in creating and assigning TFS bug to a user is, we need to specify the display name in the 'Assigned To' field of WorkItem object instead of the user name. The challenge is most of the other services of TFS returns the username which needs to be converted to Display name before assigning the work item to the user. See the below code to create and assign a work item to a user

        private void AddBug(string userDisplayName)
        {
            WorkItemStore wis = GetWorkItemStore();
            Project tp = wis.Projects[_teamProject];
 
            WorkItemType wit = tp.WorkItemTypes["Bug"];
 
            WorkItem wi = new WorkItem(wit);
            //"[Assigned to] must be display name eg: Joy George K"
            wi.Fields["Assigned to"].Value = userDisplayName; 
            wi.Title = "Bug from TFS sdk demo";
            wi.Description = "Bug from TFS sdk demo";
            ArrayList al = wi.Validate();
            if(al.Count ==0) wi.Save();
        }
        private static WorkItemStore GetWorkItemStore()
        {             TeamFoundationServer tfs = new TeamFoundationServer(new Uri(Path.Combine(_myTFSUri, _teamProjectCollectionName)));             WorkItemStore vcs = (WorkItemStore)tfs.GetService(typeof(WorkItemStore));             return vcs;         }

Get display name from username

As I told earlier, most of the other TFS services return username instead of display name. So it is required to convert username to display name, if you are using the result of other services to create work item against a particular user. Below is the code to convert user name to display name.

        private string GetDisplayNameFromUserName(string userName)
        {
            IGroupSecurityService grpservice = GetGroupSecurityService();
            return grpservice.ReadIdentityFromSource(SearchFactor.AccountName, userName).DisplayName;
        }

        private IGroupSecurityService GetGroupSecurityService()
        {
            TeamFoundationServer tfs = new TeamFoundationServer(new Uri(Path.Combine(_myTFSUri, _teamProjectCollectionName)));
            IGroupSecurityService gss = (IGroupSecurityService)tfs.GetService(typeof(IGroupSecurityService));
            return gss;
        }

Happy coding...

Monday, May 13, 2013

My VS 2010 Extension to remove duplicate blank lines is online

The problem

In my current project, we deal with a large legacy code base on a day to day basis. Some of the files inside are of 4000 lines of code and more. One of the reason for these huge files, is the continuous white spaces or multiple blank lines along with other reasons such as lack of SOLID principles.

No of lines is not an issue for an experienced intelligent developer, if he think from the technical point of view. But there is a mental blocking, when a new person is assigned with a bug in these areas. They look at the code and thinks, it's huge and need more time to find out the location and fix which eventually leads to delivery problems. 

Simple solution

As far as I understand, there is no silver bullet to solve the issue of increasing lines due to lack of SOLID principles in the code. That  needs to come from the heart of each developer. So lets focus on the issue of increasing lines, due to multiple blanks lines.

There is regex and the Visual Studio search and replace box supports it. We can use the appropriate regex to find multiple blank lines and replace with single empty line. Below is a link to regex which replaces double blank lines to single.


But as I told in the problem, if the developers are intelligent, the no of lines will not be an issue to them and they will be familiar with regex too. The case is different here. People needs single click easy solution and it lead to Visual Studio extensions.

My solution

Its simple. I used a simple Visual studio menu extensibility project after installing VS 2010 sdk and on the menu click, replaced the editor text after removing multiple blank lines.

How you can use it

The beauty of the new Visual Studio extensibility, is the ease of sharing our extensions to the world. I hosted my extension in Visual Studio gallery and you can download and use from the below link.

http://visualstudiogallery.msdn.microsoft.com/27edfcc0-a935-4126-bdaa-fb366173ad0b

But I would suggest you going to Visual Studio 2010 tools -> extension manager and search for "remove blank lines" in the online store and install from there.

Source code

Feel free to reuse / browse the code in code plex. removeblanklines.codeplex.com
Do whatever you want with the code base. If you have any queries please post as comment here or send a mail.

Below are some links which helped me during development.

Disable / enable VS menus based on criteria
GUIDs of existing VS menu command GUIDs http://msdn.microsoft.com/en-us/library/cc826118.aspx

Monday, May 6, 2013

C# v/s VB.Net Program to interface not to implementaion

Why it is said that "Always program to interface not to implementation"?

The reason is simple. If we program to interfaces, we can change it's underlying implementation at any time without changing the code which is using it. For simple example, we all deal with databases on a daily basis. When we are writing DAL (Data Access Layer) and our track codes point to the IDataAcessLayer the implementations can be anything  .ie it Can be SQLDatAccessLayer,OracleDataAccessLayer etc...Which means at a future point if your project stakeholders decide to change the DB there is no need to change your track code it the application logic projects. Only we need to change the object which is created for IDataAccessLayer.

Challenges in enforcing "Program to interface not to implementation" in large projects

Like any other engineering discipline, its easy to manage and keep the quality, if the team is small. We can have frequent reviews. Mentor them, even monitor closely. When the team grows beyond 100s with half of them are just passed out from college, its really difficult to make sure we are following this principle. This will not a problem, if you are developing a product where you have full control on the release timeline or in a project where you have lavish budget to allocate senior developers for code review. But this is not the case in most of the Indian software service companies.

C# - Enforcing "Program to interface not to implementation"

In programming languages like C# its very easy to make all developers follow the principle. Who ever developing the classes, need to implement the interfaces explicitly. Which means the track developers ( fresher category normally fills this position) cannot refer the interface methods using a class variable which they could have otherwise.

It's simple. Isn't it? the interface members are public by default. No question on that. If we implement it implicitly in a class, the other developers can create the variable of that class and invoke the interface members. Lets see the below code snippet which will give more understanding about explicit interface implementation.

    public interface IMyInterface
    {
        void Foo();
    }
    public class MyClass : IMyInterface
    {
        void IMyInterface.Foo()
        {
            Console.WriteLine("MyClass.Foo");
        }
    }
    public class Program
    {
        static void Main(string[] args)
        {
            IMyInterface mI = new MyClass();
            mI.Foo(); //This ensures that the members are only be accessible via interface variable.
            MyClass mC = new MyClass();
            //mC.Foo(); This will cause compilation error.
            //TestMethod();
        }
    }

VB.Net - Enforcing "Program to interface not to implementation"

In C# its easy as there is explicit interface implementation. Even there are more help on the same. But VB.Net doesn't have that concept. So the solution to enforcing 'program to interface..' in VB.Net, is the alternative of explicit interface implementation, similar to C#. And the solution is as follows.

Implement interface members as private in VB.Net to achieve explicit interface implementation.

No need to wonder, thinking that interface members are always public. Read the MSDN page for more details. Below is a code snippet which does the same in VB.Net

Public Interface IMyInterface
    Sub Foo()End Interface
 Public Class MyImplementation
    Implements IMyInterface
    Private Sub Foo() Implements IMyInterface.Foo
        Console.WriteLine("MyImplementation.Foo()")
    End Sub
End Class
 Module Module1
    Sub Main()
        Dim mI As IMyInterface New MyImplementation()
        mI.Foo()'Works
        Dim mC As MyImplementation = New MyImplementation()
        'mC.Foo() ' Doesn't work
    End Sub
End Module

It took really long time for me to find out a mechanism to enforce the "Program to interface..." principle in VB.Net.