|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionHaving developed a Visual Studio 2005 add-in recently, I found that when it comes to deploying the add-in, there is no setup project automatically created any more. As described in the following excerpt from MSDN online, Visual Studio 2005 now relies on the .addin file for add-in deployment:
So now, the question is how we can still use Windows Installer (.msi) to deploy an add-in with this new registration method. Here, I will walk you through building a generic custom action to manipulate and XCopy the .addin file along with your add-in assembly that will work for most add-in deployment scenarios. The .Addin FileThe following is an example of a complete .Addin XML file. The .Addin file is usually placed at \Documents and Settings\All Users\My Documents\Visual Studio 2005\Addins or \Documents and Settings\<user name>\My Documents\Visual Studio 2005\Addins. The <?xml version="1.0" encoding="UTF-16" standalone="no"?>
<Extensibility
xmlns="http://schemas.microsoft.com/AutomationExtensibility">
<HostApplication>
<Name>Microsoft Visual Studio Macros</Name>
<Version>8.0</Version>
</HostApplication>
<HostApplication>
<Name>Microsoft Visual Studio</Name>
<Version>8.0</Version>
</HostApplication>
<Addin>
<FriendlyName>My new add-in.</FriendlyName>
<Description>This add-in does something important.</Description>
<AboutBoxDetails>Copyright MyCompany 2006.</AboutBoxDetails>
<AboutIconData>0000 . . . FFFF0000</AboutIconData>
<Assembly>[Path to add-in]\MyNewAddin.dll</Assembly>
<FullClassName>MyNewAddin.Connect</FullClassName>
<LoadBehavior>1</LoadBehavior>
<CommandPreload>0</CommandPreload>
<CommandLineSafe>0</CommandLineSafe>
</Addin>
<ToolsOptionsPage>
<Category Name="MyNewAddin">
<SubCategory Name="General">
<Assembly>[Path to add-in]\MyNewAddin.dll</Assembly>
<FullClassName>MyNewAddin.OptionsPage</FullClassName>
</SubCategory>
</Category>
</ToolsOptionsPage>
</Extensibility>
Creating a Custom Action ProjectCreate a class library project, and add a new item by choosing an Installer class. The newly added class will inherit from the namespace AddinCustomAction
{
using System;
using System.IO;
using System.Diagnostics;
using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.Xml;
/// <summary>
/// Custom action for add-in deployment.
/// </summary>
[RunInstaller(true)]
public partial class AddinInstaller : Installer
{
/// <summary>
/// Namespace used in the .addin configuration file.
/// </summary>
private const string ExtNameSpace =
"http://schemas.microsoft.com/AutomationExtensibility";
/// <summary>
/// Constructor. Initializes components.
/// </summary>
public AddinInstaller()
: base()
{
InitializeComponent();
}
/// <summary>
/// Overrides Installer.Install,
/// which will be executed during install process.
/// </summary>
/// <param name="savedState">The saved state.</param>
public override void Install(IDictionary savedState)
{
// Uncomment the following line, recompile the setup
// project and run the setup executable if you want
// to debug into this custom action.
////Debugger.Break();
base.Install(savedState);
// Parameters required to pass in from installer
string productName = this.Context.Parameters["ProductName"];
string assemblyName = this.Context.Parameters["AssemblyName"];
// Setup .addin path and assembly path
string addinTargetPath = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments),
@"Visual Studio 2005\Addins");
string assemblyPath = Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().Location);
string addinControlFileName = assemblyName + ".Addin";
string addinAssemblyFileName = assemblyName + ".dll";
try
{
DirectoryInfo dirInfo = new DirectoryInfo(addinTargetPath);
if (!dirInfo.Exists)
{
dirInfo.Create();
}
string sourceFile = Path.Combine(assemblyPath, addinControlFileName);
XmlDocument doc = new XmlDocument();
doc.Load(sourceFile);
XmlNamespaceManager xnm = new XmlNamespaceManager(doc.NameTable);
xnm.AddNamespace("def", ExtNameSpace);
// Update Addin/Assembly node
XmlNode node = doc.SelectSingleNode("/def:" +
"Extensibility/def:Addin/def:Assembly", xnm);
if (node != null)
{
node.InnerText = Path.Combine(assemblyPath, addinAssemblyFileName);
}
// Update ToolsOptionsPage/Assembly node
node = doc.SelectSingleNode("/def:Extensibility/def:" +
"ToolsOptionsPage/def:Category/def:SubCategory/def:Assembly", xnm);
if (node != null)
{
node.InnerText = Path.Combine(assemblyPath, addinAssemblyFileName);
}
doc.Save(sourceFile);
string targetFile = Path.Combine(addinTargetPath, addinControlFileName);
File.Copy(sourceFile, targetFile, true);
// Save AddinPath to be used in Uninstall or Rollback
savedState.Add("AddinPath", targetFile);
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
/// <summary>
/// Overrides Installer.Rollback, which will be executed during rollback process.
/// </summary>
/// <param name="savedState">The saved state.</param>
public override void Rollback(IDictionary savedState)
{
////Debugger.Break();
base.Rollback(savedState);
try
{
string fileName = (string)savedState["AddinPath"];
if (File.Exists(fileName))
{
File.Delete(fileName);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
/// <summary>
/// Overrides Installer.Uninstall, which will be executed during uninstall process.
/// </summary>
/// <param name="savedState">The saved state.</param>
public override void Uninstall(IDictionary savedState)
{
////Debugger.Break();
base.Uninstall(savedState);
try
{
string fileName = (string)savedState["AddinPath"];
if (File.Exists(fileName))
{
File.Delete(fileName);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
}
}
}
Configuring the Setup ProjectAdd the custom action project's output to the setup project. As shown below, in the Custom Action view, add the custom action primary output to Install, Rollback, and Uninstall.
Specify the
If you want to debug your custom action, add the following line inside the method you want to debug in the custom action class: Debugger.Break();
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||