In this post, let us see how to deploy Revit Manifest files programmatically with C# and properly through using a custom installer class and some custom actions of a setup project.
The first step is to add a new class library project (say Register) into the same solution that the Revit Addin project resides in as we discussed earlier.
The second step is to create an Installer derivative, override necessary methods, append necessary help methods as we introduced before, specify some necessary constants and variables to indicate which version of Revit Manifest to care about and the roaming folder format, and initialize something about the external application that the manifest file is going to take care of:
using System;
using System.Collections;
using System.ComponentModel;
using System.Text;
using System.Configuration.Install;
using System.IO;
namespace RevitAddinWizard
{
[RunInstaller(true)]
public class Register : Installer
{
#region Constants and Fields
const string Assembly_Path_Parameber = "ASSEMBLYPATH";
const string All_Users_Parameter = "ALLUSERS";
const string Manifest_Version = "2011";
const string Folder_Format = "%{0}%\\Autodesk\\Revit\\Addins\\{1}";
const string Folder_Format_XP = "%{0}%\\Application Data\\Autodesk\\Revit\\Addins\\{1}";
const string Current_User_Profile = "AppData";
const string All_Users_Profile = "ALLUSERSPROFILE";
string fileName, filePath, roamingFolder, assemblyName, assemblyPath, className, clientId, appName;
#endregion
#region Constructor
public Register()
{
fileName = @"RegisterTest.Addin";
assemblyName = @"RevitAddinCS1.dll";
className = @"RevitAddinCS1.ExtApp";
clientId = @"809fa6b4-8e99-484e-84ba-cdfbac07ce99";
appName = @"RevitAddinCS1";
}
#endregion
#region Overrides
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
try
{
if (Context.Parameters.ContainsKey(Assembly_Path_Parameber) &&
!string.IsNullOrEmpty(Context.Parameters[Assembly_Path_Parameber]))
{
assemblyPath = Path.Combine(Path.GetDirectoryName(Context.Parameters[Assembly_Path_Parameber]), assemblyName);
}
//
// Please add /ALLUSERS=[ALLUSERS] to the CustomActionData of the Custom Actions if the manifest file is going to be deployed
// to different locations based on the user choise of the installation dialog if applicable and necessary.
// Otherwise the current user roaming folder will be used.
//
if (Context.Parameters.ContainsKey(All_Users_Parameter) &&
!string.IsNullOrEmpty(Context.Parameters[All_Users_Parameter]) &&
Context.Parameters[All_Users_Parameter] == "1")
{
if (IsXP())
{
roamingFolder = Environment.ExpandEnvironmentVariables(string.Format(Folder_Format_XP, All_Users_Profile, Manifest_Version));
}
else if (IsVistaOrWin7())
{
roamingFolder = Environment.ExpandEnvironmentVariables(string.Format(Folder_Format, All_Users_Profile, Manifest_Version));
}
}
else
{
roamingFolder = Environment.ExpandEnvironmentVariables(string.Format(Folder_Format, Current_User_Profile, Manifest_Version));
}
DirectoryInfo dirInfo = new DirectoryInfo(roamingFolder);
if (!dirInfo.Exists)
{
dirInfo.Create();
}
filePath = Path.Combine(roamingFolder, fileName);
CreateManifestFile(filePath, assemblyPath, className, clientId, appName);
stateSaver.Add("AddinPath", filePath);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
}
public override void Uninstall(IDictionary savedState)
{
base.Uninstall(savedState);
try
{
filePath = (string)savedState["AddinPath"];
if (File.Exists(filePath))
{
File.Delete(filePath);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
public override void Rollback(IDictionary savedState)
{
base.Rollback(savedState);
try
{
filePath = (string)savedState["AddinPath"];
if (File.Exists(filePath))
{
File.Delete(filePath);
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
#endregion
#region Methods
bool IsXP()
{
OperatingSystem OS = Environment.OSVersion;
return OS.Platform == PlatformID.Win32NT && (OS.Version.Major == 5 && OS.Version.Minor >= 1);
}
bool IsVistaOrWin7()
{
OperatingSystem OS = Environment.OSVersion;
return OS.Platform == PlatformID.Win32NT && (OS.Version.Major == 6 && OS.Version.Minor <= 1);
}
void CreateManifestFile(string filename, string assembly, string classname, string id, string appname)
{
using (StreamWriter writer = new StreamWriter(filename, false, Encoding.UTF8))
{
writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
writer.WriteLine("<RevitAddIns>");
writer.WriteLine(string.Format("\t<AddIn Type=\"Application\">"));
writer.WriteLine(string.Format("\t\t<Assembly>{0}</Assembly>", assembly));
writer.WriteLine(string.Format("\t\t<FullClassName>{0}</FullClassName>", classname));
writer.WriteLine(string.Format("\t\t<ClientId>{0}</ClientId>", id));
writer.WriteLine(string.Format("\t\t<Name>{0}</Name>", appname));
writer.WriteLine(string.Format("\t</AddIn>"));
writer.WriteLine("</RevitAddIns>");
}
}
#endregion
}
}
Next step is to create a Visual Studio setup project for sure and add necessary project outputs to it.
Then it is time to add the Register.dll (or better, simpler and more flexible, the primary output from the register project which contains the custom installer) to all the four available Custom Actions, Install, Commit, Rollback, and Uninstall, and specify their CustomActionData as suggested by the code comments:
The last step is certainly to rebuild everything including the setup project and give it a try. You will not miss it.
Revit Manifest Register of RevitAddinWizard helps create an installer custom action project flexibly in no time. The action will automatically create a manifest file, append proper path to the specified assembly, and deploy the file to the right Revit Addin roaming folder during installations.
Related posts:
Deploy & Install: Revit Application Addin Manifest
Deploy & Install: Revit Command Addin Manifest
Deploy & Install: Revit Addin Roaming Folders
Deploy & Install: The Registry of Revit 2011
Deploy & Install: The Registry of Revit 2012
Deploy & Install: Where Are Revit Products Installed
Deploy & Install: Manifest Navigator of RevitAddinWidget
Deploy & Install: RegEdit Launcher of RevitAddinWidget
Deploy & Install: Revit Locator of RevitAddinWidget
Deploy & Install: Manifest Encoding
Deploy & Install: Manifest Loading
Deploy & Install: Manifest ClientId
Deploy & Install: Manifest ClientId and AddinId
Deploy & Install: Manifest Integrity
Deploy & Install: Revit Manifest Organizer
Deploy & Install: Create New Of Revit Manifest Organizer
Deploy & Install: Check Integrity New Of Revit Manifest Organizer
Deploy & Install: Detect Duplicate New Of Revit Manifest Organizer
Deploy & Install: View Selected Of Revit Manifest Organizer
Deploy & Install: Edit Selected Of Revit Manifest Organizer
Deploy & Install: Merge Selected Of Revit Manifest Organizer
Deploy & Install: Dismantle Selected Of Revit Manifest Organizer
Deploy & Install: Copy/Move/Delete Selected Of Revit Manifest Organizer
Deploy & Install: Miscellaneous Of Revit Manifest Organizer
Deploy & Install: Create Revit Manifest Files Programmatically With C#
Deploy & Install: Programmatically Detect Windows Versions And Find Revit Addin Roaming Folders
Deploy & Install: Revit Addin Project Output And API Dependencies
Deploy & Install: Revit Addin Projects and Visual Studio Setup Custom Actions
Deploy & Install: Deploy Revit Manifest Files with C# Using Installer Custom Actions
Recent Comments