In this long post, let us see how the Revit Manifest Register project wizard can help create a custom install custom action project for us. Then the project output can be added into a setup project as custom actions so that Revit Manifest files can be deployed automatically and properly.
To demonstrate how it works, we need a Visual Studio solution at hand and a few sample projects in it. For example, the solution has two C# projects (RevitAddinCS1 and RevitAddinCS2), a VB.NET project (RevitAddinVB1), and a setup (Setup1) project.
Now let’s add a Revit Manifest Register project to the same solution using the New Project dialog:
This is the welcome page:
We specify the manifest version and type, pick an .AddIn or .DLL file, and choose an application definition from the manifest or the assembly file in the next page. We choose the 2011 version and pick an assembly here:
As can be noticed above the default assembly folder is set as the output folder of the current active project, RevitAddinVB1 here. If the Manifest (.AddIn) file type option is chosen, the current project folder will be defaulted instead, where has the manifest file created by the RevitAddinWizard automatically if applicable.
So it is a good idea to set the project of concern as current before launching the Revit Manifest Register wizard.
All available (external) applications will be list out in the Application combo-box. Please pick the desired one.
Then the application manifest information will be retrieved from the .AddIn file or the assembly directly and its details will be listed out in the coming page:
The absolute path of the assembly is not necessary here since it will be determined automatically during installations. The full class name of the application along with the assembly file name cannot be changed, apparently. If the ClientId is retrieved from an existing manifest file, it is not recommended to change it, but anyway we can regenerate the GUID or even manually input one if want like. Please just remember to follow the GUID rule. Otherwise, Revit will not be happy to load the manifest file.
The final deployment manifest file name and the application name can be changed from the default given ones to anything else valid.
Now it is time to review all the settings in the summary page:
If anything is unsatisfactory, we can press the Back button and go back to previous pages to make any changes accordingly; otherwise, we press the Finish button to create the Revit Manifest Register project as such:
Now we need to revisit the contents of the Application Folder of the setup project and add the primary output from the newly created register project, the RevitManifestRegister1 here.
After that, we add the output as custom actions of all the four events, Install, Commit, Rollback, and Uninstall:
If it is expected for the register to honor the All Users and the Just Me options in the installation dialog, please add the following line to the CustomActionData field of all the four Custom Actions:
/ALLUSERS=[ALLUSERS]
If the current user is the only concern, we can even skip the step of setting CustomActionData. Now we are all set and it is time to build all and give the installer a try.
Here is the complete code of the sample Revit Manifest Register:
using System;
using System.Collections;
using System.ComponentModel;
using System.Text;
using System.Configuration.Install;
using System.IO;
namespace RevitAddinWizard
{
[RunInstaller(true)]
public class RevitManifestRegister1 : 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 RevitManifestRegister1()
{
fileName = @"RevitAddinVB1_RegisterTest.Addin";
assemblyName = @"RevitAddinVB1.dll";
className = @"RevitAddinVB1.ExtApp";
clientId = @"50f1ccd3-3123-4b2f-b452-7494dcc39d66";
appName = @"A Sample External Application";
}
#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("RawAddinPath", 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["RawAddinPath"];
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["RawAddinPath"];
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
}
}
Revit Manifest Register of RevitAddinWizard helps create a custom installer project in no time. The custom 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