Ok, so I always hear people complain, that writing Revit Addins is horrible because it takes forever to debug them. You know, that spiel about having to restart Revit, every time you make a change to your code. Well, the thing is that there was a solution to it out there for A LONG TIME. I am not sure why more people don’t use it, but it’s been talked about by people like Jeremy Tammik (Link) in 2011 and later by Matteo Cominetti (Link) in 2013. The point is that this has been out there for a while, and makes debugging Revit addins quite easy. Now this method runs a little contrary to something that I have posted a while ago about Post Build Commands and copying DLLs to Revit Addins folders automatically: Link
If you are going to follow this method, you should not be using the Post Build events. Let me explain the steps and you will see why:
-
- Download and install Revit SDK. For version 2018 this is the link: Download
- Once you install it, whatever location you chose there will be a folder called Add-Ins Manager there. Copy two (2) file from that folder:
- Paste them into your main Addins folder for Revit. That should be at C:\ProgramData\Autodesk\Revit\Addins\2018\
- You will have to also change the contents of the Addin Manifest file. It’s the file with the *.addin extension. Open it up and make sure that you delete the [TARGETDIR] from the <Assembly> line. Since our DLL is in the same folder that the manifest file, we can just leave there the name of the dll itself. Something like this:
- Now that we have everything setup we can launch Revit. One thing worth noting is that we NO LONGER need to copy any of the DLLs from the plugin that we are building into the Addins folders in Revit. Basically we want Revit NOT TO load it for us.
- Let’s load the DLL that we are interested in. The important part here is to use the Read Only* Mode. It will allow us to Rebuild our project in Visual Studio and reload it into Revit without shutting down Revit.
- Next up we can simply load the DLL we want to debug. The Add-In Manager will scan it for External Commands and list them for us:
- I know the image above has all the names blocked out, but it’s pretty straight forward to make out what’s going on. We can just use the Load button and point it at the DLL that we want to load in. It will contain all of the External Commands and they will get listed in the list box above. Now since we are pointing at the DLL that’s still in the visual studio’s BIN folder, we can basically just jump into Visual Studio, make changes, rebuild it, and then come back here, and it will automatically refresh itself. We can test out our changes without restarting Revit. That’s why it was important not to load any of the files via Addins folder anymore. We will let the addin manager handle it for us. Now if we want to Debug and step through the code, we can do that as well. Just open Visual Studio and go to Debug>Attach to Process…
- You would attach yourself to Revit.exe process, the one that is currently open, and if you launch any of the methods from the Add-In Manager via Run command, it will let you step through the code, given that there are breakpoints that were hit.
That’s it! You can now debug your Revit plugins much more effectively.
Cheers!
- It was brought to my attention that the three (3) different flavors of the Add-In Manager (Read Only, Manual and Manual Faceless) might actually be related to Transaction Modes. I am utterly confused at the moment, and have to concede that I don’t have a good explanation here, so I will instead offer to just look into this and amend this post when time comes that I have a good answer.
- I am going to take a guess that this has to do with the Transaction Mode. Autodesk recommends using Manual Transaction mode as Automatic is being phased out. I would say, contrary to my original image and recommendation in this post, use the Manual mode of the Add-In Manager. Read only is for read only transactions and if I understand it correctly it will prevent the model from being updated. This might in turn cause your method to fail if it actually tries to modify the model.
- Another interesting bit that came out recently is something that Dimitar Venkov discovered. If you have a plug-in that for example writes to Extensible Storage and takes advantage of Revit’s Schema functionality. It’s possible that when you were setting up the Schema settings, you set it to allow ONLY your plugin to write to it. That’s reasonable and understandable. However, what happens when we test the method with Add-in Manager is that it’s actually being called/accessed by the Add-In Manager and will fail. So either disable that functionality and make it publicly writable or setup Configurations for Debug/Release where this specific GUID changes from your plug-in to Add-in Manager.
- One more bit of information that came up when I was debugging this method. Since we are loading the DLL dynamically after Revit was initialized, and events like ‘OnStartup’, ‘OnDocumentOpened’ etc. came to pass before, they were never executed by our application. Think if it this way. Any code that you have running during startup, or any event handlers that get fired during startup would not be fired. This brings me to the gist of the issue here. If any of these events were used to perform certain actions, like register command overrides or retrieve and store some value on the Application class, would not be available to your commands. Please be aware of that.
Hi Konrad, nice article. Very useful, I’ve been looking this for a while. One thing to mention is that if your add-in has ribbons and buttons on it, this procedure doesn’t work, right? (hope I’m wrong here :) and there is a solution.)
CHeers and thanks again!
This is the solution.
Hi Konrad, I can’t get it done as you mentioned above. When I select the dll file i get the error from the image. What could it be?
Attachment: ADDIN-ERROR.png
I realized that this error only happens when selecting “read-only” add-in manager. I selected “Manual Mode” and works smoothly!.
Thanks a lot for this topic!
This error makes me think that whatever transaction mode you added to your ExternalCommands affects this tool. You probably want to match that. So the recommendation from Autodesk developers for all new versions of Revit is to use Manual Transaction mode like this: http://thebuildingcoder.typepad.com/blog/2012/05/read-only-and-automatic-transaction-modes.html Now I have to concede that I thought that the three (3) different flavors of the Add-In Manager were somehow related to how it loads the assembly in where the ReadOnly would use the byte array stream and hence not lock the file. I don’t know. I guess it’s related to transaction modes for the methods. Its good to know. I will test this out and amend my post.
if anyone gets a missing libraries error, like if you are using Restsharp, just use the load button to load that library in as well and that should work.
Great comment. I would only add that this could be caused by the fact that external references when added to Visual Studio solution were not marked as “Copy Local”. That would ensure that they get copied to the bin\ folder when solution is built, and later would be picked up by Add-In Manager.
I do have that setting but still have run into the issue with some libraries.
You mentioned RestSharp. Is it possible that it’s about a specific version of RestSharp? I can imagine Revit loading RestSharp into its context because some other plugin inside of Revit uses it, and once that file is loaded in, Revit will not load another version of it if it encounters such. This has specifically been an issue with libraries like Xceed.Toolkit where Revit has a really old version, and if I try to use a newer one it doesn’t care unless you specifically call Assembly.Load().
Has anyone had issues with VS 2017 not hitting debug break points?
Hi. I am, but with VS 2015.
Jorge,
I fixed the issue by changing the “Attach to:” method in debug from Auto to
Managed (v4.6, v4.5, v4.0) code and Managed Compatibility Mode.
This also requires your project Debug settings under “Debugger engines” to be set to Enable native code debugging.
Another thing worth mentioning here is to make sure to go to Options in Visual Studio and under Debugging check Use Managed Compatibility. So this is something that Revit requires for any kind of debugging. It’s been discussed here: https://forums.autodesk.com/t5/revit-api-forum/use-managed-compatibility-mode-or-enable-native-code-debugging/td-p/6868592 Basically Revit requires an older version of the debugger so it has to be enabled and obviously doesn’t support edit and continue functionality. Bummer.
Konrad,
Any idea how to reduce the symbols it processes feels like it does all the addins for me?
Explain “symbols”. I don’t know what you are asking about.
Hi Konrad, thank you very much for this post, it is saving me a lot of time! Thanks.
Hi Konrad,
I admit I’ve been creating add-ins for years and debug after Revit restarts. Question: How do you handle Digital Signatures? I normally set it up as a post build event while compiling.
Thanks,
Dan
By digital signatures you mean signing the DLLs with a certificate? Yes, you can do that in a post build using the signtool.exe. That can be done with a MSBuild target or via command line.
Hi Konrad,
Yes, I only brought it up because you mention in your article not to use the post build event.
Thanks,
Dan
The faceless option simply re-runs the last command that was picked until Revit is closed. It’s handy to put a keyboard shortcut on that to open your command without looking in the list first.