Support multiple versions of Revit in invokebuttons (dll projects, Visual Studio)

Hey guys!

Here at Woods Bagot we have our Wombat plugin that is a mix of script files (script.cs and .py) and a few DLLs that come from VS solutions and then invoked by a few .inovkebutton

To give you a very simple example, let’s say that I need to create a ParameterType object. In Revit 2020 I’d need to use this line of code: ParameterType parameterType = ParameterType.Text; which would although fail in Revit 2023, as I now need to use SpecTypeId.String.Text

How can I deal with API changes between versions of Revit, from my VS solution?
I know I can use conditions in my .csproj (i.e. The Building Coder: Multi-Targeting Revit Versions, CAD Terms, Textures) or I could use shared projects in VS (i.e. https://archi-lab.net/how-to-maintain-revit-plugins-for-multiple-versions-continued/), but I don’t think this would be effective for pyRevit (as I’m not targeting Revit directly), would it?

What would be the best way to do this?

One thing I can think of, is creating 2 projects in my VS solution. Let’s call them Wombat2020 and Wombat2023. And then, reference the Revit 2020 APIs in the Wombat2020 project and the Revit 2023 APIs in the Wombat2023 project. In this way I will be creating 2 distinct DLLs in the lib folder (Wombat2020.dll and Wombat2023.dll) that reference 2 different APIs. Then I could use the revit version property in the bundle.yaml to enable/disable the commands that invoke the 2 libraries accordingly.

Although, this sounds a bit painful, especially if you have to change just one line of code in a command.
Is there a better way?

2 Likes

I prefer to just gather the version info at the start of your code. And from there just “if then” inside your code for two different functions. I think this is still the simplest way even for pyRevit files. Having two dll files to maintain sounds like a pain. (Compile, Test, Rinse, Repeat, Repeat, Repeat) Which is why I’ve moved away from any complied code for our office of 25. Just too much overhead for stuff you want to continue to develop and improve. But this is all probably more a question of style and workflow more than what is the best.

Thanks for your reply @aaronrumple !

Unfortunately in a VS project you cannot load multiple versions of the same API without making a mess :smiley: (or at least I’m not aware of how to do that?) and just decide which version of the API to use depending on the version of Revit.
You’re probably able to do that in a simple script (I mean the .pushbutton scenario), but if you have a more complex codebase, you need to have a C# project.

Thinking out loud here, and I have never looked at how the pyRevit C# side is coded, but I think that looking at it may give you a cue and maybe a way to solve it?

I mean, maybe (not entirely sure actually), but it’s kinda like going through a mechanical engineering degree when you have to change your car’s oil…surely you’ll do a proper job, but would you say it was an overkill? :smiley:

Unless I’m missing something, I’m afraid that you cannot work around the need to package 2 different dlls, that’s the way it is with .NET (and any other compiled programming languages I dare say).
pyRevit Itself has solutions for each supported revit versions.

The two options I see are:

  • move away from pyrevit and package a proper revit .NET add-in, targeting the various revit versions as explained int the posts you linked
  • move away from .NET and rewrite the wombat library in python, using HOST_APP.is_newer_than() to handle the different calls