Tuesday, June 23, 2009

Managed Extensibility Framework - Part1

I wanted to make this post since last two weeks. For some reason it didn’t happen. Today I was asked by one of my colleagues so I couldn’t take another exception.

First let me introduce you what is officially told about this framework

“The Managed Extensibility Framework (MEF) is a new library in .NET that enables greater reuse of applications and components. Using MEF, .NET applications can make the shift from being statically compiled to dynamically composed. If you are building extensible applications, extensible frameworks and application extensions, then MEF is for you.”

So take that middle sentence “statically compiled to dynamically composed”. It is all about that.

Building reusable code into libraries and using them in applications is normal. In legacy Win32 applications if a library is linked to an application, linker used to add reference to that library in PE header. When runtime tries to load this application loader used to perform following operations

  1. resolve all dependencies
  2. load them into memory
  3. map them to respective pointers
  4. then start main routine

But with CLR, and JIT compilation in the middle, things are slightly different. Now loader tries to load those libraries which are needed to execute just the Main method. As other methods are called from Main, IL for those methods are JIT compiled on demand and loaded into memory. These things can be simplified with an example. [By the way, if you are thinking that I am going away from main subject of MEF; you are thinking correctly. But I am doing this internationally. Because I feel understanding about the problem that MEF is trying to solve makes you an informed user of MEF, so that you will be able clearly distinguish when and where MEF can be used. So I will keep this part of the series just for introduction.]

Now coming back to example. Let us start with a simple console application. Name it “WOMEF”. (without MEF.)

Replace the code in Program.cs with following snippet.

using System;
using WOMEFLib;

namespace WOMEF
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter 0 to quit, any other number to continue");
while (Console.ReadLine() != "0")
{
new Program().SayHelloToUser();
}
}

public void SayHelloToUser()
{
Console.WriteLine("In SayHelloToUser");
IWOMEFLib womeflib = new CWOMEFLib();
womeflib.SayHello(Environment.UserDomainName + Environment.UserName);
Console.ReadLine();
}
}
}
Let us define IWOMEFLib and CWOMEFLib in a library. So add a class library project to this solution by name “WOMEFLib”.

Rename Class1.cs to CWOMEFLib.cs. Then replace code with following snippet.


using System;
namespace WOMEFLib
{
public interface IWOMEFLib
{
int SayHello(string username);
}
public class CWOMEFLib : IWOMEFLib
{

#region IWOMEFLib Members

public int SayHello(string username)
{
Console.WriteLine("\"" + "Say Hello to " + username + "\"");
return 0;
}

#endregion
}
}
Now in WOMEF project add a project reference to WOMEFLib project. Change configuration to Release, build and test application.

So nothing great about this. But we are going to witness some interesting facts with these two assemblies.

  1. When loader loads CWOMEFLib.dll

  2. What happens if CWOMEFLib.dll is missing when application is starting

  3. When SayHelloToUser methods is JIT compiled

  4. What happens if CWOMEFLib.dll is copied to application directory while it is waiting for user input

In order to check these scenarios we are going to view method table and descriptors of application WOMEFLib.exe in runtime.

We are going to use Windbg here. If you don’t have it installed download it at link.

When loader loads CWOMEFLib.dll

Here we are going to check when loader loads CWOMEFLib.dll.

  1. Start Windbg.

  2. In Windbg, click on File –> Open executable

  3. Navigate to Release folder of solution and select WOMEF.exe

  4. Windbg stops with interrupt 3. Press F5 to continue.
  5. ntdll!DbgBreakPoint:
    7c90120e cc int 3


  6. Now application starts and waits for user entry with message “Enter 0 to quit, any other number to continue”

  7. In Windbg go to Debug menu and click on break. This is the ideal time to break into application as it is up and running.

  8. Now load sos.dll in windbg by entering following command in Windbg “.loadby sos.dll mscorwks”
  9. ntdll!DbgBreakPoint:
    7c90120e cc int 3
    Missing image name, possible paged-out or corrupt data.
    0:003> .loadby sos.dll mscorwks


  10. Now dumpdomains by entering command “!dumpdomain”

  11. 0:003> !dumpdomain
    *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINDOWS\Microsoft.NET\... -
    PDB symbol for mscorwks.dll not loaded
    --------------------------------------
    System Domain: 7a3bd058
    LowFrequencyHeap: 7a3bd07c
    HighFrequencyHeap: 7a3bd0c8
    StubHeap: 7a3bd114
    Stage: OPEN
    Name: None
    --------------------------------------
    Shared Domain: 7a3bc9a8
    LowFrequencyHeap: 7a3bc9cc
    HighFrequencyHeap: 7a3bca18
    StubHeap: 7a3bca64
    Stage: OPEN
    Name: None
    Assembly: 001b0628
    --------------------------------------
    Domain 1: 0016d298
    LowFrequencyHeap: 0016d2bc
    HighFrequencyHeap: 0016d308
    StubHeap: 0016d354
    Stage: OPEN
    SecurityDescriptor: 0016e5c0
    Name: WOMEF.exe
    Assembly: 001b0628 [C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll]
    ClassLoader: 001b06a8
    SecurityDescriptor: 001ae190
    Module Name
    033e1000 C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll


    Assembly: 001b9800 [D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEF.exe]
    ClassLoader: 001b9e68
    SecurityDescriptor: 001b96c8
    Module Name
    00a72c5c D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEF.exe


    Assembly: 001bcb30 [D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEFLib.dll]
    ClassLoader: 001bbc98
    SecurityDescriptor: 001bcd28
    Module Name
    00a730c8 D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEFLib.dll

  12. As expected there are three app domains. In application specific appdomain three assemblies are loaded. First one (mscorlib.dll) is pretty standard one. Second one (WOMEF.exe) is application itself. And third one (WOMEFLib.dll) is referenced assembly.

  13. So loader loaded referenced assembly though we have not yet used any type from it so far. We are just at first line in Main method. Also we don’t use any type from WOMEF.dll in Main method. Still loader loaded this assembly because it is there in manifest. Now let us see what happens if this assembly is not available when we start WOMEF.exe. Kill application by pressing Control+C. If needed close Windbg and reopen.

What happens if CWOMEFLib.dll is missing when application is starting

Here we are going to check what happens if CWOMEFLib.dll is missing when application is starting. Move CWOMEFLib.dll from Release folder to some other folder outside solution directory (say to Desktop. Don’t copy cut it.)

  1. Start Windbg.

  2. In Windbg, click on File –> Open executable

  3. Navigate to Release folder of solution and select WOMEF.exe

  4. Windbg stops with interrupt 3. Press F5 to continue.
  5. ntdll!DbgBreakPoint:
    7c90120e cc int 3

  6. Now application starts and waits for user entry with message “Enter 0 to quit, any other number to continue”.

  7. Though one of the dependent assembly is not available application runs normally till this point. This makes an interesting point. Why loader didn’t complain that CWOMEFLib.dll is not available? Answer is SayHelloToUser is not yet JIT compiled. And we will verify this fact in next section. Kill application by pressing Control+C. If needed close Windbg and reopen.

When SayHelloToUser methods is JIT compiled

