Tuesday, July 21, 2009

Create Outlook 2007 Add-in Button using VSTO

While searching for "How to create simple outlook add-in using VSTO with single button" on net, I could
not find any sample.
One good link I found is Creating Add ins For Outlook 2007

Jeff has explained how to add menu bar to Outlook 2007 nicely here. I just extended his code to add simple
add-in button.

Start Visual Studio, create a new project. In the Project Types, select Visual C# -> Office -> 2007.
In the right hand pane, choose Outlook 2007 Add-in.





Add few properties to class file generated by VSTO



private Outlook.Explorer explorer;
private Office.CommandBar bar;
private Office.CommandBarButton buttonOne;



Add function to add a new button



private void AddButton()
{
try
{
//Define the existent Menu Bar
explorer = this.Application.ActiveExplorer();

bar = explorer.CommandBars.Add("Hello World Bar", Microsoft.Office.Core.MsoBarPosition.msoBarTop,
missing, false);
bar.Visible = true;

buttonOne = (Office.CommandBarButton)bar.Controls.Add(Office.MsoControlType.msoControlButton, missing,
missing, missing, false);

buttonOne.Caption = "Hello World";
buttonOne.Tag = "Hello World Bar.buttonOne";
buttonOne.Style = Office.MsoButtonStyle.msoButtonCaption;

//Assign event handler for button
buttonOne.Click += new Office._CommandBarButtonEvents_ClickEventHandler(buttonOne_Click);
}
catch (Exception ex)
{
//This MessageBox is visible if there is an error
System.Windows.Forms.MessageBox.Show("Error: " + ex.Message.ToString(), "Error Message Box", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
}
}



Write a event handler function



private void buttonOne_Click(Office.CommandBarButton ctrl, ref bool cancel)
{
System.Windows.Forms.MessageBox.Show("Hello World");
}



Add call to "AddButton" function in "ThisAddIn_Startup" function



private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
AddButton();
}



If you execute this code multiple times then it will add your add-in to outlook command bars multiple times. To avoid that just add function to Remove the add-in on start up.

Write one more function to remove the add-in on start up.




