
May 3, 2026
•
By Bas Nederveen
•
5 min read
Share this article:
On April 16, 2026, Autodesk published a .NET compatibility note for Inventor 2027 add-ins. The headline reassurance:
"Existing .NET 8 add-ins should continue to work without recompilation."
"No mandatory migration is required for upgrading to Inventor 2027."
That's accurate for the common case — pure-managed add-ins that only depend on Autodesk.Inventor.Interop and the BCL, which run cleanly on Inventor 2027's .NET 10 host. There's one specific exception that hits paid App Store add-ins: the entitlement wrapper Autodesk ships for license verification (AdWebServicesWrapper). Free App Store add-ins generally don't perform an entitlement check (there's nothing to verify), so they're unaffected. If your add-in is paid and verifies the user's entitlement before unlocking functionality, this post is for you — that's the rest of it.
Inventor 2027 hosts on .NET 10 while 2023–2026 ran on .NET 8.

The .NET runtime forward-compat story is real — net8.0 binaries generally run unmodified inside a net10.0 process — but it doesn't apply to the helper assemblies Autodesk ships next to Inventor.
The one that breaks is the entitlement wrapper. In 2023–2026 it was AddinNETFramework.AdWebServicesWrapper.dll (built for .NET 8 since 2025). In 2027 it has been renamed to AdWebServicesWrapper.dll and ships only as net10. The rename alone breaks any csproj with <Reference Include="AddinNETFramework.AdWebServicesWrapper" />; the net10-only retarget means that even after fixing the reference, a net8.0 add-in cannot resolve it at runtime.
To be precise: the only thing affected is calls into Autodesk's own entitlement service through AdWebServicesWrapper / Autodesk.WebServices.CWebServicesManager — typically WebServicesUtils18Plus.GetUserId() or GetUserName(). App Store entitlement checks (apps.autodesk.com/webservices/checkentitlement) live entirely on top of this wrapper, so every paid App Store add-in that gates functionality on a license is in.
It would be nice to have this case spelled out in the official compatibility note. In the meantime, here's the fix.
If you only need Inventor 2027 with entitlement, you need .NET 10. Concretely: target net10.0-windows and reference the renamed AdWebServicesWrapper.dll — no AddinNETFramework. prefix anymore, and it ships only as net10.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0-windows</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Reference Include="AdWebServicesWrapper">
<HintPath>path\to\Inventor\2027\AdWebServicesWrapper.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
</Project>
Install the .NET 10 SDK, gate the .addin manifest with <SupportedSoftwareVersionGreaterThan>30..</SupportedSoftwareVersionGreaterThan>, build, ship. That's the migration.
If you also want to keep building for Inventor 2023–2026 (which run on .NET 8 and reference the old AddinNETFramework.AdWebServicesWrapper name), you don't need a separate csproj per Inventor version. One csproj parameterized by a custom InventorVersion property — with the <TargetFramework> and <Choose> blocks branching on it — handles both runtimes from the same source. The InventorVersion property itself lives equally well in the add-in's .csproj (single project) or in a Directory.Build.props at the repo root (if you maintain several add-ins in the same solution and want them to share the convention).
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<InventorVersion Condition="'$(InventorVersion)' == ''">2026</InventorVersion>
<!-- Inventor 2027 hosts on .NET 10; earlier versions stay on net8.0-windows. -->
<TargetFramework Condition="'$(InventorVersion)' == '2027'">net10.0-windows</TargetFramework>
<TargetFramework Condition="'$(TargetFramework)' == ''">net8.0-windows</TargetFramework>
</PropertyGroup>
<Choose>
<When Condition="'$(InventorVersion)' == '2027'">
<ItemGroup>
<Reference Include="AdWebServicesWrapper">
<HintPath>$(InventorReferencesPath)2027\AdWebServicesWrapper.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="AddinNETFramework.AdWebServicesWrapper">
<HintPath>$(InventorReferencesPath)$(InventorVersion)\AddinNETFramework.AdWebServicesWrapper.dll</HintPath>
<Private>false</Private>
</Reference>
</ItemGroup>
</Otherwise>
</Choose>
</Project>
One csproj covers both runtimes. <Choose> evaluates at build time and picks exactly one branch based on InventorVersion, so the same project file produces a correct .NET 8 build for Inventor 2026 (and earlier) or a correct .NET 10 build for Inventor 2027 — same source, same build invocation, just a different -p:InventorVersion= flag.
Two custom MSBuild properties drive that. InventorVersion is the single source of truth: it gates the TFM, the wrapper reference, and the reference path, so flipping one flag keeps all three in sync — you can't accidentally ship a 2027 build that still references the .NET 8 wrapper. The inline <InventorVersion Condition="'$(InventorVersion)' == ''">2026</InventorVersion> gives a sensible default for a plain dotnet build, overridable from the command line. InventorReferencesPath points at wherever you keep the per-version Inventor reference DLLs — vendored into the repo (e.g. extern/Inventor/2026/, extern/Inventor/2027/), an Autodesk install dir, or a shared network share. Pulling that root out as a property keeps the csproj portable across developer machines and CI agents, and the $(InventorReferencesPath)$(InventorVersion)\... shape is what lets the <Choose> block stay readable.
Build with -p:InventorVersion=2027 (or 2026, etc.) and you get the right TFM, the right wrapper reference, and the right reference folder for that Inventor version.
Two things worth keeping in mind. Don't multi-target a single project: single-target the whole graph per Inventor version and build twice — multi-targeting forces every dependency to multi-target too and confuses Visual Studio about which TFM is "active". And keep <Private>false</Private> on these references so the build doesn't copy a second copy of the wrapper next to your add-in, which causes COM type-identity collisions when Inventor tries to load both.
Also bracket the older .addin manifests with <SupportedSoftwareVersionLessThan>30..</SupportedSoftwareVersionLessThan> so the net10 DLL never tries to load into a net8 Inventor host.
Build with -p:InventorVersion=2027 against a 2027 SDK install. If the build complains about AdWebServicesWrapper, switch that leg to net10 with the conditional pattern above and bracket your .addin manifests so each version only matches its own host.
The "no migration" message holds up well for free and hobby add-ins, including free App Store ones that don't verify entitlement. For paid App Store add-ins there's a little extra work, but it's mechanical once you know to do it. Hopefully a future revision of the compatibility note picks this case up; in the meantime, if you're hitting AdWebServicesWrapper errors you're not doing anything wrong, and you're not the only one.
All build configuration excerpts in this post are real and live in production across 7 Inventor add-ins as of May 2026.
Share this article: