# Visual Basic > Visual Basic FAQs >  [FAQ's: OD] How do I use .NET to make an Add-In for an Office application?

## RobDog888

Using VS.NET 2003...


Start a new project and select - New Project > Other Projects > Extensibility Projects > "Shared Add-In" (Fig. 1). Fill in the Name and press OK.

Fig. 1







Then you will get a "Welcome to the Add-In Wizard" extensibility wizard that will help you finish configuring your add-in.

*AddIn Wizard Step 1:* Choose the language you want to write it in - Visual Basic, Visual C#, Visual C++/ALT (Fig. 2).

Fig. 2




*AddIn Wizard Step 2:* Is where you will be presented with a checked list of which office apps you want it shared with. Ie: each paticular office app, vs addin, etc (Fig. 3). For this demo I am going to choose Outlook only. Then click Next.

Fig. 3




*AddIn Wizard Step 3:* Give your add-in a name and description. These show in the COM AddIn dialog if the AddIn is manageable by the user. Then click Next (Fig. 4).

Fig. 4




*AddIn Wizard Step 4:* This is where you can specify the Add-Ins loading behavior. Choices can be edited later (via registry edit) and include: Load when application loads, load on demand, not loaded (Fig. 5).

The other option is to specify if the Add-In is to be available to all users on the system or a particular user (Private). for the example I will choose All Users (Fig. 5). For special notes and elaboration on the consequences of "Just Me" vs. "All Users", please see post #3 below.


Fig. 5




*AddIn Wizard Step 5:* This last step is just a summary screen (Fig. 6). Click Finish to have the wizard apply the settings and selections.

Fig. 6



Almost done. Now its time to get down to some actual c0d.  :Big Grin: 

The wizard will generate a template of code based upon your selections.


VB.NET Code example below in post #2. 

C# Code example below in post #4 (Added 01.16.2007)

Installation procedures and characteristics of your setup package are continued below in post #3.  :Smilie:

----------


## RobDog888

*VB.NET 2003 Code Example:*


