I have a Revit add-in which is targeting multiple Revit versions (2023-2025). To achieve this, I reference the Nuget Package Revit_All_Main_Versions_API_x64, with a conditional version reference like this:
<Choose>
<When Condition="$(Configuration.Contains('2023'))">
<PropertyGroup>
<RevitVersion>2023</RevitVersion>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
</When>
<When Condition="$(Configuration.Contains('2024'))">
<PropertyGroup>
<RevitVersion>2024</RevitVersion>
<TargetFramework>net48</TargetFramework>
</PropertyGroup>
</When>
<When Condition="$(Configuration.Contains('2025'))">
<PropertyGroup>
<RevitVersion>2025</RevitVersion>
<TargetFramework>net8.0-windows</TargetFramework>
</PropertyGroup>
</When>
</Choose>
...
<ItemGroup>
<PackageReference Include="Revit_All_Main_Versions_API_x64" Version="$(RevitVersion).*" IncludeAssets="build; compile" PrivateAssets="All" />
</ItemGroup>
This all worked fine, until I started using PostSharp. Now that I have PostSharp (I have a OnMethodBoundaryAspect I am using), I now get an error from PostSharp when building for Revit 2025 (2023-2024 are fine):
PS0264 Could not load file or assembly 'C:\Users#######.nuget\packages\revit_all_main_versions_api_x64\2025.0.0\lib\net8.0\RevitAPI.dll'. The specified module could not be found. Build your project with detailed verbosity to see the assembly loading log. Also check that this project doesn't reference a project with a different processor architecture (x86/x64/arm64).
If I stop using Revit_All_Main_Versions_API_x64, and instead reference the Revit API dlls manually from my local folders like this:
<Reference Include="RevitAPI" Condition="$(Configuration.Contains('2023'))">
<HintPath>C:\Program Files\Autodesk\Revit 2023\RevitAPI.dll</HintPath>
<Private>True</Private>
</Reference>
etc.
It all compiles fine and PostSharp does not complain. However with this approach I cannot have the API files available for the build routine when it runs on Github, and so it fails.
I am very inexperienced with handling MS Build, so I am sure there is something pretty obvious I am missing, but I can't seem to find a way and have not been able to find an answer online.
This is probably due to a failure in native DLL loading, because RevitAPI.dll
is a mixed assembly.
If you apply aspects on declarations that reference `RevitAPI.dll` (e.g. as a base class or as a parameter type), PostSharp will attempt to load the assembly for execution. The main reason for that is that it uses reflection objects in the API to be able to execute the code that directly references the assembly.
If dependencies are not visible to the .NET process, the .NET runtime will fail to load the assembly. Since the assembly has native dependencies, it will not usually give much detail on the failure.
When you reference the DLL from a local installation, all dependencies will already be present in the same directory, and so the DLL will be loaded correctly.
There are differences between assembly loading when PostSharp runs on .NET Framework and .NET, and specifically with mixed assemblies, PostSharp likely avoids this problem under .NET Framework by not loading the DLL itself but a generated stub. This is not supported on .NET.
So you have two options:
Avoid aspects on declarations that reference Revit.
Make sure you point the .NET runtime in the correct direction (using PATH variable).
There is also PostSharpSearchPath that you may try to add paths to, but that will only work for managed DLL loading problems, which is unlikely to be the cause here.
Depending on what you want to achieve, you may consider using Metalama, which is our open-source successor to PostSharp. Specifically in this case, Metalama will not load RevitAPI.dll, avoiding this issue.