#region Remove Button from Outlook's command bar
private void RemoveButton()
{
//If the button already exists, remove it.
try
{
Office.CommandBarButton foundMenu = (Office.CommandBarButton)
this.Application.ActiveExplorer().CommandBars.FindControl(
Office.MsoControlType.msoControlButton,
missing, "Hello World Bar.buttonOne", true);
if (foundMenu != null)
{
foundMenu.Delete(true);
}
foreach (Office.CommandBar bar in this.Application.ActiveExplorer().CommandBars)
{
if (bar.Name.Equals("Hello World Bar"))
{
bar.Delete();
}
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
}
#endregion



Now add call to "RemoveButton" in "ThisAddIn_Startup" function before call to "AddButton"



private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
//Search the menu and delete it if found
RemoveButton();
AddButton();
}



Now execute the code. This will start Outlook 2007 and add one command bar button to Outlook toolbar.

Happy Coding!

Friday, January 11, 2008

Documentation of .NET class Libraries using NDoc

Introduction

API Documentation of application is one of the most tedious tasks for all developers. NDoc
makes it very easy for all. In this article I will try to explain how we can use NDoc
to generate MSDN style documentation for your class libraries.


Background
NDoc generates class libraries documentation from .NET
assemblies and the XML documentation files generated by the C# compiler (or an
add-on tool for VB.NET such as VBCommenter.

NDoc uses add-on documenters to generate documentation in several different
formats, including the MSDN-style HTML Help format (.chm), the Visual Studio
.NET Help format (HTML Help 2), and MSDN-online style web pages.

The NDoc source code is available under the GNU General Public
License
. If you unfamiliar with this license or have questions about it,
here is FAQ


Using the code
You can download NDoc utility files from SourceForge.Net

Now open the solution for which you want to generate documentation for in Visual Studio 2005. Add sample class library to test or you can use any existing one.

Select the class library for which you want to create documentation for. Right click on it and click on “Properties”.

You can see following dialog box.















Now click on ‘Build’ tag.
















You will see one check box “XML documentation file:” (See red eclipse part above.)
Just enable that check box and specify name for doc file. NDoc uses this file for creating documentation.

Now build your class library. Just check Debug/Release folder (Depends on your build configuration). You will see the documentation file in XML format.

NDoc’s help will give you brief idea about how you can document your class library more effectively.

Here are some tips from NDoc’s documentation.

1. The more code comments you add to your code, the more descriptive the generated help topics will be.

2. At a minimum each public type, and the public and protected members of your public types, should have a item describing what the member does or represents.

The VS.NET C# code editor has a handy feature that makes it easy to create the basic code comments for each type and member:

For the following code snippet:


public class MyClass() {

public MyClass( string s ) { }

}


if you place your cursor just above the MyClass constructor, and hit the '/' character three times in a row,
VS.NET will create the skeleton of a code comment block for that member:


public class MyClass() {
/// <summary>
///
/// </summary>
/// <param name="s"></param>
public MyClass( string s ) { }
}


This applies to any type or member that can have code comment tags associated with it. Further more,
once you have a code comment block, when you hit the '<' key to start a new tag, VS.NET will display an intellisense selector showing the appropriate list of code comment tags.
Unfortunately this list won't include the additional tags that NDoc supports, but you can still add them by hand.

NDoc supports large number of documentation tags. You can use it as per your need.

Ok… so your project is now ready for documentation.
Now just unzip the NDoc file which you have already downloaded from SourceForge.net. I have this version “ndoc-bin-1.3.1-v16.zip”.

Browse the unzipped archive and locate file NDocGui.exe. This gives a better GUI to use NDoc. Same folder contains command line utility “NDocConsole.exe”.
We can use command line utility for automated build process.

In this article I am going to explain about GUI utility only.

Double click on “NDocGui.exe”. You will see NDoc GUI console.
















Click on Project->New.

Notice “Select and Configure Documenter” section. Here you can specify output documentation type. NDoc can generate document in various format like MSDN, Linear HTML, JavaDoc etc.

Select MSDN for now.

Below that you can see various options to configure your documentation output like Copyright text, Output directory etc.

The most important settings are in visibility section. Just check which elements you want to document. For example, private variables, protected variables, Namespaces without summaries etc. (check red eclipse in following image.)
















Now click on Add.

This will open up following dialog box.








You will see small command button to specify value for key "Assembly", through which you can browse for your assembly path.

Select the “exe”/ “dll” file of your application, which you want to document.

NDoc will automatically take XML documentation file as per selected exe or dll file.

Now save the NDoc project file somewhere. So next time if we modify source, we can open saved project in NDoc and then can do the documentation build again.

Now Build the file. You can see the Build buttion on left upper corner of below screen. Click on it.














All build messages will appear in “Output” section of GUI console. You will see last message like,


Created c:\Documents and Settings\vinayakc\Desktop\New Folder\doc\ndoc_msdn_temp\Documentation.chm, 57,879 bytes

Compression decreased file by 238,719 bytes.

Html Help compile complete

Done.


Now check the output directory specified in output message. You will find “.chm” file there which will be the compiled documentation for your class library.
Just double click it and enjoy your application’s professional documentation.

Happy Coding!! :)

Monday, September 10, 2007

Create ASPNET Role provider schema for existing database

ASP.NET Role and profile provider is one of the best feature provided by ASP.NET 2.0.
Here ASP.NET provides you complete schema for your authorization-authentication functionality. You can customize and use this schema as well as you can use ASP.NET 2.0 Login controls which in turn use the same schema.
You can create this schema using ASP.NET website administration tool. This will create one new database named as "aspnetdb" in your local SQL instance.

But many of the times you need to update your existing database with ASP.NET Role and profile provider schema. How you can do this?? Heres the answer

"apsnet_regsql.exe" is the utility provided by MS to create this schema for you. There are serveral options available with this command line utility.
ASP.NET 2.0 provides this exe and you can find it in "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727".