```
Option Explicit On
Option Strict Off

Imports Microsoft.Office.Core
Imports Extensibility
Imports System.Runtime.InteropServices

#Region " Read me for Add-in installation and setup information. "
' When run, the Add-in wizard prepared the registry for the Add-in.
' At a later time, if the Add-in becomes unavailable for reasons such as:
'   1) You moved this project to a computer other than which is was originally created on.
'   2) You chose 'Yes' when presented with a message asking if you wish to remove the Add-in.
'   3) Registry corruption.
' you will need to re-register the Add-in by building the VBGuru1Setup project 
' by right clicking the project in the Solution Explorer, then choosing install.
#End Region

<GuidAttribute("66BE9A28-4605-4671-8057-C849BD094A14"), ProgIdAttribute("VBGuru1.Connect")> _
Public Class Connect
	
    Implements Extensibility.IDTExtensibility2

    '<LATE BIND OUR OUTLOOK APPLICATION OBJECT>
    Public moApp As Object
    Public moInstance As Object
    '<DECLARE OUT BUTTONS EVENT SO WE CAN HANDLE IT IN OUR ADDIN>
    Public WithEvents moCBMeow As CommandBarButton

    Public Sub OnAddInsUpdate(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnAddInsUpdate
        'The OnAddInsUpdate method is called when a change occurs to the list of add-ins in the COM Add-Ins dialog box,
        'such as when an add-in is loaded or unloaded. The custom parameter is an array that can be used to provide
        'additional data to the OnAddInsUpdate method if desired. This parameter is ignored in Add-ins for Office 2000.
        '<NEEDED TO COMPLETE IDTEXTENSIBILITY2 COMPATIBILITY>
    End Sub

    Public Sub OnBeginShutdown(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnBeginShutdown
        'The OnBeginShutdown method is called while the environment is being shut down. The custom parameter is an array
        'that can be used to provide additional data to the OnBeginShutdown method if desired.
        '<REMOVE OUR CUSTOM TOOLBAR BUTTON>
        If Not moCBMeow Is Nothing Then
            moCBMeow.Delete()
        End If
        moCBMeow = Nothing
    End Sub

    Public Sub OnDisconnection(ByVal RemoveMode As Extensibility.ext_DisconnectMode, ByRef custom As System.Array) _
    Implements Extensibility.IDTExtensibility2.OnDisconnection
        'The OnDisconnection method is called when the managed COM add-in is unloaded, such as when the user closes 
        'the host application. The custom parameter is an array that can be used to provide additional data to the 
        'OnDisconnection method if desired. The RemoveMode parameter is an ext_dm constant that indicates how the 
        'managed COM add-in was unloaded.
        '<THE FOUR DISCONNECT MODES:>
        'ext_dm_HostShutdown (Value: 0) - The Add-in was unloaded when the application was closed.
        'ext_dm_UserClosed (Value: 1) - The Add-in was unloaded when the user cleared its check box in the Add-In 
        '                               Manager dialog box, or when the Connect property of the corresponding AddIn
        '                               object was set to False.
        'ext_dm_UISetupComplete (Value: 2) - The Add-in was unloaded after the environment setup completed and after 
        '                                    the OnConnection method returns.
        'ext_dm_SolutionClosed (Value: 3) - The Add-in was unloaded when the solution was closed. Received by 
        '                                   solution Add-ins.
        If RemoveMode <> Extensibility.ext_DisconnectMode.ext_dm_HostShutdown Then Call OnBeginShutdown(custom)
        moApp = Nothing
    End Sub

    Public Sub OnConnection(ByVal application As Object, ByVal connectMode As Extensibility.ext_ConnectMode, _
    ByVal addInInst As Object, ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnConnection
        'The OnConnection method is called when the add-in is loaded into the environment. The addInInst parameter 
        'is an object that represents the instance of the managed COM add-in. The custom parameter is an array that 
        'can be used to use to provide additional data to the OnConnection method if desired. The application parameter 
        'represents the host application. The connectMode parameter is an ext_cm constant that indicates how the 
        'managed COM add-in was loaded.
        '<INITIAL EVENT THAT FIRES WHEN TEH ADDIN IS LOADED>
        '<SET THE PUBLIC APPLICATION OBJECT TO THE PASSED IN NSTANCE FOR SECURITY AND TRUST>
        moApp = application
        moInstance = addInInst
        '<IF YOU ARE NOT IN STARTUP, MANUALLY CALL THE OnStartupComplete EVENT PROCEDURE>
        If (connectMode <> Extensibility.ext_ConnectMode.ext_cm_Startup) Then Call OnStartupComplete(custom)
    End Sub

    Public Sub OnStartupComplete(ByRef custom As System.Array) Implements Extensibility.IDTExtensibility2.OnStartupComplete
        'The OnAction property is optional but recommended. It should be set to the ProgID of the add-in, so that if
        'the add-in is not loaded when a user clicks the button, MSO loads the add-in automatically and then raises
        'the Click event for the add-in to handle.
        '<SET OUT TOOLBAR BUTTON IN THIS EVENT AS ITS THE LAST TO FIRE SO OUTLOOK WILL BE COMPLETELY LOADED AND STARTED>
        Try
            'CHECK IF OUR BUTTON ALREADY HAS BEEN ADDED>
            moCBMeow = moApp.activeexplorer.commandbars("Standard").FindControl( _
            Microsoft.Office.Core.MsoControlType.msoControlButton, , "891", False, True)
            If moCBMeow Is Nothing Then
                '<ADD CUSTOM TOOLBAR ITEM>
                moCBMeow = moApp.ActiveExplorer.CommandBars("Standard").Controls.Add( _
                Microsoft.Office.Core.MsoControlType.msoControlButton, , "891", , False)
                '<SET UP THE BUTTONS PROPERTIES>
                With moCBMeow
                    .BeginGroup = True
                    .Caption = "Meow.NET"
                    .DescriptionText = "Meow.NET Meow.NET Meow.NET!"
                    .Enabled = True
                    .FaceId = 7466 '
                    .OnAction = "!<VBGuru1.Connect>" '<LINKS OUR ADDIN TO OUTLOOK FOR THE WITHEVENTS DECLARATION>
                    .Style = MsoButtonStyle.msoButtonIconAndCaption
                    .Tag = "891"
                    .TooltipText = "Meow.NET Meow.NET Meow.NET!"
                End With
            End If
        Catch ex As Exception
            If moCBMeow Is Nothing Then
                MsgBox("Could not set button - moCBMeow", MsgBoxStyle.Exclamation Or MsgBoxStyle.OKOnly, _
                "VB/Office Guru - VBGuru1 AddIn")
            Else
                MsgBox(ex.Message.ToString, MsgBoxStyle.Exclamation Or MsgBoxStyle.OKOnly, _
                "VB/Office Guru - VBGuru1 AddIn")
            End If
        End Try
    End Sub

    Private Sub moCBMeow_Click(ByVal Ctrl As Microsoft.Office.Core.CommandBarButton, ByRef CancelDefault As Boolean) _
    Handles moCBMeow.Click
        '<OUR TOOLBAR BUTTON CLICK EVENT PROCEDURE>
        Try
            MsgBox("Meow.NET Meow.NET Meow.NET!", MsgBoxStyle.Information Or MsgBoxStyle.OKOnly, _
            "VB/Office Guru - VBGuru1 AddIn")
        Catch ex As Exception
            MsgBox("An error has occured with AddIn: VBGuru1." & Environment.NewLine & "Error details : " & _
            ex.Message.ToString, MsgBoxStyle.Exclamation Or MsgBoxStyle.OKOnly, "VB/Office Guru - VBGuru1 AddIn")
        End Try
    End Sub

End Class
```

