#
Trimming Problems
Trimming and .NET Reactor can be used together, but the required configuration depends on the order in which trimming and protection are applied.
There are two separate concerns:
- If trimming runs before protection, the trimmer must keep the classes, members, and references that the code injected later by .NET Reactor will require.
- If trimming runs after protection, the trimmer modifies an already protected assembly. Some protection features rely on metadata or other values remaining unchanged and are therefore not compatible with this build order.
#
Solution
Choose the configuration that matches your build order:
- Trim first, then protect: Use
Eziriz.Reactor.TrimHelperso the trimmer preserves everything required by the protection code. No .NET Reactor protection feature needs to be disabled. - Protect first, then trim: Some protection features must be disabled because trimming modifies the protected assembly. Depending on the project and build type,
Eziriz.Reactor.TrimHelpermay still be required. If trimming or the resulting application does not work correctly, add the helper as described below.
#
1. Install the NuGet Package
Eziriz.Reactor.TrimHelper is required when trimming runs before .NET Reactor protection. It ensures that the trimmer keeps the classes, members, and references that may later be required by the injected protection code.
When protection runs before trimming, the helper is not always necessary, but it can still be required depending on the project and build type. If you encounter trimming or runtime problems, use the helper and the configuration below.
dotnet add package Eziriz.Reactor.TrimHelper
Alternatively, you can install it via the NuGet Package Manager in your IDE.
NuGet Package Link:
Eziriz.Reactor.TrimHelper
#
2. Update the Project File
When using Eziriz.Reactor.TrimHelper, add the following configuration to your project file (.csproj, .vbproj, etc.) to explicitly preserve all types and members in the TrimHelper assembly:
<ItemGroup>
<TrimmerRootAssembly Include="TrimHelper" RootMode="library" />
</ItemGroup>
Read more: Root Assemblies
#
3. Alternatively Use a Link XML File
Alternative configuration
Use this approach instead of the TrimmerRootAssembly configuration in step 2.
Instead of using TrimmerRootAssembly, you can use a link.xml file.
Create a file named link.xml with the following content and replace YourAssembly with the name of your own assembly:
<linker>
<assembly fullname="TrimHelper">
<type fullname="*" preserve="all" />
</assembly>
<assembly fullname="YourAssembly">
<type fullname="*" preserve="all" />
</assembly>
</linker>
The <linker> root element is required. This example also preserves every type and member in YourAssembly. Narrow that part only after verifying which application code must remain available.
Read more: ILLink descriptor format
Then add the following entry to your project file:
<ItemGroup>
<TrimmerRootDescriptor Include="link.xml" />
</ItemGroup>
#
4. Protection Order and Feature Restrictions
#
Trimming before protection
If trimming is completed before .NET Reactor protects the application, use Eziriz.Reactor.TrimHelper as described above. This ensures that the assembly still contains the references required by the code that .NET Reactor injects later.
The major advantage of this build order is that the protected assembly is not modified afterwards.
Therefore no protection feature needs to be disabled.
#
Trimming after protection
With the Visual Studio / Rider Add-in or Build Integration Manager, selecting After Compile applies protection before trimming.
In this order, the trimmer modifies an assembly that has already been protected. Some protection features expect metadata or other values in the protected assembly to remain unchanged and should therefore not be enabled.
Required when trimming runs AFTER protection
Disable Protection Settings → Anti ILDASM / Suppress Decompilation.
Also keep the following protection features disabled:
- NecroBit
- Anti Tampering
- Code Virtualization
- Hide Method Calls
Depending on the project and build type, Eziriz.Reactor.TrimHelper may still be required in this order. If trimming fails or the trimmed application does not work correctly, install the helper and apply the configuration described above.
#
Android and MAUI
For Android and MAUI applications, use Protection Timing = After Compile.
Because this means that trimming runs after protection, disable Anti ILDASM / Suppress Decompilation and keep NecroBit, Anti Tampering, Code Virtualization, and Hide Method Calls disabled.
If the build or trimmed application still does not work correctly, also use Eziriz.Reactor.TrimHelper and the configuration described above.
#
Why This Is Necessary
The trimming process removes code that it considers unused.
When trimming runs before protection, this can also remove references that are not used by the original application but will be required by code injected later by .NET Reactor. Eziriz.Reactor.TrimHelper keeps these required elements available. Since the protected assembly is created only after trimming has finished, all protection features can be used normally.
When trimming runs after protection, the situation is different: the trimmer modifies the already protected assembly. Some protection features rely on metadata or other values remaining unchanged, so those features must be disabled for this build order. Eziriz.Reactor.TrimHelper can additionally be used when required by the particular project or build type.
#
Related topics
Build Integration Manager · ReadyToRun
Single-file publishing · Choosing protection settings