For all options provided with "aspnet_regsql.exe" click here.

Suppose if you have database named as "blog_test" and you want to update it with ASP.NET role provider schema then you can do this as following

Just run following commands on command prompt.


C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>aspnet_regsql.exe -S (YourServerName)\SQLEXPRESS -A all -E -d blog_test



S - Option to specify server name
A - All services, including common tables and stored procedures shared by the services
E - This will use your windows credentials for authentication. You can sepecify your username and password using "-U" and "-P" options respectively if applicable.
d - Option to specify database name. In our case it is "blog_test"

The output of this command should be


Start adding the following features:
Membership
Profile
RoleManager
Personalization
SqlWebEventProvider

..................

Finished.


Now, open your SQL Server 2005 Management studio and check newly created tables and store procedures for database "blog_test".

So your application can use the existing database with role provider schema by ASP.NET 2.0
Rock!!!

ASP.NET web application's build using NAnt

Introduction

Now a days nightly builds are the most important entity for any project development lifecycle. NAnt is one of the
most popular tool for .NET automated builds. NAnt is same as Ant but it is specially designed for .NET.
This article will explain the procedure for writing the build file for ASP.NET application in brief.
I am expecting that reader knows the basics of XML technology and deployment of ASP.NET application.

Background

The deployment of ASP.NET application is little bit tricky. When you build the ASP.NET application
it generates separate .dll file for each class library included in the project. However ASP.NET 2.0 does not generate .dll file for your code behind
files i.e. ".cs" in case of C#. We have to use "aspnet_compiler.exe", which comes along with .NET 2.0 framework for generating .dll files for .cs files.
Again it generates separate .dll for each .cs. All this makes build and deployment process very complicated.

Here I am trying to guide you for writing build file for ASP.NET application's automated build using NAnt.
NAnt is very popular build tool. Its open source and you can download it freely from sourceforge.net

To use this code you have to download some external tools to setup your dev environment.
1. NAnt
2. Visual Studio 2005 Web Deployment Projects

Using the code

As mentioned earlier you have to first install the "Visual Studio 2005 Web Deployment Projects". Just download it from MSDN site and
install it on default location. This installation is required to merge multiple dll files generated by MSBuild.exe.
Download NAnt and copy the folder in to "c:"( You can copy it in to any directory. I am giving "C:" just for an example. I have used the same path in
the build file given below.)
Now go to "C:\nant\nant-0.85\bin" folder. Here you can see set of some xml/xsl files and one "lib" folder.
Create one new file here and name it as "build.number.xml". This file will specify the current version of the project in the source control.
Copy the following contents and save the file.



<?xml version="1.0" encoding="utf-8"?>
<build>
<major>1</major>
<minor>0</minor>
<build>0</build>
<release>0</release>
<companyname>CompanyName</companyname>
<copyright>Copyright 2007</copyright>
</build>


The schema of the above file should be in the same folder. Create one file and name it as "genVer.xsl".
Copy the following code and save the file.



<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">

#define VER <xsl:value-of select="build/major"/>,<xsl:value-of select="build/minor"/>,<xsl:value-of select="build/build"/>,<xsl:value-of select="build/release"/>

#define STRVER "<xsl:value-of select="build/major"/>,<xsl:value-of select="build/minor"/>,<xsl:value-of select="build/build"/>,<xsl:value-of select="build/release"/>"

#define COMPANYNAME "<xsl:value-of select="build/companyname"/>"

#define COPYRIGHT "<xsl:value-of select="build/copyright"/>"

</xsl:template>
</xsl:stylesheet>



Now we have to do some xsl coding which will help us to increment the version number. So create one new file in the same folder and
name it as "IncrBuild.xsl"
Copy the following code and save the file.


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/build/build">
<xsl:variable name="buildNumber" select="."/>
<xsl:element name="build">
<xsl:value-of select="$buildNumber + 1"/>
</xsl:element>
</xsl:template>
<xsl:template match="/ @* node()">
<xsl:copy>
<xsl:apply-templates select="@* node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>



