This posting assumes you have a VBA auto macro and want to quit using the auto macro functionality and convert it to an add-in. See the previous posting VBA Document Projects as to why you might want to do this. Without a lot of explanation, here are the prerequisites and the steps required to create the add-in.
Here is an example of an automatic macro that exists within a drawing document. It automatically writes out dwf and pdf files of the drawing whenever the drawing is saved. The rest of this post looks at the process to create an add-in to replace this auto macro.
' Get the filename minus the extension.
Dim strFilename As String
strFilename = ThisDocument.FullFileName
strFilename = Left(strFilename, Len(strFilename) - 4)
' Save the current SilentOperation and then turn it on.
' This will suppress the dwf viewer from being displayed.
Dim currentSetting As Boolean
currentSetting = ThisApplication.SilentOperation
ThisApplication.SilentOperation = True
' Save the file as dwf.
Call ThisDocument.SaveAs(strFilename & ".dwf", True)
' Reset SilentOperation back to its previous value.
ThisApplication.SilentOperation = currentSetting
' Save the file as pdf.
Call ThisDocument.SaveAs(strFilename & ".pdf", True)
End Sub
What You'll Need
A Programming Language - To write an add-in you need to use a language that supports creating COM components. For this example I'll illustrate the process using both Visual Basic 2008 and C# 2008. Microsoft provides free Express versions of both of these languages. You can install them from the Microsoft web site. Microsoft also provides online training resources for learning these languages. If this is all new to you and you don't know which one to get I would recommend Visual Basic, but it really is a personal preference.
Inventor SDK Developer Tools - You'll also need some Inventor specific development tools. This is delivered when you install Inventor but you need to run its setup to install it. Assuming you're using Inventor 2009, locate the following file in Explorer and run it:
C:\Program Files\Autodesk\Inventor 2009\SDK\DeveloperTools.msi
Inventor 2009 was released when Visual Studio 2005 was the current development platform. Because of that the Add-In wizard provided with it does not get installed for use with Visual Studio 2008. To work around this you can copy the files below to the specified directories. Don't unzip the files but just copy the file as-is.
VB 2008
Copy VBInventorAddInTemplate.zip to
"My Documents\Visual Studio 2008\Templates\ProjectTemplates"C# 2008
Copy VCSInventorAddInTemplate.zip to
"My Documents\Visual Studio 2008\Templates\ProjectTemplates"
Creating the Add-In
The add-in is created using the add-in template. Start VB or C# and choose to create a new project. For the template choose "Autodesk Inventor AddIn", as shown below. You can also specify the name of the add-in at this point, ("AutoSaveAddIn" in the example below).
In the Visual Studio Solution Explorer you'll see the various files listed that were created for the project. For a Visual Basic add-in, most of the code is in the StandardAddInServer.vb file and for a C# add-in it is in the StandardAddInServer.cs file. Double-click on this file to open it in the code editor. You should see something very similar to one of the pictures below. Your GuidAttribute value will be different than those shown below since that is unique for every add-in.
Editing the Name and Description of the Add-In
One common thing you'll want to do when creating an add-in is to define the name and description of the add-in as it will be seen in the Add-In Manager. You do this by editing the code in the "COM Registration" block of the code. Click on the "+" next to this region to expand it. The code in red is the portion I've changed to modify the name and the description. The code below is from the VB add-in but the C# code is almost identical and it will be obvious what to edit.
Dim clssRoot As RegistryKey = Registry.ClassesRoot
Dim clsid As RegistryKey = Nothing
Dim subKey As RegistryKey = Nothing
Try
clsid = clssRoot.CreateSubKey("CLSID\" + AddInGuid(t))
clsid.SetValue(Nothing, "Automated DWF and PDF Save")
subKey = clsid.CreateSubKey( _
"Implemented Categories\{39AD2B5C-7A29-11D6-8E0A-0010B541CAA8}")
subKey.Close() subKey = clsid.CreateSubKey("Settings")
subKey.SetValue("AddInType", "Standard")
subKey.SetValue("LoadOnStartUp", "1")
'subKey.SetValue("SupportedSoftwareVersionLessThan", "")
subKey.SetValue("SupportedSoftwareVersionGreaterThan", "12..")
'subKey.SetValue("SupportedSoftwareVersionEqualTo", "")
'subKey.SetValue("SupportedSoftwareVersionNotEqualTo", "")
'subKey.SetValue("Hidden", "0")
'subKey.SetValue("UserUnloadable", "1")
subKey.SetValue("Version", 0)
subKey.Close()
subKey = clsid.CreateSubKey("Description")
subKey.SetValue(Nothing, "Saves drawings as DWF and PDF.")
Catch ex As Exception
System.Diagnostics.Trace.Assert(False)
Finally
If Not subKey Is Nothing Then subKey.Close()
If Not clsid Is Nothing Then clsid.Close()
If Not clssRoot Is Nothing Then clssRoot.Close()
End Try
End Sub
Reacting to Events in Visual Basic
Now we can add the code that will react anytime a document is saved. For a VB add-in, add the code below that's shown in red. The second line is in the "ApplicationAddInServer Members" code region so you'll need to expand that region to see the code. The code consists of a declaration and an assignment.
Implements Inventor.ApplicationAddInServer
' Inventor application object.
Private m_inventorApplication As Inventor.Application
Private WithEvents m_appEvents As Inventor.ApplicationEvents
#Region "ApplicationAddInServer Members"
Public Sub Activate( _
ByVal firstTime As Boolean) _
' Initialize AddIn members.
m_inventorApplication = addInSiteObject.Application
m_appEvents = m_inventorApplication.ApplicationEvents
End Sub
At the top of the code window are two combo boxes. The one on the left displays a list of classes and the one on the right displays a list of methods for the selected class. Choose "m_appEvents" on the left and "OnSaveDocument" on the right, as shown below. This will insert the sub m_appEvents_OnsaveDocument as shown below. This is the event handler for the OnSaveDocument event will be called whenever a document is saved in Inventor.
Here's code that's equivalent to the original AutoSave macro. This performs a couple of additional checks that the original automatic macro didn't need to do. First, the OnSaveDocument is fired before and after the document is actually saved. This listens for when the event is fired after the Inventor save. The event is also fired whenever any document is saved. This looks for and only handles drawing documents.
ByVal DocumentObject As Inventor._Document, _
ByVal BeforeOrAfter As Inventor.EventTimingEnum, _
ByVal Context As Inventor.NameValueMap, _
ByRef HandlingCode As Inventor.HandlingCodeEnum) _
Handles m_appEvents.OnSaveDocument
If BeforeOrAfter = EventTimingEnum.kAfter Then
If DocumentObject.DocumentType = DocumentTypeEnum.kDrawingDocumentObject Then
' Get the filename minus the extension.
Dim filename As String
filename = DocumentObject.FullFileName
filename = Left(filename, Len(filename) - 4)
' Save the current SilentOperation and then turn it on.
' This will suppress the dwf viewer from being displayed.
Dim currentSetting As Boolean
currentSetting = m_inventorApplication.SilentOperation
m_inventorApplication.SilentOperation = True
' Save the file as dwf.
DocumentObject.SaveAs(filename & ".dwf", True)
' Save the file as pdf.
DocumentObject.SaveAs(filename & ".pdf", True)
' Reset SilentOperation back to its previous value.
m_inventorApplication.SilentOperation = currentSetting
End If
End If
End Sub
Reacting to Events in C#
The code highlighted in red below was added to support handling the save event in C#. The last two lines are in the "ApplicationAddInServer Members" code region so you'll need to expand that region to see the code. The line where the delegate is created to handle the event is mostly created by using Intellisense. Go slowly as you type and you'll see options pop up that allow you to press the tab key to create much of the code.
private Inventor.ApplicationEvents m_appEvents = null;
public StandardAddInServer()
{
}
#region ApplicationAddInServer Members
public void Activate(
{
// Initialize AddIn members.
m_inventorApplication = addInSiteObject.Application;
m_appEvents = m_inventorApplication.ApplicationEvents;
// Create the delegate object to handle the event.
m_appEvents.OnSaveDocument += new
ApplicationEventsSink_OnSaveDocumentEventHandler(
}
Intellisense can also create the event implementation code as you're typing the line above. Below is the code it created with the additional code in red that I added to save the dwf and pdf files.
{
// A value has to be returned for the handling code.
HandlingCode = HandlingCodeEnum.kEventNotHandled;
if (BeforeOrAfter == EventTimingEnum.kAfter)
{
if (DocumentObject.DocumentType == DocumentTypeEnum.kDrawingDocumentObject)
{
// Get the filename minus the extension.
String filename = DocumentObject.FullFileName;
filename = filename.Substring(0, filename.Length - 4);
// Save the current SilentOperation and then turn it on.
// This will suppress the dwf viewer from being displayed.
Boolean currentSetting = m_inventorApplication.SilentOperation;
m_inventorApplication.SilentOperation = true;
// Save the file as dwf.
DocumentObject.SaveAs(filename + ".dwf", true);
// Save the file as pdf.
DocumentObject.SaveAs(filename + ".pdf", true);
// Reset SilentOperation back to its previous value.
m_inventorApplication.SilentOperation = currentSetting;
}
}
}
Cleaning Up
Finally, just a bit of code to clean up everything when the add-in is unloaded. This is in the Deactivate method of the add-in. The code I added is in red.
' Release objects.
Marshal.ReleaseComObject(m_appEvents)
m_appEvents = Nothing
Marshal.ReleaseComObject(m_inventorApplication)
m_inventorApplication = Nothing
System.GC.WaitForPendingFinalizers()
System.GC.Collect()
End Sub
Here's the equivalent code for C#.
{
// Disconnect the event delegate.
m_appEvents.OnSaveDocument -= new
ApplicationEventsSink_OnSaveDocumentEventHandler(
// Release objects.
Marshal.ReleaseComObject(m_appEvents);
m_appEvents = null;
Marshal.ReleaseComObject(m_inventorApplication);
m_inventorApplication = null;
GC.WaitForPendingFinalizers();
GC.Collect();
}
Using the Add-In
Now all you need to do is build the add-in. Building the add-in creates the dll and also registers it. When you run Inventor you should see the add-in in the Add-In Manager and when you save a drawing document the corresponding pdf and dwf files will also be created.
To use the add-in on another computer you need to copy the add-in dll to that computer and register it. Below are some commands you can use within .bat files to both register and unregister the add-in for 32 and 64-bit installations.
Register on 32-bit
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe /codebase AutoSaveAddIn.dll
PAUSE
Unregister on 32-bit
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe /unregister AutoSaveAddIn.dll
PAUSE
Register on 64-bit
C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\RegAsm.exe /codebase AutoSaveAddIn.dll
PAUSE
Unregister on 64-bit
C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\RegAsm.exe /unregister AutoSaveAddIn.dll
PAUSE
When you test the add-in you can't just open an existing drawing, immediately save it, and expect to see the dwf and pdf files. The reason is because the drawing hasn't changed so clicking the save button doesn't do anything. If you make any change to the drawing, i.e. edit an iProperty or move a view or dimension, the OnSaveDocument event is fired and the additional files will be created.

Subscribe
Man I've been doing this the hard way, I've got about 100 lines to do this!
Thanks for the post Brian. I will have a play and see what happens.
Cheers
Jon
Posted by: Jon Brabbs | October 03, 2008 at 12:10 AM
Hi,
I realise I'm a little late joining the party on this, but I was wondering if the template you've created can be used with the Express 2008 versions of both C# and VB.NET?
Cheers,
Alex.
Posted by: AlexF | November 06, 2008 at 03:11 AM
Brian,
I ran thru this example using C# and it builds successfully, but I have to manually register the dll to get Inventor to see it. I am running Vista64 / Inventor 2009 64 bit. Do I need to do anything different for the 64 bit vs the 32?
Just got back from AU - had a great time!
Thanks,
Bob
Posted by: Bob Collins | December 10, 2008 at 08:48 PM
Brian,
Great code. This will come in handy. A question though, is there a way to generated a pdf\dwf of all the sheets in the IDW file. I noticed that it only publishes the current sheet.
Thanks,
Dan
-----------
See the posting http://modthemachine.typepad.com/my_weblog/2009/01/translating-files-with-the-api.html
-Brian
Posted by: DanV | January 14, 2009 at 08:56 AM
Hi Brian,
Thank you for posting this and all the other great tips. Is it possible to see the conversion of a VBA form to a VB Add-in?
Thanks,
Tim
Posted by: Tim Straz | February 16, 2009 at 02:59 PM
Hi Brian,
(AutoSave DWF/PDF)
If I want to place the DWF/PDF in a particular folder fx. T:\InvDrw.. How do i do that..?
Posted by: Peter Bosse | April 08, 2009 at 04:39 AM
The full filename of the file to create is being defined in the program. You set this to anything you would like. In the sample it's getting the full filename of the document being saved and modifying the extension.
Dim filename As String
filename = DocumentObject.FullFileName
filename = Left(filename, Len(filename) - 4)
It could be changed to something like this:
Dim filename As String
filename = "T:\InvDrw\Myfile.dwf"
Posted by: Brian Ekins | April 13, 2009 at 02:51 PM
Is it necessary for me to register (using RegAsm) any custom assemblies that my add-in class references?
Here is the problem I am having:
I am have created an add-in to Inventor 2009(in C#) and I am in the process of debugging it. My add-in uses classes that are defined in other custom assemblies that I have created to be used with the add-in. When I register the add-in, run Inventor, and click on my created add-in button, I sometimes get exceptions stating that my add-in cannot find the custom assemblies that are needed in order for it to run, although the assemblies are in the same directory as the add-in .dll and are of the correct version.
Posted by: AlvaA | May 01, 2009 at 12:09 PM
I have the expresss version of visual basic. I build a project in 32 bit and it works. I build it on a 64 bit machine and it doesn't show in the addins. I tried to manually registering it per your bat setup, got a successful register and it still does not show. What am I missing.
Posted by: Randy | May 26, 2009 at 09:49 AM
What I was missing was the name it was published with. It is there and works great.
Thanks
Posted by: Randy | May 26, 2009 at 11:25 AM
Hi Brian, I built the project and I regoster i on 32 bit, but it does not work in Inventor (I'm using 2008 version). What am I missing? Is it right if the dll is not in the bin directory of Inventor?
thanks
Enrico
Posted by: Enrico Lucchetti | June 14, 2009 at 10:23 AM
Hi Brian,
The "StandardAddInServer" gives me errors when I open the the template in vb2008. Any idea what's happening here?
Jon
Posted by: Jon Holler | November 08, 2009 at 03:25 PM