----------


## RobDog888

*AddIn Installation Characteristics*

After you have coded your AddIn, you can build the dll and the installation setup package and you will be ready for deployment. When the installation is run there are two options that are for the install type: "Everyone" or "Just Me". Now depending on your choice will determine the availability of the AddIn to be accessed under different user profile accounts. 

Special Note: The original setup AddIn Wizard Step #4 (Fig. 5 in post #1) where you choose the availability of the AddIn will determine how your AddIn will be able to be managed. 
Just Me:
Installs the dll AddIn data to the registry location - 
HKEY_CURRENT_USER\Software\Microsoft\Office\Outlook\Addins\VBGuru1.Connect
All Users:
Installs the dll AddIn data to the registry location -
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\Outlook\Addins\VBGuru1.Connect
A "Just Me" install will give your user(s) AddIn access via the COM AddIns button in Outlook and similar in other Office applications. The user(s) will have the ability to unload, remove, and Add. Now this may be an issue if you dont want your users to have any control over the loading of the AddIn. If thats your need then choosing "All Users" will be the choice you want.

An "All Users" install will give your user(s) no access via the COM AddIns button in Outlook and similar in other Outlook applications. The user(s) will NOT have the ability to unload, remove, or Add your AddIn as the AddIn will not be visible in the COM AddIns list. So with that, they could uninstall the AddIn via the Add/Remove control panel applet if they have permissions to do so but otherwise they cant control the AddIns loading behaviors if they cant see it.  :Wink: 



*AddIn Installation Procedure:*

Step by step installation guide of the setup package.


*Step 1:*
Close all unecessary programs and also close the Office application that the AddIn is targeted for as the load behavior is "Load At Startup" for this FAQ.


*Step 2:*
If you have the appropriate security permissions then you should have no issues installing your AddIn. Execute the msi setup package to start the installation and you will be presented with the first step as shown (Fig. 7) and click "Next".


Fig. 7






*Step 3:*
Click "Next" again to confirm and proceed with the installation (Fig. 8).


Fig. 8






*Step 4:*
Select your installation destination location by clicking on the "Browse" button or accept the default location. Then choose the type of access you want to give for other profiles on your system, if any, by choosing either "Everyone" or "Just Me". Then click "Next" to start the installation process (Fig. 9)


Fig. 9






*Step 5:*
Installation process shown as its installing (Fig. 10).

Fig. 10






*Step 6:*
Confirmation of sucessfully installing your AddIn (Fig. 11).


Fig. 11






The installation process installs four (4) fliles in the destination directory for our demo AddIn:
Extensibility.dllOffice.dllVBGuru1.dllVBGuru1.tlb


Open Outlook now and we will see our AddIn loaded and displayed on the Standard toolbar (image cropped for easier viewing.  :Wink: ).





Click on our custom toolbar button ("Meow.NET").




 :Smilie:

----------


## Tec-Nico

Here is the code for the add-in in C#.

The code is just the same than its VB counter-part but it uses reflection to perform the late-binding and includes a few things that will make the add-in work properly using C#.

One of the main things is the use of a Type.Missing object that is used whenever there is an optional parameter we don't want to provide, we use that object.