Now you are ready to write actual build file. by default "nant" folder contains one file "Nant.build". This is simple xml file where you
can write you build code. You can separate file for your build code with extension ".build". You can run this build code using "nant.exe".
There are several options available with this exe file. You can read it from NAnt documentation available <a href="http://nant.sourceforge.net/release/0.85/help/">here</a>.
I am not giving NAnt coding basics here. You can read it from NAnt's help.
So lets start writing the heart beats for your automated build file.
Open "NAnt.build" file in any text or XML editor.

First create the rootnode for which will specify the name of the project and default target which NAnt.exe execute to start the
build process.



<project name="ProjectName" default="buildProject" xmlns="http://nant.sf.net/schemas/nant-0.85.win32.net-1.0.xsd">
</project>


Between the project tag, we have write some targets and properties.
To make our code more generic and configurable we have to declare some properties first.Please see code comments for description.



<!--Properties for build process-->
<!-- BuildDir is the directory where our .NET source resides.Project directory for web application-->
<property name="BuildDir" value="D:\Work"/>
<!-- target is the directory where we are going to store deployable files.-->
<property name="target" value="D:\Work\deploy" overwrite="false" />
<!-- SolutionFileName is the name of your solution file.-->
<property name="SolutionFileName" value="NantTrial.sln"/>
<!-- BuildNumberPath is path of the xml file where your current build no is specified.-->
<property name="BuildNumberPath" value="C:\nant\nant-0.85\bin\build.number.xml"/>
<!-- dotnet is the path of the folder where .NET framework is installed.-->
<property name="dotnet" value="c:/windows/Microsoft.NET/Framework/v2.0.50727" overwrite="false"/>
<!-- MSBuildPath is the path for the MSBuild.exe. This file comes along with .NET framework and
being stored at the same folder.-->
<property name="MSBuildPath" value="C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe" />
<!-- WebDeploymentExePath is the path of the folder where you have installed WebDeployment Project.-->
<property name="WebDeploymentExePath" value="C:\Program Files\MSBuild\Microsoft\WebDeployment\v8.0" />
<!-- WebProjectFolderName is your project's directory name-->
<property name="WebProjectFolderName" value="NantTrial" />
<!-- FinalDeployDllName is name which you want to give your final .dll file generated by WebDeployment tool.-->
<property name="FinalDeployDllName" value="ProjectName" />
<!-- newReleaseLabel can be used for naming the folder which contains final deployable files or labelling the source in
source control.-->
<property name="newReleaseLabel" value="ProjectName-0-0-0-0"/>
<!--Major build number-->
<property name="build.version.major" value="0"/>
<!--Minor build number-->
<property name="build.version.minor" value="0"/>
<!--build number-->
<property name="build.version.build" value="0"/>
<!--revision number-->
<property name="build.version.revision" value="0"/>
<!--Ending Properties for build process-->