Here we are going to check when SayHelloToUser methods is actually JIT compiled. Move back CWOMEFLib.dll to Release folder.

  1. Start Windbg.

  2. In Windbg, click on File –> Open executable

  3. Navigate to Release folder of solution and select WOMEF.exe

  4. Windbg stops with interrupt 3. Press F5 to continue.
  5. ntdll!DbgBreakPoint:
    7c90120e cc int 3
  6. Now application starts and waits for user entry with message “Enter 0 to quit, any other number to continue”.

  7. In Windbg go to Debug menu and click on break. This is the ideal time to break into application as it is up and running.

  8. Now load sos.dll in windbg by entering following command in Windbg “.loadby sos.dll mscorwks”
  9. ntdll!DbgBreakPoint:
    7c90120e cc int 3
    Missing image name, possible paged-out or corrupt data.
    0:003> .loadby sos.dll mscorwks


  10. Now dumpdomains by entering command “!dumpdomain”

  11. 0:003> !dumpdomain
    *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINDOWS\Microsoft.NET\... -
    PDB symbol for mscorwks.dll not loaded
    --------------------------------------
    System Domain: 7a3bd058
    LowFrequencyHeap: 7a3bd07c
    HighFrequencyHeap: 7a3bd0c8
    StubHeap: 7a3bd114
    Stage: OPEN
    Name: None
    --------------------------------------
    Shared Domain: 7a3bc9a8
    LowFrequencyHeap: 7a3bc9cc
    HighFrequencyHeap: 7a3bca18
    StubHeap: 7a3bca64
    Stage: OPEN
    Name: None
    Assembly: 001b0628
    --------------------------------------
    Domain 1: 0016d298
    LowFrequencyHeap: 0016d2bc
    HighFrequencyHeap: 0016d308
    StubHeap: 0016d354
    Stage: OPEN
    SecurityDescriptor: 0016e5c0
    Name: WOMEF.exe
    Assembly: 001b0628 [C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll]
    ClassLoader: 001b06a8
    SecurityDescriptor: 001ae190
    Module Name
    033e1000 C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll


    Assembly: 001b9800 [D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEF.exe]
    ClassLoader: 001b9e68
    SecurityDescriptor: 001b96c8
    Module Name
    00a72c5c D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEF.exe


    Assembly: 001bcb30 [D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEFLib.dll]
    ClassLoader: 001bbc98
    SecurityDescriptor: 001bcd28
    Module Name
    00a730c8 D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEFLib.dll

  12. Now we are just at first line of Main method. Let us get address if method table of assembly WOMEF.exe by using command !dumpmodule –mt <module address 00a72c5c>. See module address in red color.
  13. 0:003> !dumpmodule -mt 00a72c5c
    Name: D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEF.exe
    Attributes: PEFile
    Assembly: 001b9780
    LoaderHeap: 00000000
    TypeDefToMethodTableMap: 00a700c0
    TypeRefToMethodTableMap: 00a700cc
    MethodDefToDescMap: 00a70128
    FieldDefToDescMap: 00a70138
    MemberRefToDescMap: 00a7013c
    FileReferencesMap: 00a701a4
    AssemblyReferencesMap: 00a701a8
    MetaData start address: 004020c0 (1864 bytes)

    Types defined in this module

    MT TypeDef Name
    ------------------------------------------------------------------------------
    00a73010 0x02000002 WOMEF.Program

    Types referenced in this module

    MT TypeRef Name
    ------------------------------------------------------------------------------
    03650508 0x01000001 System.Object
    03654258 0x01000012 System.Console
    036508ec 0x01000013 System.String
    00a73484 0x01000016 WOMEFLib.IWOMEFLib


  14. Using method table address let us get module descriptions by using command !dumpmt –md <method table 00a73010>. See mt address in red color.
  15. 0:003> !dumpmt -md 00a73010
    EEClass: 00a712f4
    Module: 00a72c5c
    Name: WOMEF.Program
    mdToken: 02000002 (D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEF.exe)
    BaseSize: 0xc
    ComponentSize: 0x0
    Number of IFaces in IFaceMap: 0
    Slots in VTable: 7
    --------------------------------------
    MethodDesc Table
    Entry MethodDesc JIT Name
    035a6a70 03424934 PreJIT System.Object.ToString()
    035a6a90 0342493c PreJIT System.Object.Equals(System.Object)
    035a6b00 0342496c PreJIT System.Object.GetHashCode()
    036172f0 03424990 PreJIT System.Object.Finalize()
    00a7c019 00a73008 NONE WOMEF.Program..ctor()
    00de0070 00a72ff0 JIT WOMEF.Program.Main(System.String[])
    00a7c015 00a72ffc NONE WOMEF.Program.SayHelloToUser()

  16. Here observe the JIT status of SayHelloToUser method as NONE. Means that SayHelloToUser is not yet JIT compiled. Let us run the application by pressing F5 in Windbg and entering a non zero value in console. As soon as you enter a non-zero value in console CLR compiles SayHelloUser, loads it from with reference to SayHello method in WOMEFLib.dll. Now console waits for input because of ReadLine.

  17. Now let us break into debugger again by clicking on Break menu option of Debug menu in Windbg.

  18. Let us check status of method description again by using same command !dumpmt –md <method table 00a73010>. You can even use up arrow twice in windbg to get there.
  19. 0:003> !dumpmt -md 00a73010
    EEClass: 00a712f4
    Module: 00a72c5c
    Name: WOMEF.Program
    mdToken: 02000002 (D:\My Documents\Visual Studio 2008\Projects\MEF\WOMEF\WOMEF\bin\Release\WOMEF.exe)
    BaseSize: 0xc
    ComponentSize: 0x0
    Number of IFaces in IFaceMap: 0
    Slots in VTable: 7
    --------------------------------------
    MethodDesc Table
    Entry MethodDesc JIT Name
    035a6a70 03424934 PreJIT System.Object.ToString()
    035a6a90 0342493c PreJIT System.Object.Equals(System.Object)
    035a6b00 0342496c PreJIT System.Object.GetHashCode()
    036172f0 03424990 PreJIT System.Object.Finalize()
    00a7c019 00a73008 NONE WOMEF.Program..ctor()
    00de0070 00a72ff0 JIT WOMEF.Program.Main(System.String[])
    00de00d0 00a72ffc JIT WOMEF.Program.SayHelloToUser()


  20. Now observe status of SayHelloToUser method as JIT. This makes it clear that SayHelloToUser method would have never been JIT compiled if a zero is entered in console window as the first option. So when control goes inside while loop CLR started JIT compiling called method.

  21. Let us see a tricky case now. Assume that we wont make WOMEFLib.dll available to WOMEF.exe when WOMEF.exe is starting but we will copy this assembly while application is waiting for user input with message “Enter 0 to quit, any other number to continue” for the first time. Kill application by pressing Control+C. For this last case we don’t need windbg.

What happens if CWOMEFLib.dll is copied to application directory while it is waiting for user input

Here we are going to check what happens if CWOMEFLib.dll is copied to application directory while it is waiting for user input for the first time. Move CWOMEFLib.dll from Release folder to some other folder outside solution directory (say to Desktop. Don’t copy cut it.)
  1. Open command prompt

  2. Navigate to Release folder of solution and start WOMEF.exe

  3. Application starts and waits for user entry with message “Enter 0 to quit, any other number to continue”. At this point move back CWOMEFLib.dll to Release folder.

  4. Enter a non-zero value and press enter

  5. Now when application tries to compile SayHelloToUser, it tries to refer type CWOMEF in WOMEFLib.dll and fails to resolve assembly. It comes out with an exception

  6. Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'WOMEFLib, ..


  7. That means, even though the assembly is made available when it is actually being referred, loader ignores to reload.

  8. It is this particular aspect that MEF tries to solve.

Existing possibilities

OK with that background I hope you are clear on what MEF is trying to solve. But before looking at MEF let us see how we can solve this particular problem with existing technology. With CLR 2.0 we have an option of loading assembly in runtime. After loading assembly in runtime we can create objects of types defined in it and we can even invoke them using reflection techniques. This is quite straight forward. I will just provide a working sample. Do following changes to our solution
  1. In WOMEF project remove reference to WOMEFLib.dll.

  2. Then replace code in Program.cs with following snippet

  3. using System;
    using System.Reflection;
    namespace WOMEF
    {

    class Program
    {
    static void Main(string[] args)
    {
    Console.WriteLine("Enter 0 to quit, any other number to continue");
    while (Console.ReadLine() != "0")
    {
    new Program().SayHelloToUser();
    }
    }

    public void SayHelloToUser()
    {
    Console.WriteLine("In SayHelloToUser");
    InvokeMethod("WOMEFLib", "CWOMEFLib", "SayHello", new object[] { Environment.UserDomainName+Environment.UserName });
    Console.ReadLine();
    }

    public object InvokeMethod(string assemblyName, string className, string methodName, object[] parameters)
    {
    System.Type[] parametersTypes;
    int parametersCount = 0;
    object returnObject = null;
    try
    {
    Type type = System.Reflection.Assembly.LoadFrom(assemblyName + ".dll").GetType(
    assemblyName + "." + className);

    parametersTypes = new System.Type[parameters.GetUpperBound(0) + 1];

    foreach (object parameter in parameters)
    {
    if (parameter != null)
    parametersTypes[parametersCount] = parameter.GetType();
    parametersCount++;
    }

    MethodInfo mi = type.GetMethod(methodName, parametersTypes);
    ConstructorInfo ci = type.GetConstructor(Type.EmptyTypes);
    object objectinstance = ci.Invoke(null);
    //Invoke
    returnObject = mi.Invoke(objectinstance, parameters);
    }
    catch (TargetException tex)
    {
    throw tex;
    }

    return returnObject;
    }
    }
    }

  4. Here Invoke method loads assembly (WOMEFLib) in runtime, constructs class object (CWOMEFLib) and invokes a method (SayHello) in it.

In next post we will see how MEF framework not only simplifies this process but also provides many more useful options for tihis kind of scenarios.

Saturday, June 13, 2009

Integrating Real time communication tools with real time systems

There is an excellent video on how Wonderware integrated Office Communication framework around Application Server.