Also, we need to add a reference to System.Windows.Forms to access the MessageBox.

Finally, the code has a part where it gets the standard command bar depending on the application the add-in connects to (In this case is just Outlook but think of the possibilities of this) by using reflection.

Enjoy!


```
namespace VBGuru1
{
	using System;
	using Microsoft.Office.Core;
	using Extensibility;
	using System.Runtime.InteropServices;
	//In order to use late binding, we will use Reflection:
	using System.Reflection;
	//In order for the message box to work, add a .NET Reference to "System.Windows.Forms" (Project>Add Reference...):
	using System.Windows.Forms;

	#region Read me for Add-in installation and setup information.
	// When run, the Add-in wizard prepared the registry for the Add-in.
	// At a later time, if the Add-in becomes unavailable for reasons such as:
	//   1) You moved this project to a computer other than which is was originally created on.
	//   2) You chose 'Yes' when presented with a message asking if you wish to remove the Add-in.
	//   3) Registry corruption.
	// you will need to re-register the Add-in by building the MyAddin21Setup project 
	// by right clicking the project in the Solution Explorer, then choosing install.
	#endregion

	[GuidAttribute("1DB8CC3C-2C58-4CCE-A4C9-4D3895324ED2"), ProgId("VBGuru1.Connect")]
	public class Connect : Object, Extensibility.IDTExtensibility2
	{
		//LATE BIND OUR OUTLOOK APPLICATION OBJECT>
		public object moApp;
		public object moInstance;
		//DECLARE BUTTON (Later we will add its event handler)>
		public CommandBarButton moCBMeow;
		//Declare a missing type to use as an empty parameter when using Optional Parameters:
		private object oOptionalParameter = Type.Missing;

		public Connect()
		{
		}

		public void OnAddInsUpdate(ref System.Array custom)
		{
			/*
			 The OnAddInsUpdate method is called when a change occurs to the list of add-ins in the COM Add-Ins dialog box,
			 such as when an add-in is loaded or unloaded. The custom parameter is an array that can be used to provide
			 additional data to the OnAddInsUpdate method if desired. This parameter is ignored in Add-ins for Office 2000.
			 NEEDED TO COMPLETE IDTEXTENSIBILITY2 COMPATIBILITY>
			*/
		}

		public void OnBeginShutdown(ref System.Array custom)
		{
			/*
			 The OnBeginShutdown method is called while the environment is being shut down. The custom parameter is
			 an array that can be used to provide additional data to the OnBeginShutdown method if desired.
			 REMOVE OUR CUSTOM TOOLBAR BUTTON>
			*/
			if(moCBMeow != null)
				moCBMeow.Delete(oOptionalParameter);
			moCBMeow = null;
		}

		public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref System.Array custom)
		{
			/*
			 The OnDisconnection method is called when the managed COM add-in is unloaded, such as when the user closes
			 the host application. The custom parameter is an array that can be used to provide additional data to the
			 OnDisconnection method if desired. The RemoveMode parameter is an ext_dm constant that indicates how the 
			 managed COM add-in was unloaded.
			 THE FOUR DISCONNECT MODES:>
			 ext_dm_HostShutdown (Value: 0) - The Add-in was unloaded when the application was closed.
			 ext_dm_UserClosed (Value: 1) - The Add-in was unloaded when the user cleared its check box in the Add-In
			                                Manager dialog box, or when the Connect property of the corresponding AddIn
			                                object was set to False.
			ext_dm_UISetupComplete (Value: 2) - The Add-in was unloaded after the environment setup completed and after
			                                    the OnConnection method returns.
			ext_dm_SolutionClosed (Value: 3) - The Add-in was unloaded when the solution was closed. Received by
			                                   solution Add-ins.
			*/
			if(disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
				this.OnBeginShutdown(ref custom);
			moApp = null;
		}

		public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
		{
			/*
			 The OnConnection method is called when the add-in is loaded into the environment. The addInInst parameter
			 is an object that represents the instance of the managed COM add-in. The custom parameter is an array that
			 can be used to use to provide additional data to the OnConnection method if desired. The application parameter
			 represents the host application. The connectMode parameter is an ext_cm constant that indicates how the
			 managed COM add-in was loaded.
			 INITIAL EVENT THAT FIRES WHEN TEH ADDIN IS LOADED>
			 SET THE PUBLIC APPLICATION OBJECT TO THE PASSED IN NSTANCE FOR SECURITY AND TRUST>
			*/
			moApp = application;
			moInstance = addInInst;
			//IF YOU ARE NOT IN STARTUP, MANUALLY CALL THE OnStartupComplete EVENT PROCEDURE>
			if(connectMode != Extensibility.ext_ConnectMode.ext_cm_Startup)
				this.OnStartupComplete(ref custom);
		}

		public void OnStartupComplete(ref System.Array custom)
		{
			/*
			 The OnAction property is optional but recommended. It should be set to the ProgID of the add-in, so that if
			 the add-in is not loaded when a user clicks the button, MSO loads the add-in automatically and then raises
			 the Click event for the add-in to handle.
			 SET OUT TOOLBAR BUTTON IN THIS EVENT AS ITS THE LAST TO FIRE SO OUTLOOK WILL BE COMPLETELY LOADED AND STARTED>
			*/
			try
			{
				//Code extended to support different applications and take advantage of Late Binding:
				CommandBars oCommandBars;
				CommandBar oStandardBar;

				try
				{
					oCommandBars = (CommandBars) moApp.GetType().InvokeMember("CommandBars", BindingFlags.GetProperty, null, moApp,null);
				}
				catch(Exception)
				{
					//Outlook has the CommandBars collection on the Explorer object:
					object oActiveExplorer;
					oActiveExplorer = moApp.GetType().InvokeMember("ActiveExplorer", BindingFlags.GetProperty, null, moApp, null);
					oCommandBars = (CommandBars)oActiveExplorer.GetType().InvokeMember("CommandBars",BindingFlags.GetProperty,null,oActiveExplorer,null);
				}

				//Set up the button on the "Standard" commandbar:
				try
				{
					oStandardBar = oCommandBars["Standard"];        
				}
				catch(Exception)
				{
					//Access's main toolbar (Standard) is called "Database":
					oStandardBar = oCommandBars["Database"];      
				}
				//End of Code extended to support different applications and take advantage of Late Binding

				//CHECK IF OUR BUTTON ALREADY HAS BEEN ADDED>
				moCBMeow = (CommandBarButton) oStandardBar.FindControl(Microsoft.Office.Core.MsoControlType.msoControlButton, oOptionalParameter, "891", false, true);
				if(moCBMeow == null)
				{
					//ADD CUSTOM TOOLBAR ITEM>
					moCBMeow = (CommandBarButton) oStandardBar.Controls.Add(Microsoft.Office.Core.MsoControlType.msoControlButton, oOptionalParameter, "891", oOptionalParameter, false);
					//SET UP THE BUTTONS PROPERTIES>
                    moCBMeow.BeginGroup = true;
                    moCBMeow.Caption = "Meow.NET";
                    moCBMeow.DescriptionText = "Meow.NET Meow.NET Meow.NET!";
                    moCBMeow.Enabled = true;
                    moCBMeow.FaceId = 7466; // Replace for Cat's Icon!
                    moCBMeow.OnAction = "!"; //
                    moCBMeow.Style = MsoButtonStyle.msoButtonIconAndCaption;
                    moCBMeow.Tag = "891";
                    moCBMeow.TooltipText = "Meow.NET Meow.NET Meow.NET!";
				}
				
				//Add the Event Handler for the click event:
				moCBMeow.Click += new _CommandBarButtonEvents_ClickEventHandler(moCBMeow_Click);
			}
			catch(Exception ex)
			{
				string sMessage;
				if(moCBMeow == null)
					sMessage = "Could not set button - moCBMeow";
				else
					sMessage = ex.Message.ToString();

				MessageBox.Show(sMessage, "VB/Office Guru - VBGuru1 AddIn", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
		}

		private void moCBMeow_Click(CommandBarButton Ctrl, ref bool CancelDefault)
		{
			//OUR TOOLBAR BUTTON CLICK EVENT PROCEDURE>
			try
			{
				MessageBox.Show("Meow.NET Meow.NET Meow.NET!", "VB/Office Guru - VBGuru1 AddIn", MessageBoxButtons.OK, MessageBoxIcon.Information);
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.Message.ToString(), "VB/Office Guru - VBGuru1 AddIn", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
		}
	}
}
```

----------

