This tutorial is about writing your own addin. There are other tutorials out there. This tutorial is not about doing it the most simple way. There are Visual Studio templates out there that will set up most stuff for you (https://ekinssolutions.com/nifty_addin_template/). In this tutorial, we will set up everything manually. I want to show you all the settings. That has the advantage that you are not limited to specific settings, Inventor/Visual Studio versions or programming language.
I wanted you to have a functional and useful addin at the end of the tutorial. Also, I want you to be able to change the functionality easily. However, I did not want to spend too much time explaining the functionalities and code of what the addin does. Therefore I have chosen to change my iLogic rule “One Rule to Search Them All” (http://www.hjalte.nl/22-one-rule-to-search-them-all) into an addin. If you want to know more about this function you can just read about it in the blog post. Here I will only focus on creating an addin. To be fair you probably should never turn an iLogic rule into an addin so you have a button. Autodesk made that possible as a default option for iLogic rules.
Then why should you create addins? Most of the time I create addins in the following cases:
- The codebase for what I want is too big/complicated for an iLogic rule
- You need to present a cool-looking window to the user. (At least looking better than the windows we can make with iLogic)
- You need Inventor to react to events (other than the user pushing a button or the built-in events from iLogic).
In this tutorial, I show you how/where to write all your code. If you want to follow along but you get lost (or if you just want to look a the completed code.) Then you can find the entire project on my git hub page. (Download)
This isn’t a programming tutorial. So I expect that you have some programming experience. For example from creating iLogic rules.
Create a Visual Studio project
I assume that you have installed Visual Studio 2022. (Be aware that Visual Code is another programming IDE from Microsoft but you can't create addons with it.) This is not a tutorial on how to install Visual Studio. But some tips if you did not install it jet: you can download it here: https://visualstudio.microsoft.com/downloads/ Make sure you install everything to create .Net desktop applications. Also, include the .Net Core 8 runtimes.
Start Visual Studio (2022) and create a new project.
Make sure that you pick a project that targets the .Net core 8. Besides that, you have a couple of options.
First of all, you can select your language C# or VB.net. C# is the most commonly used .Net language. Therefore most information on the internet is about C#. That can be an advantage if you are looking for a solution to a programming problem. But if you have a problem with the inventor API then most answers/examples are written in VB.net (or VBA which is very similar) In this tutorial I will focus on VB.net because you can find more relevant information.
Your second choice is what kind of technologies you want to use in your forms. You have the following options: Winforms, WPF or none. Winform is the oldest technology but you will find a lot of information about it. (If you create/use custom controls in Winforms then you might run into trouble when you need your application to be 64bits. This is for example the case if you also start working with the vault API) With WPF forms you can do more (it’s more flexible) but they are more complicated to create. If you don’t want to create any forms then you can create a “Class Library”. Which is the most simple to set up. In this tutorial, I create a class library with WPF technology.
Setup the project
Delete the file “Class1.vb. (That probably means deleting all files in your solution explorer.)
Go to the “Add Project Reference...” screen.
Browse and select the following files:
C:\Program Files\Autodesk\Inventor [VERSION]\Bin\Autodesk.Inventor.Interop.dll
The following iLogic dll’s are only needed if you are going to use the iLogic function.
C:\Program Files\Autodesk\Inventor [VERSION]\Bin\Autodesk.iLogic.Interfaces.dll
C:\Program Files\Autodesk\Inventor [VERSION]\Bin\Autodesk.iLogic.Runtime.dll
For the Autodesk.Inventor.Interop.dll reference you need to set the properties “Embed Interop Types” to "False", “Copy Local” to "True".
For almost all addins you need the package "System.Drawing.Common". (The only situation I can think of that you don't need it, is when you don't use any icons or forms in your addin...) Therefore select "Tools", "NuGet package manager" and "Manage NuGet packages for solution..."
Search for the package "System.Drawing.Common" and install it for the projects in your solution.
Set compile events
When your addin is compiled then in needs to be installed so Inventor can use it. Go to the “Project Properties”.
Most likely the following settings are set correctly but it’s good to double-check the following settings.
Next, we need to make sure that the addin files are copied to the correct location. Addin files can go in a couple of places.
- All Users, Version Independent
- %ALLUSERSPROFILE%\Autodesk\Inventor Addins\
- All Users, Version Dependent
- %PROGRAMFILES%\Autodesk\Inventor 20xx\Bin\Addins\
- I noticed that you need local admin rights on your computer to write to this folder. If you don't have those "rights" then Visual Studio will stop the building process when you try to debug your addin!
- Per User, Version Dependent
- %APPDATA%\Autodesk\Inventor 20xx\Addins\
- Per User, Version Independent
- %APPDATA%\Autodesk\ApplicationPlugins
You need to copy at least the *.addin file and your addin dll file to one of these locations. You can do that by adding the following lines to the "Post-build events".
XCopy "$(TargetPath)" "[TARGET LOCATION]\$(TargetName)\" /Y /R
XCopy "$(ProjectDir)[YOUR ADDIN NAME].addin" "[TARGET LOCATION]\$(TargetName)\" /Y /R
Make sure you change the information between the [square brackets].
Set compile events (alternative)
There is an alternative for setting the “Compile events”. You can also set the “Output path”. That has the advantage that all files are copied automatically. (Instead of adding a line in the compile events for each file you want to copy.) The disadvantage is that Visual Studio will always create an extra folder named "net8.0-windows". In the GUI there is no setting to disable that behaviour. But you can disable that behaviour by editing the project file directly.
Now add the following lines after the first PropertyGroup
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>[TARGET LOCATION]\[YOUR ADDIN NAME]\</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>[TARGET LOCATION]\[YOUR ADDIN NAME]\</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
Make sure you change the information between the [square brackets].
Set Inventor as a startup program for debugging
Select "Debug" and then "[YOUR PROJECT] Debug Properties". (Or do some clicking)
Delete the existing profile.
After that, you will need to add a new “Executable debug profile”.
In this new profile, you can add the path to Inventor.
GUID
For the next files, you will need a GUID. This is an identification string used by Inventor. Multiple sites and tools can generate it for you. I usually use this site: https://www.guidgenerator.com/
Save the string for later use.
Addin file
For an addin you minimum need 2 files. The first one is the .addin file. With that file, you tell Inventor that you want it to load an addin. The information in that file are presented in the addin screen within Inventor.
Add a new file to the project. The name is not important as long the extension is “.addin”. Usually, you give it the same name as your addin. I will use “MyILogicAddin.addin”
Change the file properties of the addin file. It needs to be copied to the output path when the project is compiled.
Add the following (XML) code to the file:
<Addin Type="Standard">
<ClassId>{[GUID here]}</ClassId>
<ClientId>{[GUID here]}</ClientId>
<DisplayName>[Name]</DisplayName>
<Description>[Description]</Description>
<Assembly>[File name of the dll]</Assembly>
<SupportedSoftwareVersionGreaterThan>29..</SupportedSoftwareVersionGreaterThan>
</Addin>
The .addin file is a XML file. XML files are simple text files often used to save settings. All settings are saved in nested tags. A tag always has the form
<[TagName] [Properties]>[TagValue]</ [TagName]>
In the XML replace the text between the square brackets (also remove the square brackets). Most tags are self-explanatory but the following tags need a bit more attention.
In the “ClassId” and “ClientId” tags you need to put the GUID that we create earlier. Make sure that you remove the square brackets but leave the curly brackets.
In the “Assembly” tag put the file name of your addin dll. (You can find the name in your Visual Studio project settings. Don’t forget to add the extension “.dll”)
Here I left out a lot of tags that are not needed. For the full list have a look here: https://help.autodesk.com/view/INVNTOR/2025/ENU/?guid=GUID-52422162-1784-4E8F-B495-CDB7BE9987AB
Create the class StandardAddInServer
The second file each addin needs is the DLL (Dynamic-link library). This is the file with the compiled code. In this file, there should at least be 1 class, the "StandardAddInServer". This class is the entry point for Inventor. That means that when Inventor starts it reads your .addin file. Then it will load your dll and start looking for this class. When it has been found it will start calling functions in this class.
Add a Class to your project and call it “StandardAddInServer”
Add the following code to the file and change the GUID:
You see 4 functions/subs here (Activate(…), Deactivate(), ExecuteCommand(…), Automation()). We will only be using the “Activate” function. The others need to be there but don’t need to do anything.
In the “Activate” function we initialize the button class. Also, notice the try/catch block. By default, Inventor will not warn you if anything goes wrong while loading your addin. Therefore the try/catch block is needed to catch any exceptions that your code might throw and handle the exception. Here I just show the user a message box with the most basic information from the exception. (In production code, you might consider writing all the exception info to a log.) This will help you when something goes wrong and you need to find the problem. (And yes there will always be something wrong and then you need all the information that you can get!)
Button class
The button class creates a button in Inventor. Here we also write the code that is executed when the button is clicked. I called the class “MyButton” but you are free to call it anything. Just make sure you use the same name in the function “StandardAddInServer.Activate(…)”
Create a class “MyButton” and add the following code:
Imports Inventor
Public Class MyButton
Private _inventor As Inventor.Application
Private _settingsButton As ButtonDefinition
Public Sub New(inventor As Inventor.Application)
_inventor = inventor
SetupButtonDefinition()
AddButtonDefinitionToRibbon()
End Sub
Private Sub SetupButtonDefinition()
Dim conDefs As ControlDefinitions = _inventor.CommandManager.ControlDefinitions
_settingsButton = conDefs.AddButtonDefinition(
"MyButton DisplayName",
"MyButton InternalName",
CommandTypesEnum.kEditMaskCmdType,
Guid.NewGuid().ToString(),
"MyButton DescriptionText",
"MyButton ToolTipText")
AddHandler _settingsButton.OnExecute, AddressOf MyButton_OnExecute
End Sub
Private Sub AddButtonDefinitionToRibbon()
Dim ribbon As Ribbon = _inventor.UserInterfaceManager.Ribbons.Item("Assembly")
Dim ribbonTab As RibbonTab = ribbon.RibbonTabs.Item("id_TabManage")
Dim ribbonPanel As RibbonPanel = ribbonTab.RibbonPanels.Item("iLogic.RibbonPanel")
ribbonPanel.CommandControls.AddButton(_settingsButton)
End Sub
Private Sub MyButton_OnExecute(Context As NameValueMap)
Try
Dim rule As New ThisRule()
rule.ThisApplication = _inventor
rule.Main()
Catch ex As Exception
MsgBox("Something went wrong while runing rule. Message: " & ex.Message)
End Try
End Sub
End Class
When the button class is initialized the function “new” is called automatically. Here we call 2 other functions. You probably noticed that those functions are very short. They are so short that I could have added them to the “new” function. One of the problems of creating large programs is reading the code later again. Creating small functions with good descriptive names makes understanding the code later much easier. Also, it increases the chance that you can reuse the same code again for other purposes.
In the “SetupButtonDefinition” function you can change “DisplayName”, “InternalName”, “DescriptionText” and “ToolTipText” of the button that we are creating. There we also define which function should get called “MyButton_OnExecute”.
In the “AddButtonDefinitionToRibbon” we define where the button needs to go. We start by selecting the “Ribbon”. I have chosen the “Part” ribbon but you can choose 1 of the following options: ZeroDoc, Part, Assembly, Drawing, Presentation, iFeatures and UnknownDocument. Then we need to specify the internal name of the “RibbonTab” and “RibbonPanel”. There are too many options to print here but the following illogic rule will print them in the ilogic log.
For Each ribbon As Ribbon In ThisApplication.UserInterfaceManager.Ribbons
Logger.Info(vbTab & Ribbon.InternalName)
For Each ribbonTab As RibbonTab In Ribbon.RibbonTabs
Logger.Info(vbTab & vbTab & RibbonTab.DisplayName & " - " & RibbonTab.InternalName)
For Each ribbonPanel As RibbonPanel In RibbonTab.RibbonPanels
Logger.Info(vbTab & vbTab & vbTab & RibbonPanel.DisplayName & " - " & RibbonPanel.InternalName)
Next
Next
Next
Dim loggerWindow = ThisApplication.UserInterfaceManager.
DockableWindows.
Cast(Of DockableWindow).
Where(Function(d) d.InternalName.Equals("ilogic.logwindow")).
First()
loggerWindow.Visible = True
In my case, my button is only visible in the assembly environment. The button is on the “Manage” tap in the “iLogic” panel.
As managed the function “MyButton_OnExecute” is called when the button is clicked. Here we initialize the class “ThisRule” that does the real work.
Abstract rule class
We are going to emulate iLogic. This means that we need some default illogic functions at our disposal in the rule class. If you at any point want to create a second button then you probably don’t want to implement the same logic twice. (At least I would not like it, maybe I'm a bit lazy…) Also, I want to be able to copy iLogic code as is to my addin. Therefore I chose to create an abstract class and inherit all functions in the base class in the rule class. For now, this base class is very small and there are only 2 properties. In most cases, it is sufficient to only have access to the iLogic property “ThisApplication” and “ThisDoc”
Create a class “AbstractRule” and add the following code:
Imports Autodesk.iLogic.Interfaces
Imports Autodesk.iLogic.Runtime
Imports Inventor
Public MustInherit Class AbstractRule
Public Property ThisApplication As Inventor.Application
Public ReadOnly Property ThisDoc As ICadDoc
Get
Return New CadDoc(ThisApplication.ActiveDocument)
End Get
End Property
End Class
Rule class
This is the class that will hold the iLogic rule. In this example, I will be able to copy/paste an iLogic rule from Inventor to the class. (Just remember we did not implement all iLogic functions/properties. Your code might not work if you copy one of your rules. In that case, you need to implement your functions to emulate the iLogic functions)
Create a class “ThisRule” and add the following code:
Imports Inventor
Public Class ThisRule
Inherits AbstractRule
Public Sub Main()
' Your iLogic code goes here.
End Sub
End Class
Notice line 4, this is where we tell the compiler to inherit the base class. In the more complicated rules, you will have more functions or even a whole class. Then you might need to add also code outside of the main function.
To end this tutorial with a functional/working addin we will replace the class code with the rule “One Rule to Search Them All”. The class “ThisRule” will then look like this.
Imports Inventor
Public Class ThisRule
Inherits AbstractRule
Private searchText As String
Private iLogicAddinGuid As String = "{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}"
Private iLogicAddin As ApplicationAddIn = Nothing
Private iLogicAutomation = Nothing
Private outputFile As String = "c:\TEMP\seachedRules.txt"
Sub Main()
If (IO.File.Exists(outputFile)) Then
IO.File.Delete(outputFile)
End If
searchText = InputBox("Text to search for", "Search")
iLogicAddin = ThisApplication.ApplicationAddIns.ItemById(
"{3bdd8d79-2179-4b11-8a5a-257b1c0263ac}")
iLogicAutomation = iLogicAddin.Automation
Dim doc As AssemblyDocument = ThisDoc.Document
searchDoc(doc)
For Each refDoc As Document In doc.AllReferencedDocuments
searchDoc(refDoc)
Next
Process.Start("notepad.exe", outputFile)
End Sub
Private Sub searchDoc(doc As Document)
Dim rules = iLogicAutomation.Rules(doc)
If (rules Is Nothing) Then Return
For Each rule In rules
Dim strReader As IO.StringReader = New IO.StringReader(rule.Text)
Dim i As Integer = 1
Do While (True)
Dim line As String
line = strReader.ReadLine()
If line Is Nothing Then Exit Do
If (line.ToUpper().Contains(searchText.ToUpper())) Then
Dim nl = System.Environment.NewLine
IO.File.AppendAllText(outputFile,
"Doc name : " & doc.DisplayName & nl &
"Rule name: " & rule.Name & nl &
"line " & i & " : " & line.Trim() & nl & nl)
End If
i = i + 1
Loop
Next
End Sub
End Class
Now press "Run" (or press F5) in Visual Studio and try your addin!