Kind of integration they achieved is remarkable. Watch video at link below to have glimpse on how it is done. It is quite evident from this video that social collaboration infrastructures when integrated with real-time systems bring lot of value proposition to plant floor. As dependency on various communication means (like mobile phones, messengers, micro blogging) is increasing to achieve a task, clean and neat integration among these tools brings feature richness to solution offering.

We tend to record events and alarms from the system. We even archive them for many years. Most this information is captured out of systems. But with each event, humans operating systems share and discuss lot of information. Interleaving conversations with system generated events makes up a wealth of information. Further this information can be fed to data mining systems to bring out lot of interesting facts which can be used for improvements, optimizations etc.

This video is from Channel9.

Wonderware: Synchronizing Production, Industrial Operations and Business Objectives

Participants:

Rob McGreevy, Dir. Industry Solutions, Wonderware
Paul Forney, Chief Solutions Architect, Wonderware

Charles Torre, Senior Technical Evangelist at Microsoft

Thursday, June 11, 2009

Regular expressions interleave

Today we had requirement to write regex for domain users and machines. While doing this I expected some scope for succinctness in expression. First I will start with the expression I wrote then I will to succinctness part.

=====================

Regular expression to match hostnames in intranet scenario.

Here requirements are

1) Machine names can contain letter, numbers, underscore or hyphen

2) Names should not start or end with underscore or hyphen

3) labels are tld part follow machine name with an ‘.’ in between.

4) Further on labels may follow same format as machine name.

5) Every label follows with a dot

6) tld is just com

^[A-Za-z0-9][A-Za-z0-9-_]+[A-Za-z0-9].([A-Za-z0-9][A-Za-z0-9-_]+[A-Za-z0-9].){1,3}(comCOM){1}$

Here the special requirement is have a configurable number of labels.

With a minor change similar expression can be used to match Fully Qualified Domain Name for usernames and email addresses also.

^[A-Za-z0-9][A-Za-z0-9-_]+.[A-Za-z0-9-_]+[A-Za-z0-9]@([A-Za-z0-9][A-Za-z0-9-_]+[A-Za-z0-9].){1,3}(comCOM){1}$

Now coming to little bit of explanation.

^ : start of the string; [A-Za-z0-9] : must start with a character or numeric avoid hyphen or underscore; and rest of the expression is self explanatory.

=====================

With that I am curious to know about possible ways of writing expressions with interleave characters with specifiable multiplicity.

I know that is very confusing statement. Sorry I am very poor in expressing in short and crisp sentence.

What I mean here is these expressions can be looked at as

<character set>.<character set>@<character set>.<com>. Here dot and @ are mere interleaves for character sets. They hold restrictions like they can not placed at beginning and ending of character sets. That mean they are always interleaved.

Now I am want know possible means of specifying such interleaves with a language syntax. Also I should be able to specify multiply within a definable part of expression. For example I can allow only 1 dot before @ and that must be interleaved within valid character sets.

So I wish to express this expression as ^[A-Za-z]<interleave([0-9]+[.])>@([A-Za-z]<interleave([0-9]+)>.) {1,3}(comCOM){1}$

Requesting gurus of regular expressions to help me in case such a feature is available ?

Thursday, June 04, 2009

Google Wave – waawhhh

It is just more than five years since google started email service. I using it from those early days.

But from what I understood from upcoming “Google Wave” its is going to redefine the way that we will be looking at all those online services like mail, chat, blog, album, video share, microblog, shared documents etc…

Based on federation services as defined by google as www.waveprotocol.org this is going to create a revolution.

Here are few options that I am just dying to try once I get access

a) replay options

b) model based context oriented spell check

c) collaborative document with diff marks

d) and cool picture drop down (I don’t mind using bits from gears till html 5 makes the feature default in browsers)

e) kind of live transfer letter by letter. I just can’t image how that would show up in low bandwidth networks

f) Inline reply

g) kind of editing features

what else to mention, each and every feature demonstrated there.

Just can’t wait any longer…..

Monday, June 01, 2009

Bing is up and ready

New Microsoft search engine Bing is up and running. It is decision search engine. Check it out. Performance is just like Google. Yet Yet to check on relevance of content. I searched my name and found similar results as Google search. I am going to use this as primary search engine for next few days

image

ASP.Net AjaxControl Toolkit update

This is quite late information but could be useful. ASP.Net Ajax control toolkit is updated with three new controls.

Now we don’t need to depend on FreeTextBox kind of controls for Html WYSIWYG (What-You-See-Is-What-You-Get) editors.

Then an extender on textbox can get windows like combo box with advanced options like enter and append to filter etc.

Then we get a built-in color picker. Personally I am no so impressed with this, but it is now available. Find link here

AJAX Control Toolkit (May 2009 Release)

Thursday, May 14, 2009

Weather modeling or web services aim to conserve power - Narendra Bhandari Intel

This is one of eye opening keynote. Just compiled some of the highlights from my twitter.

How S/W developers code programs has dramatic impact on power consumption in Data centers.

Loop vs Service has big impact on power.

It is time S/W professionals understand hardware chages taking place in hardware side of industry.

Dual Core to Multi Core to Many Core. Wether modelling to webservices everone need to optimise for sake of conserving power.

Visual Adernline, Intel Parallel Studio performance Tools from Intel to take advantage of hardware advances. Most of the tools are developed like VS2010 plug-ins and thus bring lot of value with simplied learning curve.

www.intel.com/go/parallel, www.intel.com/software and Intel Certified Solution Program

tech.ed 2009 Day2. Resul Pookutty's Key note session


Resul Pookutty's Key note session mesmerized everyone there. He is so impressive that session just got extended on and on.

He is so well prepared and organized with content. It is really unique of its kind.

Following is one of the clipping that were played at session. This one is from Oscar winning SDM.

MS-Tech Ed India 2009, Theme Song

Download it here.

Wednesday, May 13, 2009

Microsoft tech.ed 2009 Day1


Exciting first day. We shared pre-registration counter with Infosys.

Unfortunately our ID cards were not printed and thus we had to wait for sometime before we could go in.

Overall administration is not very much appreciable rather I would say they could have lot better.

Steve Ballmer keynote is really a highlight for this event.

I was on twitter through out sessions. 


Here are list of session I attended today
.Net 4.0 Fundamentals - Sanjay Vyas
ASP.Net MVC - Stephen Walther
Best Practices for team based S/W Developmen - Prashant G, Infosys
Architecting & Developing cool apps in this era of Multicore - Rajagopal, Intel

Couple of videos from session. I am sorry for bad quality. 


And I met two of my old colleagues Siddheshwar and Sreejumon at session. Expecting more fun tomorrow. 

TechEd 2009 - Hyderabad

Attending TechEd 2009 - Hyderabad from 13th to 15th May.

Expecting great sessions. Will post updates.

Friday, May 08, 2009

icloud has launched

Xcerion XML internet OS/3. I posted this when I got beta my beta account. It is released last month.

icloud is a service based on the Xcerion Internet Operating System /3 (XIOS/3).

XIOS is the technical solution behind the service. It offers “A free online computer with desktop, applications and storage.”

icloud consists of a desktop with applications and files that you run through your web browser. Because it's running in the cloud (the internet) it can offer you impressive features such as easy sharing and rich collaboration.

