debugging revit add-ins

image by archi-lab

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:

    1. Download and install Revit SDK. For version 2018 this is the link: Download
    2. 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:
    3. Paste them into your main Addins folder for Revit. That should be at C:\ProgramData\Autodesk\Revit\Addins\2018\
    4. 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:  
    5. 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. 
    6. 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.
    7. 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:
    8. 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…
    9. 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.

19 Comments

  1. Jorge says:

    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!

  2. Arif Hanif says:

    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.

      • Arif Hanif says:

        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().

  3. Arif Hanif says:

    Has anyone had issues with VS 2017 not hitting debug break points?

  4. Hi Konrad, thank you very much for this post, it is saving me a lot of time! Thanks.

  5. Dan Tartaglia says:

    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.

      • Dan Tartaglia says:

        Hi Konrad,

        Yes, I only brought it up because you mention in your article not to use the post build event.

        Thanks,
        Dan

Leave a Comment