This guide explains the step-by-step process to add support for a new Revit version to pyRevit.
Before starting, gather the following information:
- Revit Version Year (e.g., 2028)
- Target .NET Framework:
- Revit 2021-2024:
net48 - Revit 2025-2026:
net8.0-windows - Revit 2027+:
net10.0-windows
- Revit 2021-2024:
- Check if a new .NET version is required - If the new Revit uses a different .NET version than previous releases, additional steps are needed (see sections 4 and 5)
Create a new runtime project for the Revit version.
cd dev/pyRevitLabs.PyRevit.Runtime
cp -r 2027 2028Rename pyRevitLabs.PyRevit.Runtime.2027.csproj to pyRevitLabs.PyRevit.Runtime.2028.csproj and update its contents:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<UseWpf>true</UseWpf>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<PropertyGroup>
<RevitVersion>2028</RevitVersion>
<TargetFramework>net10.0-windows</TargetFramework>
</PropertyGroup>
</Project>!!! note
Adjust the TargetFramework based on which .NET version the new Revit uses.
Edit dev/Directory.Build.targets and add a new PropertyGroup for the version constants:
<PropertyGroup Condition="'$(RevitVersion)' == '2028'">
<DefineConstants>$(DefineConstants);REVIT2028;REVIT2021_OR_GREATER;REVIT2022_OR_GREATER</DefineConstants>
</PropertyGroup>If the new Revit uses a new .NET version, add a mapping in the NetFolder section:
<PropertyGroup>
<NetFolder Condition="'$(TargetFramework)' == 'net48'">netfx</NetFolder>
<NetFolder Condition="'$(TargetFramework)' == 'net8.0-windows'">netcore</NetFolder>
<NetFolder Condition="'$(TargetFramework)' == 'net10.0-windows'">netcore</NetFolder>
<!-- Add new framework mapping here if needed -->
</PropertyGroup><PropertyGroup>
<RevitVersion Condition="'$(RevitVersion)' == '' and '$(TargetFramework)' == 'net48'">2021</RevitVersion>
<RevitVersion Condition="'$(RevitVersion)' == '' and '$(TargetFramework)' == 'net8.0-windows'">2025</RevitVersion>
<RevitVersion Condition="'$(RevitVersion)' == '' and '$(TargetFramework)' == 'net10.0-windows'">2027</RevitVersion>
<!-- Add new default here if needed -->
</PropertyGroup>Copy the Xceed.Wpf.AvalonDock.dll from the previous version:
mkdir dev/libs/Revit/2028
cp dev/libs/Revit/2027/Xceed.Wpf.AvalonDock.dll dev/libs/Revit/2028/This DLL is required for the dockable console functionality in supported Revit versions.
Add entries for the new Revit builds in release/pyrevit-hosts.json. CI copies this file into bin/ at build time.
Example entry:
{
"build": "20270115_1200",
"meta": {
"schema": "1.0",
"source": "https://www.autodesk.com/support/technical/article/..."
},
"notes": "",
"product": "Autodesk Revit",
"release": "Revit 2028",
"target": "x64",
"version": "28.0.0.0"
}!!! note Build numbers are released by Autodesk with each update. Add new entries as updates are released.
If the new Revit requires a new .NET version, update the GitHub Actions workflow.
Edit .github/workflows/ci.yml (and wip.yml / release.yml if they install their own SDKs) and add a new setup step:
- name: Prepare .NET XX.0
uses: actions/setup-dotnet@v5
with:
dotnet-version: XX.0.xEdit release/CodeDependencies.iss and add new procedures for the .NET runtime.
Copy the latest procedures from the upstream InnoDependencyInstaller repository. Look for procedures like Dependency_AddDotNetXX0 and Dependency_AddDotNetXX0Desktop.
Example (based on .NET 10):
procedure Dependency_AddDotNet110;
begin
// https://dotnet.microsoft.com/download/dotnet/11.0
if not Dependency_IsNetCoreInstalled('Microsoft.NETCore.App', 11, 0, 0) then begin
Dependency_Add('dotnet110' + Dependency_ArchSuffix + '.exe',
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
'.NET Runtime 11.0.0' + Dependency_ArchTitle,
Dependency_String('https://builds.dotnet.microsoft.com/dotnet/Runtime/11.0.0/dotnet-runtime-11.0.0-win-x86.exe', 'https://builds.dotnet.microsoft.com/dotnet/Runtime/11.0.0/dotnet-runtime-11.0.0-win-x64.exe'),
'', False, False);
end;
end;
procedure Dependency_AddDotNet110Desktop;
begin
// https://dotnet.microsoft.com/download/dotnet/11.0
if not Dependency_IsNetCoreInstalled('Microsoft.WindowsDesktop.App', 11, 0, 0) then begin
Dependency_Add('dotnet110desktop' + Dependency_ArchSuffix + '.exe',
'/lcid ' + IntToStr(GetUILanguage) + ' /passive /norestart',
'.NET Desktop Runtime 11.0.0' + Dependency_ArchTitle,
Dependency_String('https://builds.dotnet.microsoft.com/dotnet/WindowsDesktop/11.0.0/windowsdesktop-runtime-11.0.0-win-x86.exe', 'https://builds.dotnet.microsoft.com/dotnet/WindowsDesktop/11.0.0/windowsdesktop-runtime-11.0.0-win-x64.exe'),
'', False, False);
end;
end;!!! tip The upstream repository is regularly updated with the latest .NET runtime download URLs. Check there first for ready-to-use procedures.
Edit release/pyrevit.iss and add calls in the InitializeSetup function:
function InitializeSetup: Boolean;
begin
// .NET 8 for Revit 2025-2026
Dependency_AddDotNet80;
Dependency_AddDotNet80Desktop;
// .NET 10 for Revit 2027+
Dependency_AddDotNet100;
Dependency_AddDotNet100Desktop;
// .NET XX for Revit 20YY+ (add new dependencies here)
Result := True;
end;Check the Revit API release notes for breaking changes. Common patterns include:
Use preprocessor directives to handle API differences:
#if REVIT2028_OR_GREATER
// New API for 2028+
element.NewMethod();
#else
// Legacy API
element.OldMethod();
#endifIf needed, add new _OR_GREATER constants in dev/Directory.Build.targets:
<PropertyGroup Condition="'$(RevitVersion)' == '2028'">
<DefineConstants>$(DefineConstants);REVIT2028;REVIT2021_OR_GREATER;REVIT2022_OR_GREATER;REVIT2028_OR_GREATER</DefineConstants>
</PropertyGroup>The build is driven by the C# ModularPipelines project under build/. Run from build/:
cd build
dotnet run -c Debug -- ci
cd ..For Release stamping on the new Revit version, run with Build__Channel=release (or wip) instead of the default none. See build/README.md for full options.
.\bin\pyrevit.exe attach dev default --installed- Launch the new Revit version
- Check that pyRevit loads without errors
- Test core functionality (ribbon, scripts, console)
| File | Purpose |
|---|---|
dev/pyRevitLabs.PyRevit.Runtime/YYYY/*.csproj |
Runtime project per Revit version |
dev/Directory.Build.targets |
Version constants and framework mappings |
dev/Directory.Build.props |
Common project properties and NuGet packages |
dev/libs/Revit/YYYY/ |
Version-specific DLLs (Xceed.Wpf.AvalonDock) |
release/pyrevit-hosts.json |
Revit build registry for version detection (staged to bin/ by CI) |
.github/workflows/ci.yml, wip.yml, release.yml |
CI/CD pipeline configuration |
release/CodeDependencies.iss |
.NET runtime installer procedures |
release/pyrevit.iss |
Main pyRevit installer script |
This usually means a Revit API has changed. Check the API documentation and add conditional compilation (#if REVITxxxx_OR_GREATER).
Check for reflection-based code that may behave differently on new .NET versions. Submodules like IronPython may need updates for new .NET compatibility.
Ensure the DLL was copied to the correct dev/libs/Revit/YYYY/ folder.