Some of the feature include

  • Online storage
  • Productivity
  • Photos, music, videos
  • Internet
  • Application development
  • Utility applications
  •  

    It is available in three forms. Check this link. Also check link for applications made available by default.

    Thursday, May 07, 2009

    Cascading DropDownLists in DetailsView – Databinding error

    I came across a requirement to have linked DropdownLists in insert mode of  DetailsView bound to EntityDataSource.

    In insert mode of DetailsView one of the fields is bound to a dropdownlist’s selected value.  But the requirement here is values of dropdownlist vary depending on where condition bound to selected value of another dropdown list.

     image

    As shown above TaskID is one of the fields. But tasks vary based on project selected. This is achieved by converting TaskField to TemplateField. I have pasted below code for EditTemplate, InsertTemplate and ItemTempalte. In this only TaskID is bound column while project is added manually.

    Without doing modifications shown below I was getting error

    Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.

    This is because upon postback DetailsView control is not re binding to selected value  SelectedValue='<%# Bind("TaskID") %>'

    <asp:TemplateField HeaderText="TaskID" SortExpression="TaskID">

    <
    EditItemTemplate>
    <
    asp:Label ID="Label3" runat="server" Text='<%# Eval("TaskID") %>'></asp:Label>
    </
    EditItemTemplate>

    <
    InsertItemTemplate>
    <
    asp:DropDownList ID="DropDownList5" runat="server" AutoPostBack="True"
    DataSourceID="EntityDataSource5" DataTextField="ProjectName"
    DataValueField="ProjectID" Width="100%">
    </
    asp:DropDownList>
    <
    asp:EntityDataSource ID="EntityDataSource5" runat="server"
    ConnectionString="name=MyEntities" include="Tasks"
    DefaultContainerName="MyEntities" EntitySetName="Projects">
    </asp:EntityDataSource>
    <
    br />
    <
    asp:DropDownList ID="DropDownList4" runat="server"
    DataSourceID="EntityDataSource6" DataTextField="TaskDescription"
    DataValueField="TaskID" Width="100%">
    </
    asp:DropDownList>
    <
    asp:EntityDataSource ID="EntityDataSource6" runat="server"
    ConnectionString="name=MyEntities"
    DefaultContainerName="MyEntities" EntitySetName="Tasks"
    Where="it.ProjectID==@ProjectID" >
    <
    WhereParameters
    >
    <
    asp:ControlParameter ControlID="DropDownList5" Name
    ="ProjectID"
    Type="Int32" PropertyName
    ="SelectedValue" />
    </
    WhereParameters
    >
    </
    asp:EntityDataSource>
    </
    InsertItemTemplate>

    <
    ItemTemplate>
    <
    asp:Label ID="Label3" runat="server" Text='<%# Bind("TaskID") %>'></asp:Label>
    </
    ItemTemplate>

    </
    asp:TemplateField>

    Also observe highlighted portions where autopostback is set for project dropdownlist and its selectedvalue is bound to DetailsView in where condition of Tasks Dropdownlist. But here TaskID selected value is not bound to TaskID field of DetailsView.

    This binding is made in OnItemInserting event handler of DetailsView as shown below

    <asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" CellPadding="4"
    DataKeyNames="ResourceID" DataSourceID="EntityDataSource2" ForeColor="#333333"
    GridLines="None" Height="50px" Width="125px" OnItemInserted="DetailsView1_ItemInserted"
    DefaultMode="Insert" OnItemInserting="DetailsView1_OnItemInserting">

    with page behind file containing handler like

    protected void DetailsView1_OnItemInserting(object sender, DetailsViewInsertEventArgs e)
    {
    String TaskID = ((DropDownList)(DetailsView1.FindControl("DropDownList4"))).SelectedValue;
    e.Values.Add("TaskID", TaskID);
    }

    Here inserting event is handled to add TaskID field to values based on selected value of TaskID’s DropDownlist.

    Primary and Unique keys

    Today one of my colleagues expressed difficulty in ensuring uniqueness for certain columns in a table.

    Characteristics of these columns are

    1. There are not necessary (allow-null) columns for inserting a row in a table in which they are defined
    2. But when inserted they must form a unique combination

    What could have been done so easily with Unique Key became so difficult because of lack of referential integrity.

    These columns could have been defined in a different table and referenced with a foreign  key relationship to primary table.

    Such a simple thing could not be corrected as we are so tightly coupled with its structure. Awful! a classic example of making life miserable by knowingly living with self made mistakes.

    Tuesday, May 05, 2009

    Built-in functions of Transact-SQL

    Many a times, we end up spending lot of time doing something that made available to us just due to lack of awareness.

    Today I spent 30 minutes to get date as string from datetime column in database. Doing this from code is quite a trivial task.

    But here I want to bind a source to UI control. DATENAME function solved my problem just like that. It is built-in function of SQL.

    Here are some more references for built-in functions from MSDN

    Functions (Transact-SQL)

    Monday, May 04, 2009

    Wild west stunt show in Ramoji Film City

    Ramoji Film City, the largest film studio complex in the world as certified by Guinness World Records, is an ultimate leisure destination for holidays in Hyderabad. Following photograph taken before the start of the show. It is just a part of complete set.

    This particular show is so realistic and really makes you watch again and again.

    IMG008

    MSDN for low bandwidth

    Low bandwidth option of MSDN is really worth giving a try. Its much better than regular one.

    Find some of the low bandwidth options for MSDN.

    Low bandwidth

    http://msdn.microsoft.com/en-us/library/system.collections.arraylist(loband).aspx

    This option is really good.

     

    Mobile/PDA

    http://msdn.microsoft.com/en-us/library/system.collections.arraylist(pda).aspx

    Not quite there. Option to choose language is desired.

     

    Printer-friendly

    http://msdn.microsoft.com/en-us/library/system.collections.arraylist(printer).aspx

    Familiar one. But not so inviting

     

    MSDN Inside the (IDE)

    http://msdn.microsoft.com/en-us/library/system.collections.arraylist(ide).aspx

    Useful, though can’t understand why feedback banner hides content at top. MSDN folks to correct this.

    Friday, May 01, 2009

    Using Set operations (SQL) to detect differences between two tables

    Identifying differences between two tables can become quite a daunting task.

    Using SQL set operations like {UNION,INTERSECT,EXCEPT} can greatly simply this is process.

    Any attempt to use compare operations on .Net runtime turns out to be very costly affair for these operations.

     

    I tried creating a set operations. Here my intention is to pass two tables which share same schema, then pass on ID field which

    is anchor. This results a single table specifying Addedd/Changed/Deleted/UnChanged records. That makes whole set.

    SELECT t1.*, 'Added'FROMTable1 t1
    LEFT JOINTable2 t2 ONt1.ID = t2.ID
    WHEREt2.ID IS NULL

    union

    SELECT
    t1.*,'Changed'
    FROMTable1 t1
    INNER JOINTable2 t2 ONt1.ID = t2.ID
    except
    SELECT
    t2.*,'Changed'
    FROMTable1 t1
    INNER JOINTable2 t2 ONt1.ID = t2.ID

    union

    SELECT
    t2.*, 'Deleted'
    FROMTable1 t1
    RIGHT JOINTable2 t2 ONt1.ID = t2.ID
    WHEREt1.ID IS NULL

    union

    SELECT
    t1.*,'UnChanged'
    FROMTable1 t1
    INNER JOINTable2 t2 ONt1.ID = t2.ID
    INTERSECT
    SELECT
    t2.*,'UnChanged'
    FROMTable1 t1
    INNER JOINTable2 t2 ONt1.ID = t2.ID

    ORDER BY XX

    I tried this with two tables each having 100 columns and 5000 rows. I could detect above mentioned changes like Added/Changed/Deleted/UnChanged within 18 seconds.

    Thus I believe set operations can offer much cleaner and simpler solution in such scenarios.

    Monday, April 27, 2009

    A Self-confessed Slave

    Source

    “For people who are stupid, we say that they lack a brain. Figuratively, we associate a condition with an organ and say that that organ is missing. So if someone is weak and pliable, we say that they lack a spine or a backbone. Someone cruel and inhuman, we refer to as heartless. With the lack of courage, we associate gutlessness. Emasculation has obvious connections. So I was wondering: which organ or part of the body is there an association with ethics? If someone lacks all sense of morality and ethics, what part of the body are they missing?”

    Though the context of original article is different, these words carry much broader meaning.

    In my sense dealing with a cruel person is far easier than dealing with unethical person. Moral consciousness is the ability by means of which we perceive what is good and what is bad. In my opinion those who lack sense of morality are deaf and those who lack ethics are blind.

    We we are placed in a situation to judge based on arguments from either side we are expected to show morality. That is why I feel lack of morality is like being deaf.

    Similarly ethics are intangible. They are just perceived. But only those with an eye can perceive them. Thus in my opinion those who lack ethics are blind.

    Friday, April 17, 2009

    Project task types

    Often I get confused about kind of task to pickup while adding tasks in project. More than confusion it is like self-contradiction.

    Today I thought of making my own notes about ‘Fixed Type’, ‘Fixed Duration’, Fixed Work’ kind of tasks with “Effort Driven” option. This is very much subjective in nature and differs in different contexts.  But having a context as a reference can help making better judgment.

    Fixed Units

    Let us assume a scenario

    Need following kind of resources to perform a task
    1) Architect - 1 - 50%
    2) Development Lead - 1 - 100%
    3) Full-time developers - 2 - 100%
    4) Test Lead - 1 - 100%
    5) Full-time testers - 2 - 100%
    6) Tech writer - 1 - 50%
    7) Designer - 1    - 25%

    Initial estimate to complete this task is 10 days.

    After 4 days, team realizes that it actually takes 2 additional days(total of 12 days) to complete the task.

    Without "effort driven" option
    All resources will be charged for 12 days as per units (%), thus increasing cost of the task. Even adding additional resources will not help in completing task within 10 days.

    With "effort driven" option
    There is a possibility to add resources in order to complete task within 10 days. However the total cost of the task will be same as above.

    These are such tasks where we hard-lock resources and monitor duration. As task progresses and understanding of task improves, "effort driven" option can be exercised to meet schedules by adding more resources. But this is not commonly practiced for this kind of tasks.

    Summary

    Here cost of task and duration(within permissible period) is dynamic but resource availability is constrained. Normally core team is assigned with Fixed unit kind of tasks.

    Fixed Work

    In this mode "Effort Driven" option is default and can not be changed.


    These are such types of tasks where know-how is well known but resource availability is not fixed. Moreover these type of tasks can span across comfortable durations. If target date gets postponed, resources become free accordingly. For some reason if work-effort increases or work-units reduce, duration increases accordingly.

    Summary

    Here cost of task is fixed but duration is dynamic (within acceptable period). Duration can be minimized based on resource availability.

    Fixed duration

    These are time constrained tasks. Where we start with experts and try to demystify complications as soon as possible. Then exercise "Effort Driven" option to meet target dates by adding additional resources.

    Summary

    Here duration is fixed but cost and resources are not constrained. Theses are like “support” kind of tasks where business continuity is involved.

    Wednesday, April 15, 2009

    Know your polling station

    If you are in Cyberabad region, you can get to know the location of polling station at
    http://www.cyberabadpolice.gov.in/knowyourpolicestation/pollingstations/

    First get your polling station number from http://ceoandhra.nic.in/Final_erolls_2009_II.html then check for polling station number under police station from above site.

    Looking for route is a bit tedious task, but the image resolution is good enough. You can zoom in and check for Route number and polling station number

    Excellent work done by Cyberabad police.

    Tuesday, April 14, 2009

    ABB Opens New Automation Products Plant In India

    Source

    ABB has inaugurated its green field automation products facility near Bangalore, India, to manufacture automation products.

    Spread over 18 acres, the factory will manufacture products such as air circuit breakers, switch fuse units, molded-case circuit breakers, low- and medium-voltage drives and systems, high-power rectifiers, static excitation systems and main and auxiliary traction converters, among others.

    Commending ABB’s growth in the last six to seven years, Sjoekvist notes that the virtual debt-free status and a healthy order backlog will help ABB tide over the global economic crisis. “Improving energy efficiency and focus on renewable energy were key factors in adding value,” he says

    What Went Wrong Ethically in the Economic Collapse

    Source

    “Shoo. You can’t attend this meeting. We are going to discuss things here that you will tell me I shouldn’t do. I don’t want that on the record and you can’t stop me.”

    ABB will enhance productivity at BMW

    Source

    ABB has signed a frame agreement with BMW Group to deliver 2,100 industrial robots over five years, beginning in 2010

    The robots will be applied in parts handling, gluing and spot welding on car-body assembly lines for BMW's 1-series, 3-series, X5-series and Mini models.

    Tuesday, April 07, 2009

    GMail is 5 year old

    On April 2 GMail turned 5. I switched to GMail on 8/30/04. Since then it is serving as my primary web mail ID.

    When I started it offered me 1 GB free space and on today it offers 7GB+. I still trying catching up my 1 GB.

    GMail made possible easy to archive and label. Also kind of never delete a mail is a reality now.

    Search within mail is awesome. Stars, filters, key short cuts. More to that it offers authentication to blogger and many other services. One feature that I feel like having is auto archive the ones that are labeled after configured time span.

    Anyway it wonderful journey with GMail so far and I assume that GMail will stay for ever and ever.

    MOSS 2007 designer is free now

    https://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=baa3ad86-bfc1-4bd4-9812-d9e710d44f42

     

    Starting from April 01 Microsoft is offering MOSS2007 designer free.

    Wednesday, April 01, 2009

    Getting default browser’s path

    Following registry keys hold default browser’s application path

    1. HKEY_CLASSES_ROOT\http\shell\open\command

    2. HKEY_LOCAL_MACHINE\SOFTWARE\Classes\http\shell\open\command

    As expected there is no consistency here. We tested following browsers

    1. Microsoft Internet Explorer 8.0.6001.18702
    2. Mozilla Firefox 3.0.7
    3. Google Chrome 1.0.154.53
    4. Opera 9.63
    5. Apple Safari 3.2.1 (525.27.1)

    First options works for all browsers except Safari. Second option is not very much recommended. Following code snippet extracts browser path from open command.

    using System.Text.RegularExpressions;
    using Microsoft.Win32;
    RegistryKey regKey = Registry.ClassesRoot.OpenSubKey(@"\http\shell\open\command");
    string[] valnames = regKey.GetValueNames();
    string val0 = (string)regKey.GetValue(valnames[0]);
    Regex regex = new Regex("[\\w\\W\\d]*.exe\"",RegexOptions.IgnoreCase);
    Match match = regex.Match(val0);
    MessageBox.Show(match.Value);

    Top quality teamwork tips

    Quoted from

    Mastering the Art of Teams and Team-Building: 10 Tips for Top-Quality Teamwork by Randall S. Hansen, Ph.D.

    http://www.quintcareers.com/printable/top_quality_teamwork_tips.html

     

    Working in teams is inevitable. For years now, organizational leaders have recognized the added value that comes from having employees work in formal or informal teams, but over the last two decades even greater emphasis has been placed on work teams. Several studies indicate that more than 80 percent of organizations employ multiple types of workplace teams.

    Team-building and teamwork skills are essential in the workplace and highly desirable skills to possess when seeking a new job or promotion. Teams working at their potential generate more productivity and better solutions than if all the individual members had worked independently.

    How can you be a better team member? How can you get your team to work more effectively as a team? How can you lead your team to success? Here are 10 tips for creating better teams.

    1. Foster Open Communications. The best teams are those in which every member shares their thoughts and opinions with the group, and where decision-making is based on dialogue and not dictatorship. But open communication is not just about having an atmosphere in which people can talk freely -- it's also about team members listening to each other and valuing each other's opinions. If your team lacks open communications, bring it up at your next team meeting.

    2. Build Trust. Trust is the cornerstone of all effective teams. Without trust, there really is no team, just a collection of individuals working together. Teams need to develop to a point where every member trusts that every other member will do the work required and be an active member of the team. One of the trendy methods of trust-building is having team participate in a ropes-challenge course, where teams work together to solve problems.

    3. Set Clear Goals. A team without specific goals will not nearly be as effective as a team with goals. Goals should be specific, including a deadline for completion. But goals should not necessarily always come from the leader of the team; all goals should be discussed by the entire team, especially in situations in which deadlines will be tight.

    4. Review Progress. Once goals have been set, the team frequently goes off to complete all the tasks to achieve its goal. This scenario is perfectly fine, except that in too many instances, new information or actions can affect the goal's completion. Thus, teams benefit from conducting regular check-ins with all team members -- perhaps something as often as weekly -- to review progress and iron out any wrinkles or overcome obstacles that have arisen.

    5. Encourage Cooperation, not Competition. Despite being placed in teams with co-workers competing with you for your next promotion, you must find a way to collaborate with every member of the team. One of the worst labels in the workplace is that of “not being a team player.” You will be plenty of time to showcase your personal accomplishments, but without your cooperation, your team may not succeed. Collaboration is a must.

    6. Focus on Professionalism. The reality of life is that we all have certain types of personalities that clash with our own, but for teams to work, you have to put aside these petty differences and focus on the positive aspects of all team members. Remember that you are not forging lifelong friendships with your team, you simply need to work together to achieve your goals. Downplay people's negative traits and focus on their positives – just as they will yours.

    7. Celebrate Differences/Diversity. One of the best trends in society, as well as the workplace, has been a growing diversity of people -- by race, ethnicity, gender, and age. Diversity introduces new ways of thinking and leads to new ideas and better decisions. Rather than feeling uncomfortable that most of the team does not look or act like you, celebrate their individual differences and the value that each brings to the team.

    8. Be Enthusiastic. Even if you generally prefer to work by yourself, the reality you are face is that teams in the workplace are here to stay. One way to make the best of the situation is to jump into the team experience with as much enthusiasm as possible. Enthusiasm is contagious, so not only will your enthusiasm help you feel better about being a team member, it will lead other team members to also become more enthusiastic.

    9. Share the Work/Do the Work. The best teams are those in which each member plays a vital part in work that results in superior performance; thus it is imperative that each member not only feels he or she plays a vital role, but actually does so. But sharing the work is only part of the equation. The other part is that once the work has been assigned, each team member must be accountable to complete the tasks. Much as been written about the “free-rider” problem within teams, but with individual accountability within the team, people cannot hide from their team responsibilities.

    10. Clarify Responsibilities to the Team. Often one of the main causes of team members not completing their work is not because they are “slackers,” but because they simply do not understand their role on the team -- or the importance that their work will lend to the team. The key here is that each team member must totally understand his or her role on the team and responsibility to the team so the team can succeed.

    Final Thoughts
    Your work life will include individual and team projects and assignments, and as you move up the organization, the importance of working well in teams -- and leading teams to success -- will gain more and more value. If you take these 10 tips to heart, your satisfaction with teamwork and your performance on the team will improve greatly.

    Thursday, March 26, 2009

    Fxcop stylesheet

    For some reason FxCop still points to a stylesheet from gotdotnet which is broken.

    Today we had a requirement to generate static code analysis report in a simple tabular form.

    Following snippet did the job. You can apply any css on this for better look. Or even set style for table, tr and td.

    <?xml version="1.0"?>
    <
    xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <
    xsl:template match="/">
    <
    html>
    <
    body >
    <
    table>
    <
    xsl:for-each select="//Issue">
    <
    tr>
    <
    td><xsl:value-of select="@Certainty"/></td>
    <
    td><xsl:value-of select="@File"/></td>
    <
    td><xsl:value-of select="@Line"/></td>
    <
    td><xsl:value-of select="../@FixCategory"/></td>
    <
    td><xsl:value-of select="@Level"/></td>
    <
    td><xsl:value-of select="."/></td>
    </
    tr>
    </
    xsl:for-each>
    </
    table>
    </
    body>
    </
    html>
    </
    xsl:template>
    </
    xsl:stylesheet>

    Just thought of sharing it.

    Monday, March 23, 2009

    Program Files folder in X64

    While qualifying one of our projects for X64, we encountered issue with Program Files folder.

    We use Wix for building msi package.

    Wix could get %PROGRAMFILES% variable from OS and place files appropriately at C:\Program Files (x86)\

    But our product was looking at C:\Program Files.

    I prefer picking up any paths from app.config files and delegate task to Wix to update application specific configuration files during installation. This makes life so simple when moving between x86 and x64.

    Here I am referring to running x86 stuff as is on x64. Rules change when we compile code for X64.

    Friday, March 20, 2009

    Internet Explorer 8 Released

    Microsoft Released Internet Explorer 8 today. Its app 17 MB download and took 8 minutes to install.

    And recommends to restart system after reboot. Compatibility mode, developer tools, quick search in address bar are few impressive things. Private browsing is just like any other new age browser feature. It is supported on

    Find release notes at http://msdn.microsoft.com/en-us/ie/dd441788.aspx

    Java 6 update 11 is recommended version for viewing Java Applets.

    Sunday, March 15, 2009

    Clickonce installer with example

    Smartclient is a nice concept for occasionally connected applications. A windows forms application or a WPF application can be made available for easy deployment from a webserver, file share etc.. Not only that it can also serve as an update server too.

    Though Wix ClickThrough is another concept for similar use, both got unique advantages. And I feel clickonce is the option for today while and clickthrough is evolving.

    In this post I would like describe some of the basic concepts of clickonce. I feel this would be useful for anyone starting with clickonce. Let us start with a bit basic theory then move on to infrastructure required to do this and then to an example.

    Concept

    The core ClickOnce deployment architecture is based on two XML manifest files –Application manifest and Deployment manifest.

    The application manifest describes the application itself, including the assemblies, the dependencies and files that make up the application, the required permissions, and the location where updates will be available.

    The deployment manifest describes how the application is deployed, including the location of the application manifest, and the version of the application that clients should run.

    Following diagram shows how versions will be maintained in webserver. Each version will have its own Application Manifest file.

    At any time deployment manifest points to one of the versions. Deployment manifest contains an URI which client tries to access from web browser. Click once infrastructure sends pointed version to client. If client contains that version previously then download doesn’t takes place, rather application is launched in client. Else assemblies of that version will be copied to client.

    image

    In Client each version is stored in separate directory in application cache which is typically at “C:\Documents and Settings\username\Local Settings\Apps\2.0\<xx>”. In addition click once application gets added to add/remove programs (if install option  is selected in deployment manifest). In such case application automatically gets added to start menu also. Applications also run under Code Access Security purview. By default click once application gets deployed with Full trust permissions. However this can be tuned in application manifest.

    Also click once applications can be updated automatically. Assume that client has 1.0.0.0 version installed. Click once applications can be configured to check for new updates during start up (Other options are also available like, after start up, periodically etc.). During start up if application detects if deployment manifest is pointing to new version. If so then it prompts user to update to new version. If user prefers to update new version is downloaded and made as default version. Incase user is not comfortable with updated version, he or she can prefer to un-install latest update and rollback to previous version. This roll back can be done as many times till lower version is available.

    In case of large applications downloading entire application in one lot may not be very much acceptable. For such scenarios click once offers optional group mechanism. With this initial download happens for required assemblies only. Options groups will be downloaded on demand.

    With this background let us move to infrastructure needed for this.

    Infrastructure

    Click expects .Net 3.0 to be available in target applications. If your application depends on higher version of  .Net framework, then that becomes as necessary pre-requisite. Pre-requisites can be handled using bootstrapper. I will not cover bootstrap here. Let us assume required .Net framework version is available in client machine.

    As mentioned above clickonce installation is nothing but “target assemblies + application manifest” + “deployment manifest”. Assemblies are built by developer. Then manifests can be built using mage.exe or mageui.exe. This is part of Windows SDK. Thus if you have Visual Studio 2005/2008 installed on your machine then you have both of these tools.

    Apart from these developer also needs a “Personal Information Exchange (.pfx)” file to sign manifests. Signing manifests is mandatory. You may find this post useful to create a pfx file.

    Thus to summaries this section. We need following set of files to create click once installation setup

    1. Application assemblies
    2. Personal Information Exchange File (pfx)
    3. mege.exe or mageUI.exe

    Now let us start on example.

    Example 1 - Basic

    Let us take a forms application. As a first step let us try to create a clickonce installation setup for this forms application.

    Just start Visual Studio and create a forms application by name “MyWebForm”. Just change Form title to “MyWebForm”. That is it nothing else. Build Release version. So MyWebFormApp.exe is the only file we want to create clickonce installation setup.

    In IIS create a virtual directory by name MyWebForm. Under that create a subdirectory by name “1.0.0.0”. And copy MyWebFormApp.exe  to that folder.

    image

    Now start mageui.exe from “C:\Program Files\Microsoft SDKs\Windows\<v6.0A>\Bin\”.

    Create application manifest

    image

    1. Click on File – > New – > Application Manifest
    2. Enter Name as MyWebFormApp
    3. Enter version as 1.0.0.0
    4. Select ‘Files’ from list box then select application directory. In this case it is “C:\Inetpub\wwwroot\MyWebForm\1.0.0.0”
    5. Click on populate.
    6. Then save manifest to folder 1.0.0.0 as “MyWebFormApp.exe.manifest”. MageUI prompts to sign application before saving. Select pfx file and click on save.

     

    Create deployment manifest

    image

    1. Click on File – > New – > Deployment Manifest
    2. Enter Name as MyWebFormApp
    3. Enter version as 1.0.0.0
    4. Select ‘Description’ from list box enter product name
    5. Select ‘Deployment Options’ from list box enter start location as “http://<webserver>/MyWebForm/MyWebForm.application”
    6. Select ‘Update Options’ from listbox and check on “Before Application Starts”
    7. Select ‘Application Reference’ from listbox and click on ‘Select Manifest’
    8. Select “MyWebFormApp.exe.manifest” from “C:\Inetpub\wwwroot\MyWebForm\1.0.0.0\” folder
    9. Then save manifest to folder “C:\Inetpub\wwwroot\MyWebForm\” as “MyWebForm.application”. MageUI prompts to sign application before saving. Select pfx file and click on save.

    Installing first version

    Open browser and browse to “http://<webserver>/MyWebForm/MyWebForm.application”

    A window pops us prompting to install. Click on install. Application starts automatically and form is shown

    You can also observe a new start menu short cut and an entry in Add/Remove programs.

     

    So that is quite simple. Now let us add an optional package.

    Example 2 – Optional group

    Before we proceed uninstall application installed in last step from Add/Remove programs.

    Add another project

    Now let us create another form project to solution file by name “MyWebFormOptional1”.

    Add reference of this project to main project.

    Also add a button to main form MyWebFormApp. In button click event add code to launch second form.

            private void button1_Click(object sender, EventArgs e)
    {
    MyOptionalForm1 opt1 = new MyOptionalForm1();
    opt1.ShowDialog();
    }




    Update code to Dynamically load assembly



    Idea here is to make MyWebFormOptional1 as optional group. Thus when click once application is downloaded first time only MyWebFormApp gets downloaded. Upon clicking on button “MyWebFormOptional1.exe” gets downloaded.



    In order to this we use Application.LoadFile method. Copy paste following code in MyWebForm.cs



    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    using System.Reflection;
    using System.Deployment.Application;
    using System.Security.Permissions;
    using System.IO;
    using MyWebFormOptional1;

    namespace MyWebFormApp
    {
    public partial class MyWebForm : Form
    {
    Dictionary<String, String> DllMapping = new Dictionary<String, String>();

    [SecurityPermission(SecurityAction.Demand, ControlAppDomain = true)]
    public MyWebForm()
    {
    InitializeComponent();

    DllMapping["MyWebFormOptional1"] = "MyWebFormOptional1";
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    }


    /// <summary>
    /// Use ClickOnce APIs to download the assembly on demand.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
    Assembly newAssembly = null;

    if (ApplicationDeployment.IsNetworkDeployed)
    {
    ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;

    //MessageBox.Show(args.Name);

    // Get the assembly name from the Name argument.
    string[] nameParts = args.Name.Split(',');
    string assemblyName = nameParts[0];
    string downloadGroupName = DllMapping[assemblyName];

    try
    {
    deploy.DownloadFileGroup(downloadGroupName);
    }
    catch (DeploymentException de)
    {
    MessageBox.Show("Downloading file group failed. Group name: " + downloadGroupName + "; Assembly name: " + args.Name);
    throw (de);
    }

    // Load the assembly.
    // Assembly.Load() doesn't work here, as the previous failure to load the assembly
    // is cached by the CLR. LoadFrom() is not recommended. Use LoadFile() instead.
    try
    {
    if (File.Exists(Application.StartupPath + @"\" + assemblyName + ".exe"))
    newAssembly = Assembly.LoadFile(Application.StartupPath + @"\" + assemblyName + ".exe");
    else if (File.Exists(Application.StartupPath + @"\" + assemblyName + ".dll"))
    newAssembly = Assembly.LoadFile(Application.StartupPath + @"\" + assemblyName + ".dll");

    }
    catch (Exception e)
    {
    throw (e);
    }
    }
    else
    {
    //Major error - not running under ClickOnce, but missing assembly. Don't know how to recover.
    throw (new Exception("Cannot load assemblies dynamically - application is not deployed using ClickOnce."));
    }


    return (newAssembly);
    }

    private void button1_Click(object sender, EventArgs e)
    {
    MyOptionalForm1 opt1 = new MyOptionalForm1();
    opt1.ShowDialog();
    }
    }
    }


    Build application and copy MyWebFormApp.exe and MyWebFormOptional1.exe to 1.0.0.0 folder.



    Update Application manifest



    Open MyWebFormApp.exe.manifest file from 1.0.0.0 folder in MageUI.exe.



    Select ‘Files’ from list box then populate files again. Now “MyWebFormOptional1.exe ” gets added.



    Click on checkbox to select this file as optional. And enter “MyWebFormOptional1” as group. Save application manifest.



    Update deployment manifest



    Then open deployment manifest. Select ‘Application Reference’ from listbox and click on ‘Select Manifest’. Select same manifest again and save manifest once again.



    Installing second version




    1. Open browser and browse to “http://<webserver>/MyWebForm/MyWebForm.application”


    2. A window pops us prompting to install. Click on install. Application starts automatically and form is shown


    3. Now open application cache at C:\Documents and Settings\username\Local Settings\Apps\2.0\<xx>” and observe that only MyWebFormApp.exe is downloaded.


    4. Now click on button to open MyWebFormOptional1. Window opens.


    5. Again check application cache. This time observe that application downloads second form automatically.



    Example 3 – Update



    Now let us target on auto updating application to new version. Don’t un-install previous application.




    1. Create a new folder under C:\Inetpub\wwwroot\MyWebForm\ as 1.0.1.0


    2. Update AssemblyInfo.cs file in solution for both project as

      [assembly: AssemblyVersion("1.0.1.0")]


      [assembly: AssemblyFileVersion("1.0.1.0")]


    3. Build application and copy MyWebFormApp.exe and MyWebFormOptional1.exe to 1.0.1.0 folder.


    4. Create Application manifest. But ensure to set version as 1.0.1.0 and also files are populated from 1.0.1.0 folder


    5. Update deployment manifest by selecting manifest from 1.0.1.0 folder in “Application Reference” pane.



    Now launch application from start menu. This time user will be prompted with following dialog.



    image



     



    Hope you found this post useful.

    Saturday, March 14, 2009

    Experts Exchange subscription

    Online forums are always helpful. But sometimes you end up with paid solutions like experts exchange to get a more closure solution. During last year I was in similar situation and paid for a premium service for a month. And I used my credit card to pay it.

    But unfortunately EE stored my cc details and charged my card every month since then. As it is small amount it went un-noticed.

    Today I just cancelled. I am sure there is no where I selected for a recurring payment on monthly basis. Be watchful about EE.

    Monday, March 09, 2009

    Find and replace a pattern using VIM

    In recent past I am not using shell scripts and thus lost touch with powerful search replace options for patters.

    As Windows Find replace options doesn’t support much of regex stuff, I resorted to VIM.

    My intention to fix an XML file in structured format.

    I have an xml file with elements like following (it is just a snippet of big file)

    <PolicyNo>012345678</PolicyNo>
    <DateOfCommencement>03DEC1983</DateOfCommencement>
    <Plan_Term>579-60</Plan_Term>
    <SumAssured>2,00,000</SumAssured>
    <GrievanceRedressalOfficer>011-57293184</GrievanceRedressalOfficer>

    And I wanted it in the format of

    <DataPoint PolicyNo=”012345678”></DataPoint>
    <DataPoint DateOfCommencement=”03DEC1983”></DataPoint>
    <DataPoint Plan_Term=”579-60”</DataPoint>
    <DataPoint SumAssured=”2,00,000”></DataPoint>
    <DataPoint GrievanceRedressalOfficer=”011-57293184”</DataPoint>

    Following expression did the trick. I got to tweak second back reference little a bit for different cases where non special characters are present.

    And I could also prefix line numbers to confine operations to limited set of lines

    like

    :9,26s…..

    :s/<\(\w\+\)>\(.\+\)<\/\(\w\+\)>/<Detail \1=”\2”><\/Detail>/gc

    As usual this is a simple search replace syntax in the format of :s/<find string>/<replace string>/<options in this case gc>

    Here find string is formatted as

    1. starting with ‘<’
    2. start of first back reference \(
    3. word of one of more length \w\+
    4. close of first back reference \)
    5. ending with ‘>’
    6. start of second back reference <\
    7. characters repeated till character ‘<’. I changed this for few lines
    8. escape for close charcter ‘/’
    9. closing tag. Though this is need not be back reference. I just did it
    10. ending with >

    Now replace string is

    1. “<Detail “
    2. First back reference \1
    3. followed by ‘=’
    4. followed by opening quotes “
    5. second back reference ‘\2’
    6. followed by closing quotes ‘”’
    7. Closing tag syntax.

    And the options include

    g – all occurrences in a line

    c – seek confirmation

    Following links might be useful

    VIM Regular Expressions

    And my favorite regex site Regular Expressions Reference

    Monday, February 16, 2009

    What can you do?

    Sometimes we tend to find questions rather than finding answers to questions. We tend do that to introspect ourselves.

    But what do we really intend to do with those questions? Are we supposed to find answers for them? Actually NO, I mean not for all of them.  Then, why should we collect those questions? Because we want a change the course of life. How can we do that?

    According to philosophers, answers are required to execute something but questions are required to change the execution.

    Right, next time when something bothers you, formulate a question out of it and add it your collection. Probably when you revisit your collection you may get a clue for a change that you can bring in your life.

    Sample what can you do collection goes like this…

    What can you do when you are

    • being consumed?
    • being concealed?
    • not assigned any specific goals?
    • asked to work for goals that are not yours?
    • not allowed to act to your ability?
    • not allowed to be creative?
    • being manipulated?
    • not assessed?
    • deprived of opportunities?
    • expected to operate without any motivation?
    • asked to manage as proxy rather than as a delegate?

    Sunday, February 15, 2009

    Office Communicator Mobile 2007 R2

    Today I installed OCM 2007 R2 on my mobile. I guess my organization hosts OCM 2007 server not R2. But earlier I was not able to connect to server using server specified configuration. But with OCM 2007’s Auto configuration feature it just connects in 10 seconds and brings status of contact quickly. I even tried sending couple of messages. I use Asus P320, Windows Mobile 6.1 Professional. This is very useful for Windows mobile users.

    Visual Studio 2010 to include Wix 3.0

    We are using beta version of wix. Though it offers everything that is needed at this moment; we are waiting for Wix 3.0 just to be with release product. According to this post Wix 3.0 will be included in VS2010.

    Its a really tool for installation needs where module developers can have closure interaction with packaging team.

    And for exclusive packaging teams promising way ahead is Wix.

    Sunday, February 08, 2009

    Web mail services – who is winning

    Gmail user base grew 39%, from 18.8 million to 26 million between September 2007 and September 2008 period.

    During the same period, Windows Live Hotmail dropped 4% 46.2 million to 44.6 million.

    Yahoo continues to lead at 11% growth rate with 91.9 million visitors in December 2008.

    Monday, February 02, 2009

    Parsing comma separated files (csv) in C#

    Parsing a comma separated file. This task sounded so simple for this till the time I received couple of bugs.

    Initially I attempted with a simple approach as shown below.

            using (StreamReader csvFile = new StreamReader(filePath, Encoding.Default))
    {
    //First line must contain columns
    string csvHeader = csvFile.ReadLine();

    //Comma seperated values
    csvColumns.InsertRange(0, csvHeader.Split(','));
    }

    Due to these bugs I educated myself about rules of CSV. I can quote couple of references here.

    Wiki Comma-separated values and CSV standard.

    Important point to note here is that each value in CSV can contain a comma or newline or quotes embedded in itself.

    This simple point changes rules of games very much. Normal stream operations to read line are of no use here. As well split functions are of no use. So only option left out is to parse byte by byte watching for characters to skip and add.

    Here is the code using which I managed to parse a Csv and resolved bugs. It is too primitive but works.

    namespace CsvUtilities
    {
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.IO;
    using System.Diagnostics;
    using System.Runtime.Serialization;
    using System.Globalization;

    public sealed class CsvParser
    {
    //constants
    private const int quote = '"';
    private const int comma = ',';
    private const int carrierreturn = '\r';
    private const int linefeed = '\n';

    //File Name
    private string fileName;

    /// <summary>
    /// File name propery
    /// </summary>
    public string FileName
    {
    get { return fileName; }
    set { fileName = value; }
    }

    //shared reader
    FileStream reader;

    //Flag to signal end of line
    private bool endofline;

    #if DEBUG
    public TimeSpan timeSpan;
    #endif

    /// <summary>
    /// Default parameter less constructor
    /// </summary>
    public CsvParser()
    {

    }

    /// <summary>
    /// Constructor to set file
    /// </summary>
    /// <param name="fileName">File name to parse</param>
    public CsvParser(string fileName)
    {
    //Input validation
    if (String.IsNullOrEmpty(fileName))
    throw new ArgumentException("File name can not be null");
    if (File.Exists(fileName) == false)
    throw new FileNotFoundException(fileName);

    this.fileName = fileName;
    }

    /// <summary>
    /// Parses Csv and return a data table
    /// </summary>
    /// <param name="headerIncluded">If header is not included colums will be named Column(x)</param>
    /// <returns>Data table with rows populated from Csv file</returns>
    public DataTable Parse(bool headerIncluded)
    {
    DataTable dataTable = new DataTable();
    dataTable.Locale = CultureInfo.InvariantCulture;
    DataRow dataRow;

    //Input validation
    if (String.IsNullOrEmpty(fileName))
    throw new ArgumentException("File name can not be null");

    #if DEBUG
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    #endif
    using (reader = new FileStream(fileName, FileMode.Open))
    {
    string value;
    int idx = 0;

    //Header handling
    while (reader.Position != reader.Length)
    {
    value = GetValue();
    if (headerIncluded == false)
    {
    value = "Column" + idx++;
    if (endofline)
    reader.Position = 0;
    }

    try
    {
    dataTable.Columns.Add(value);
    }
    catch (DuplicateNameException dnex)
    {
    throw;
    }

    if (endofline) break;
    }

    //Initialization
    dataRow = dataTable.NewRow();
    idx = 0;
    endofline = false;

    //Row handling
    while (reader.Position != reader.Length)
    {
    value = GetValue();
    dataRow[idx++] = value;

    if (endofline)
    {
    dataTable.Rows.Add(dataRow);
    dataRow = dataTable.NewRow();
    idx = 0;
    endofline = false;
    }
    }

    }
    #if DEBUG
    stopwatch.Stop();
    timeSpan = stopwatch.Elapsed;
    #endif
    return dataTable;
    }

    private string GetValue()
    {
    char currentByte; // Current Byte
    char nextByte; // Next Byte

    Boolean withinQuote = false; // Is current position within a quote

    List<char> bytes = new List<char>();

    long position = 0;

    //If stream is null throw exception
    if (reader == null)
    throw new ArgumentException("CSVDataset: stream can not be null");

    if (reader.CanRead == false)
    throw new ArgumentException("CSVDataset: Can not read stream");

    while (reader.CanRead)
    {
    currentByte = (char)reader.ReadByte();

    position = reader.Position;

    //If at last position terminate
    if (position == reader.Length)
    break;

    //peek next character
    nextByte = (char)reader.ReadByte();
    //As ReadByte moved cursor ahead bring cursor back
    reader.Seek(position, SeekOrigin.Begin);

    //Current character is within the quote
    if (withinQuote)
    {
    //Is this character a terminating quote
    if ((currentByte == quote) && (nextByte == comma))
    {
    reader.Seek(position + 1, SeekOrigin.Begin); //jump comma
    break;
    }
    if ((currentByte == quote) && (nextByte == quote))
    {
    continue;
    }
    else
    {
    bytes.Add(currentByte);
    continue;
    }
    }

    if (currentByte == quote)
    {
    withinQuote = true;
    continue;
    }
    if (currentByte == comma) break;

    if ((currentByte == carrierreturn) (currentByte == linefeed))
    {
    if ((nextByte == carrierreturn) (nextByte == linefeed))
    {
    reader.Seek(position + 1, SeekOrigin.Begin); //jump CR+LF
    }
    endofline = true;
    break;
    }

    bytes.Add(currentByte);
    }

    //Reading value completed. Return
    return new string(bytes.ToArray());
    }
    }
    }

    Hope this is useful to start with. Advanced parsers can be found at codeproject http://www.codeproject.com/KB/database/CsvReader.aspx

    Tuesday, January 27, 2009

    Mcshield delaying system boot up time

    Of late I am observing that my laptop takes long time to boot up. I am hunting in event log to to find probable reason.

    One thing that I observed today is about vmware disk images. Because these are huge file Mcshield takes long time to scan those file for virus.

     

    Actually I got these files in D drive. But still upon boot up these these files are being scanned causing delay in boot up time

    “A thread in process C:\Program Files\McAfee\VirusScan Enterprise\Mcshield.exe took longer than 90000 ms to complete a request.

    Build VSCORE.13.3.2.128 / 5300.2777
    Object being scanned = \Device\HarddiskVolume2\xxxxx-x86.tar.bz2”

     

    Any ideas on how to overcome this issue.

    Friday, January 16, 2009

    Google maps mobile update

    Updated to new google maps for windows mobile.

    Though street view is not so much facinating for Indian users, there are couple of things that are interesting.

    1) Now application can be installed on storage card. Thus even application data can be stored on Storage card. No more limitation of phone memory.

    2) My location can be triggered from map itself. No need to go to Menu.

    I am more happy for first point.

    Monday, January 12, 2009

    Why Should You Care about REST?

    MSDN Magazine January 2009 edition published first article in Service Station column about building WCF services using REST.

    Article is titled An Introduction To RESTful Services With WCF by Jon Flanders.

    In this article Jon mentioned about “Why Should You Care about REST?” as

    “In my mind, there are two main reasons. First, REST offers some significant features and benefits over RPC technologies in many cases. Second, Microsoft is moving many of its own implementations away from RPC technologies (such as SOAP) and toward REST. This means that even if you aren't convinced or motivated to use REST to build your own systems, as more frameworks and technologies from Microsoft (and others) move to REST, you'll need to know how to interact with them.”

    With that it is quite obvious that Microsoft/WCF is moving towards REST in year 2009.

    In this post I would like to collect some of the good links to start on REST.

    1. HTTP - Hypertext Transfer Protocol – To get overview of HTTP
    2. Dissertation of Roy Thomas Fielding – To understand REST architecture
    3. A Guide to Designing and Building RESTful Web Services with WCF 3.5
    4. Fiddler – Tool to capture http traffic

    Sunday, January 11, 2009

    Updated to Windows Live Writer 2009

    Updated to live writer 14 which is part new live update pack.

    Notable changes

    1) Preview

    2) Segeo font

    Friday, January 02, 2009