Basics of Revit Add-In Programming: Visual Studio
Basics of Revit Add-In Programming: Visual Studio
Basics of Revit Add-In Programming: Visual Studio
Visual Studio
There is a version of Visual Studio that can be installed for individual use, the Community version,
which can be downloaded for use associated with a Microsoft account.
A very important part of an application is its interface. The interface is responsible for
Página 1
capturing user input and, after certain processing, presenting the results properly. Windows replaced its
The way to define an interface is through the use of XAML, pronounced zammel in English, which
means eXtensible Application Markup Language. XAML is a declarative language based on XML and has
native support for editing in Visual Studio. The interface can be defined by dragging the components to
the standard window, or by textual editing of XAML.
Through this example, we will better understand the use of this technology. We will open Visual
Studio and start a new project.
The design options are presented. We must choose WPF App and choose the name “WpfToCSV”.
Página 2
The focus of this work is not WPF, therefore, it presents the complete code without going into
details about its syntax. It is interesting to start with the interface and then promote the logic, using the
interface components. Of course, this is indicated for coding when the project is ready, something that is
usually done with UML.
XAML code:
<Window x:Class="WpfToCSV.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfToCSV"
mc:Ignorable="d"
Title="Creating CSV" Height="170" Width="330">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
Página 3
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
C# code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using Microsoft.Win32;
namespace WpfToCSV {
Página 4
/// <summary>
/// Interaction logic for MainWindow.xaml
eTlipse - Computação, Engenharia e Responsabilidade Social Ltda.
www.etlipse.com | [email protected]
Developed by Joel Diniz and Edson Andrade
/// </summary>
public partial class MainWindow : Window {
// Global variables:
string arquivoNome;
public string ArquivoName { get { return arquivoNome;} set { arquivoNome =
value; } }
public MainWindow() {
InitializeComponent();
ArquivoName = "";
}
InitialDirectory = System.IO.Path.GetFullPath(CombinedPath),
Filter = "Rtf documents|*.rtf|Txt files (*.txt)|*.txt|Csv files
(*.csv)|*.csv|All files (*.*)|*.*",
FilterIndex = 3,
RestoreDirectory = true
};
saveFileDialog.ShowDialog();
if (saveFileDialog.FileName == "") {
MessageBox.Show("Invalid File ", "Save as ", MessageBoxButton.OK);
} else {
ArquivoName = saveFileDialog.FileName;
using (StreamWriter writer = new StreamWriter(ArquivoName)) {
writer.WriteLine("Element;Nivel;Material");
writer.WriteLine("Door:;{0};{1}", txtPortaNivel.Text,
txtPortaMaterial.Text);
writer.WriteLine("Window:;{0};{1}", txtJanelaNivel.Text,
txtJanelaMaterial.Text);
}
MessageBox.Show("File Saved Successfully!", "Save!",
MessageBoxButton.OK);
}
If everything goes without error, the window created as an interface is displayed and the program can be
tested.
Revit API
Development of plug-ins with Revit's API, Application Programming Interface, using the C #
language, from .Net, in Visual Studio.
We will use, as a resource, “Revit 2019” and “Visual Studio 2017” to develop our examples.
These two platforms can be downloaded in student version, for educational use.
Visual Studio must be optimized to work with C #, computational language, and use English as
a language, to better follow the examples.
Not all defined steps are indispensable for the functioning of all examples, but their definition is
important for good programming practice or even indispensable for specific examples.
We will use practical examples to understand the concepts needed to use the Revit API, with
the C # language, on the Visual Studio platform.
You can find specific help in the SDK, software development kit, of the API, available with the
installation of the Revit package, the SDK installer, which is only available in the installation files, found
in “C: \ Autodesk \ Revit_2019_G1_Win_64bit_dlm \ Utilities \ SDK \ RevitSDK.exe ”. The SDK
provides help, as well as examples and support files for development using the Revit API.
Página 6
There are several types of projects that can be created with Visual Studio. We will use Class
Library to create a plug-in for Revit.
A window for project definitions makes it possible to choose the standards to be used. We will
choose "Visual C #" for language, "Class Library" to generate a dll, dynamic link library. The project's
name will be “TreinaOlaRevit20180731”. We return to the main window, and the created project is
displayed.
Página 7
The wheel must not be reinvented in programming. We will make use of code libraries, which
contain the necessary code for reuse and assembly of our logic. The Revit API is contained in a dll,
dynamic link library, which are libraries with the description of the code needed to interact with Revit.
We need to add a reference to the libraries that we will use.
First, we will add the two dlls needed to use the Revit API, "RevitAPI.dll" and "RevitAPIUI.dll".
They are in the directory where our Revit is installed, possibly “C: \ Program Files \ Autodesk \ Revit
2019”.
We right-click on References from the Solution Explorer window. We select “Add Reference ...”
Página 8
Change the “Copy Local” parameter in Solution Explorer to false. This will prevent a copy of the
library from being copied to the folder whenever the program is copied.
Página 9
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
We added the directive that instructs about the transaction. Note that for updates, the
Automatic option is no longer supported:
[Transaction(TransactionMode.Manual)]
Página 10
A method, "Execute", will be added, and, once it returns "Result", we need to output this to our
code. We can comment on the code that throws the exception of not implementing the code with “//”.
We will use the output within a “try ... catch” structure, to handle exceptions.
This code of ours will only display a message in Revit using a normal text window, which can be
done with the code “TaskDialog.Show (" Revit "," Hello Revit! ");”.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
Página 11
[Transaction(TransactionMode.Manual)]
public class OlaRevit : IExternalCommand { // Class that will rise the dll for use
in Revit.
public Result Execute(ExternalCommandData commandData, ref string message,
ElementSet elements) { // Input method that implements the required API interface.
try {
TaskDialog.Show("Revit", " Hello Revit!"); //
Dialog box that will run if all goes well.
return Result.Succeeded; // Return that everything went well.
} catch (Exception ex) { // Exception handling.
message = ex.Message;
TaskDialog.Show("Error!",message);
return Result.Failed; // Error return.
// throw; // Code to be commented or removed.
}
//throw new NotImplementedException(); // Code to be commented or removed.
}
}
And see if we didn't get an error in the status bar . A warning screen
may appear, since we are not creating a program, and we have not assigned it to an application, which
can be configured to use Revit, but we will not do it here yet.
When we execute the project in this way, we will have the warning that the output cannot be
executed directly, since it is a dll, and that we would need an external program for that. To immediately
test the library, we can then configure Revit as the program to test the output.
Página 12
We must then the “Debug” tab, and then choose “Start external program:”. The "Browser" button
allows us to select the program that will be executed when we compile the project, in this case, Revit.
Navigate to the folder where Revit was installed and select the "Revit.exe" executable. A likely path will
be “C: \ Program Files \ Autodesk \ Revit 2019”.
Página 13
When Revit starts, it will check if there is a file, which we call a manifest, in your default plug-in
folder. If there is a file in this folder, Revit will interpret it. This is the way to allow the use of plug-ins in
Revit. If everything goes well with the interpretation, we will be notified of its loading, and we will have
to choose between not loading the dll, because this is a possibility of entry for viruses, loading only
once, or always loading. When we choose to always load, Revit will not give us warnings for loading
these plug-ins on the next starts. An example of a manifest is in the download area of eTlipse, website
https://www.etlipse.com/, which refers to the use of AddInManager, an application that makes it
possible to directly load plug-ins from the formed .dll.
We will create the file “TreinaOlaRevit20180731.addin”, which will contain the necessary
information for interpretation when starting Revit. This file will need to be in the Revit plug-ins folder,
in general, “C: \ Users \ [XXXX] \ AppData \ Roaming \ Autodesk \ Revit \ Addins \ 2020 \”, where
Página 14
Our file will be as shown below. Parentheses are used here only for comment, but obviously they
should not be contained in our manifest.
The plug-in Id must be unique, and can be generated in Visual Studio itself, under Tools>
Create GUID> 5. This is a number generated with a special algorithm to make it unlikely to coincide.
It is possible to automate the copy of the Manifest to the appropriate Revit folder, which
understands the plug-ins to be executed. We must access, in Visual Studio, the Project menu,
Properties submenu. In the project properties window, in the Built Events tab, Post-build box, we put
the directive below, which will depend on the Revit in use, in the example 2019.
copy "$ (TargetDir)". "" "$ (AppData) \ Autodesk \ Revit \ Addins \ 2019 \"
Página 15
We launch Revit, and we will get the warning we described. For testing it may be interesting not
to choose to always accept to run the plug-in.
Página 16
As intended, the execution, with the click on the item, will take us to the dialog screen with text
that we programmed.
We created a project in Visual Studio, called “AddPanel”, as in the first example. This time we will
need to add more references. We must add a reference to “PresentationCore”. The same must be done
to add “System.Xaml”.
Página 18
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.UI;
using Autodesk.Revit.DB;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.UI.Selection;
Página 19
using System.Windows.Media.Imaging;
[Transaction(TransactionMode.Manual)]
public class CsAddPanel : Autodesk.Revit.UI.IExternalApplication {
return Result.Succeeded;
}
return Result.Succeeded;
}
Some configurations are necessary to make use of the WPF interface with the Revit API, some
very specific and not so usual. ETLipse provides a specific template for this need, facilitating the use of
this important resource on the .Net platform.
The eTLipse template can be downloaded from the eTLipse page to be used in Visual Studio
and to facilitate the use and configuration of WPF applications using the Revit API. The template file
consists of a compressed file in .zip format that must be placed in the appropriate directory. It is
important to check the default directory used by the version in use of Visual Studio.
The configuration of the path used to load the templates is registered in the configuration menu.
Use the "Options ..." option in the "Tools" menu.
In the options window, we must choose the item “Projects and Solutions”, and, as a subtopic of
this option, we will have the item “Locations”. The path options will be displayed in “Projects Location”
in this same window, where we should observe the item “User Project templates location”.
Página 21
We can see that Visual Studio will present the eTLipse template as one of the options for a
new project, as shown in the following figure. We need to select the displayed option “TL Revit 2020
WPF Addin” and click on “Next”.
Página 22
Once you have built your application on the template, you can then compile your solution. The
project will open Revit and launch its solution. It is important to note that, for the protection of Revit,
the initial screen will be displayed to authorize the use of the application, which may only be for once,
forever, or may not allow loading. Finally, you can open a project in Revit and the created solution will
be in the menu that will have the name configured in the solution.
Página 24