You can configure above properties as per your requirements.
There are total 4 targets in the build file.
1. buildProject [Default target responsible for build the .NET application and create .dll files in the deploy folder.]
2. clean [Remove the previous deploy folder]
3. setversion [Set version string in application's AssemblyInfo.cs file.]
4. setVersionString [Set version string property. This property can be used for labelling the source or naming the deply folder.]
5. incrementBuildNumber [This will execute .xsl file to increment current version by 1]

All these properties depend on each other and will be executed in the bottom-up manner (5 to 1). You can configure this as per your
requirements using target's "depends" property.

You can download the attached sample NAnt.build file for above targets.
The key part of the article lies in "buildProject" target. Here we are going to build the web application.
To build the application we have to use .NET's command line utility "MSBuild.exe". This file lies in .NET framework's folder by default.
This file takes solution file name as argument. Execute it using following code.


<exec program="${MSBuildPath}">
<arg value="${BuildDir}\${SolutionFileName}" />
</exec>



Now the code can be compiled using "aspnet_compiler.exe". This file also comes along with .NET framework installation and resides
in the same folder."aspnet_compiler.exe" has multiple command line options. You can use it as per your need.
The complete set of options are described <a href="http://msdn2.microsoft.com/en-us/library/ms229863(VS.80).aspx">here</a>.
Execute "aspnet_compiler.exe" using following code.



<exec program="${dotnet}/aspnet_compiler.exe" commandline="-f -u -p ${BuildDir}\${WebProjectFolderName} -v / ${target}"/>


This tool will generate separate .dll for your class libraries. But the problem is it also generates separate .dlls for every .cs file.
It not a good idea to ship your build with these multiple .dll files, one for each web page. So there is need to merge these
multiple .dll files in to one final deployable .dll.

You can do this using Visual Studio 2005 Web Deployment Projects.
Installation of Web Deployment Projects copies "aspnet_merge.exe" to your build machine. It takes target folder name and name for
final dll as an arguments.

Execute "aspnet_merge.exe" using following code.



<exec program="${WebDeploymentExePath}\aspnet_merge.exe" commandline="${target} -o ${FinalDeployDllName} -xmldocs"/>



This whole process will copy some unnecessary files to target deployment folder which we need to remove.
Remove these files using



<delete>
<!--Remove unnecessary files from the build.-->
<fileset>
<include name="${target}/*.build" />
<include name="${target}/*.scc" />
<include name="${target}/*.sln" />
<include name="${target}/build.*" />
</fileset>
</delete>



Now open the command prompt. Change directory to your NAnt folder (i.e."C:\nant\nant-0.85\bin\" in my case ).
type "Nant.exe" and press "Enter".
The build process will start. You can see the verbose on command line. If build gets succeded it will give message as




BUILD SUCCEEDED

Total time: 33.3 seconds.


Now check your "target" folder i.e. value of property "target" in build file. In my case it is "D:\Work\deploy".
All web pages (.aspx) should be there with one "bin" folder and "precompiledApp.config" file. Bin folder should contain
all dlls for class libraries and one dll for your ".cs" file instead of seperate dlls for each. ( The name of the dll should be
the value of property "FinalDeployDllName". In my case it is "ProjectName" )

Just rock!! You are now ready for deployment.

The main advantage of NAnt automated builds is you can schdule your nightly builds. Just create one "bat" file
with the command "NAnt.exe" and schedule its running time using Windows scheduler.


Points of Interest

While designing an ASP.NET application one thing keep in mind that don't keep your solution file in the same folder where
your web pages are being stored. "MSBuild.exe" will fail to perform build in this case.
I am planning to write separate article for NAnt's common target's like Source control tasks, send mail, copy files to folders on
server etc. I will out it shortly.

Whole Contents of NAnt.Build



<?xml version="1.0"?>

<project name="ProjectName" default="buildProject" xmlns="http://nant.sf.net/schemas/nant-0.85.win32.net-1.0.xsd">
<!--Properties for build process-->
<!-- BuildDir is the directory where our .NET source resides.Project directory for web application-->
<property name="BuildDir" value="D:\Work"/>
<!-- target is the directory where we are going to store deployable files.-->
<property name="target" value="D:\Work\deploy" overwrite="false" />
<!-- SolutionFileName is the name of your solution file.-->
<property name="SolutionFileName" value="NantTrial.sln"/>
<!-- BuildNumberPath is path of the xml file where your current build no is specified.-->
<property name="BuildNumberPath" value="C:\nant\nant-0.85\bin\build.number.xml"/>
<!-- dotnet is the path of the folder where .NET framework is installed.-->
<property name="dotnet" value="c:/windows/Microsoft.NET/Framework/v2.0.50727" overwrite="false"/>
<!-- MSBuildPath is the path for the MSBuild.exe. This file comes along with .NET framework and
being stored at the same folder.-->
<property name="MSBuildPath" value="C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe" />
<!-- WebDeploymentExePath is the path of the folder where you have installed WebDeployment Project.-->
<property name="WebDeploymentExePath" value="C:\Program Files\MSBuild\Microsoft\WebDeployment\v8.0" />
<!-- WebProjectFolderName is your project's directory name-->
<property name="WebProjectFolderName" value="NantTrial" />
<!-- FinalDeployDllName is name which you want to give your final .dll file generated by WebDeployment tool.-->
<property name="FinalDeployDllName" value="ProjectName" />
<!-- newReleaseLabel can be used for naming the folder which contains final deployable files or labelling the source in
source control.-->
<property name="newReleaseLabel" value="ProjectName-0-0-0-0"/>
<!--Major build number-->
<property name="build.version.major" value="0"/>
<!--Minor build number-->
<property name="build.version.minor" value="0"/>
<!--build number-->
<property name="build.version.build" value="0"/>
<!--revision number-->
<property name="build.version.revision" value="0"/>
<!--Ending Properties for build process-->

<!--Increment the build number-->
<target name="incrementBuildNumber">
<!--Increment the number in the build number file.-->
<style style="incrBuild.xsl" in="${BuildNumberPath}" out="build.number.tmp"/>
<delete file="${BuildNumberPath}"/>
<move file="build.number.tmp" tofile="${BuildNumberPath}"/>
<!--<style style="genVer.xsl" in="${BuildNumberPath}" out="${VersionPath}"/>-->
<xmlpeek file="${BuildNumberPath}" xpath="/build/major" property="build.version.major"/>
<xmlpeek file="${BuildNumberPath}" xpath="/build/minor" property="build.version.minor"/>
<xmlpeek file="${BuildNumberPath}" xpath="/build/build" property="build.version.build"/>
<xmlpeek file="${BuildNumberPath}" xpath="/build/release" property="build.version.revision"/>
<!--You can check in the latest build file in to source control.-->
</target>

<!--Set the version string for new label. This label can be used to name the final build folder or labelling the
source in source control.-->
<target name="setVersionString" depends="incrementBuildNumber">
<property name="newReleaseLabel" value="ProjectName-${build.version.major}-${build.version.minor}-${build.version.build}-${build.version.revision}"/>
<echo message= "${newReleaseLabel}" />
</target>

<!--Set version in AssemblyInfo.cs file.This version will be stamped for generated .dll files.-->
<target name="setversion" depends="setVersionString" description="Stamp the version info onto assemblyinfo.cs files">
<foreach item="File" property="filename">
<in>
<items basedir="application">
<include name="**\AssemblyInfo.cs"></include>
</items>
</in>
<do>
<script language="C#">
<code><![CDATA[
public static void ScriptMain(Project project)
{
//FileStream file = File.Open(project.Properties["filename"], FileMode.Open, FileAccess.ReadWrite);
StreamReader reader = new StreamReader(project.Properties["filename"]);
string contents = reader.ReadToEnd();
reader.Close();
string replacement = string.Format(
"[assembly: AssemblyVersion(\"{0}.{1}.{2}.{3}\")]",
project.Properties["build.version.major"],
project.Properties["build.version.minor"],
project.Properties["build.version.build"],
project.Properties["build.version.revision"]
);
string newText = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replacement);
StreamWriter writer = new StreamWriter(project.Properties["filename"], false);
writer.Write(newText);
writer.Close();
}
]]>
</code>
</script>
</do>
</foreach>
</target>

<target name="clean" description="Remove all files from target folder.">
<delete dir="${target}" />
</target>

<target name="buildProject" depends="setversion">
<call target="clean" />
<exec program="${MSBuildPath}">
<arg value="${BuildDir}\${SolutionFileName}" />
</exec>
<exec program="${dotnet}/aspnet_compiler.exe" commandline="-f -u -p ${BuildDir}\${WebProjectFolderName} -v / ${target}"/>
<exec program="${WebDeploymentExePath}\aspnet_merge.exe" commandline="${target} -o ${FinalDeployDllName} -xmldocs"/>
<delete>
<!--Remove unnecessary files from the build.-->
<fileset>
<include name="${target}/*.build" />
<include name="${target}/*.scc" />
<include name="${target}/*.sln" />
<include name="${target}/build.*" />
</fileset>
</delete>
</target>
</project>