Create a Plugin in Revit 2026 with .NET8 API
Quick Summary: Setting up development environment.
1. Context / Introduction
Overview: Revit Plugin Types
External Commands - Commands invoked from Add-in Tab and implements - IExternalCommand interface
External Applications - programmatically add or modify the UI (for instance, create custom ribbon tabs, panels, and buttons) and implements the IExternalApplication interface.
Transaction - In Revit, any operation that modifies a document must be executed within a transaction. A transaction is a set of actions that can be committed or rolled back as one unit, ensuring consistency in the document.
Transaction Modes: - When you decorate an external command class with the [Transaction] attribute, you specify the intended transaction mode. The available modes include:
- ReadOnly: Indicates that the command will not make any changes to the document. This is useful for commands that only read or display information.
- Manual: Requires you to manually start, commit, or roll back a transaction within your code if you intend to make changes.
- ReadWrite (not used in the examples): Automatically starts and commits a transaction if you’re making changes to the document.
2. Example: External Applications
Folder Organization
A typical folder structure might look like this: MyRevitPlugins/
├── MyRevitPlugins.sln
├── addins/
└── MyCustomRibbonApp.addin
└── MyRevitPlugins/
├── App.cs
├── CommandOne.cs
├── CommandTwo.cs
├── CommandThree.cs
└── MyRevitPlugins.csproj
MyRevitPlugins.sln: The solution file.
MyRevitPlugins.csproj: The project file for the assembly containing both the external application and the commands.
addins/MyCustomRibbonApp.addin: The Revit manifest file that tells Revit to load your external application when it starts.
App.cs: Contains your ribbon creator class (the external application).
CommandOne.cs, CommandTwo.cs, CommandThree.cs: Each of these defines a separate command.
Code snippet:
A. External Application – App.cs This class creates a custom ribbon tab and adds three buttons, each wired to an external command.
C# using Autodesk.Revit.UI; using System; using System.Reflection; namespace MyRevitPlugins { public class App : IExternalApplication { public Result OnStartup(UIControlledApplication application) { string tabName = "My Custom Tab"; // Create a custom ribbon tab (ignore error if already exists) try { application.CreateRibbonTab(tabName); } catch (Exception) { // If the tab already exists, you can ignore or log the exception. } // Create a panel on the custom tab RibbonPanel panel = application.CreateRibbonPanel(tabName, "My Commands"); // Get the path to this assembly string assemblyPath = Assembly.GetExecutingAssembly().Location; // Add Command One button PushButtonData btnData1 = new PushButtonData( "CommandOne", "Command One", assemblyPath, "MyRevitPlugins.CommandOne"); btnData1.ToolTip = "Executes Command One."; panel.AddItem(btnData1); // Add Command Two button PushButtonData btnData2 = new PushButtonData( "CommandTwo", "Command Two", assemblyPath, "MyRevitPlugins.CommandTwo"); btnData2.ToolTip = "Executes Command Two."; panel.AddItem(btnData2); // Add Command Three button PushButtonData btnData3 = new PushButtonData( "CommandThree", "Command Three", assemblyPath, "MyRevitPlugins.CommandThree"); btnData3.ToolTip = "Executes Command Three."; panel.AddItem(btnData3); return Result.Succeeded; } public Result OnShutdown(UIControlledApplication application) { // Clean-up can be performed here. return Result.Succeeded; } } }
External Command One – CommandOne.cs
This command simply shows a message dialog when executed.
using Autodesk.Revit.UI; using Autodesk.Revit.DB; using Autodesk.Revit.Attributes; namespace MyRevitPlugins { [Transaction(TransactionMode.ReadOnly)] public class CommandOne : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { TaskDialog.Show("Command One", "Command One executed successfully."); return Result.Succeeded; } } }
External Command Two – CommandTwo.cs
A similar command with its own message.
using Autodesk.Revit.UI; using Autodesk.Revit.DB; using Autodesk.Revit.Attributes; namespace MyRevitPlugins { [Transaction(TransactionMode.ReadOnly)] public class CommandTwo : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { TaskDialog.Show("Command Two", "Command Two executed successfully."); return Result.Succeeded; } } }
External Command Three – CommandThree.cs
And the third command:
using Autodesk.Revit.UI; using Autodesk.Revit.DB; using Autodesk.Revit.Attributes; namespace MyRevitPlugins { [Transaction(TransactionMode.ReadOnly)] public class CommandThree : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { TaskDialog.Show("Command Three", "Command Three executed successfully."); return Result.Succeeded; } } }
Add‑in Manifest File – MyCustomRibbonApp.addin
This XML file registers your external application with Revit. Place it in the “addins” folder (or copy it to the proper Revit add‑ins folder during build/deployment).
<?xml version="1.0" encoding="utf-8" standalone="no"?> <RevitAddIns> <AddIn Type="Application"> <Name>My Custom Ribbon App</Name> <Assembly>MyRevitPlugins.dll</Assembly> <FullClassName>MyRevitPlugins.App</FullClassName> <AddInId>INSERT-YOUR-GUID-HERE</AddInId> <VendorId>YourVendorID</VendorId> <VendorDescription>Your Vendor Description</VendorDescription> <VendorEmail>youremail@example.com</VendorEmail> </AddIn> </RevitAddIns>