# Publish and Distribute Protected .NET Applications

Distribute the protected output with its required runtime files, not the original build. Keep diagnostic and build-only files out of customer packages.

# 1. Prepare the release configuration

Build and test the unprotected application first. Apply the intended protection settings to a fresh copy, keeping input, protected output, and release staging in separate directories. Do not release assemblies using the Debug naming convention.

For a licensed command-line installation, include -licensed and stop the release on any nonzero exit code:

dotNET_Reactor.Console.exe -licensed -project "C:\Build\MyApp.nrproj"

-licensed checks that Reactor runs as a licensed full version; it does not activate Reactor or create an application license. Never package stale output after a failed protection run. See Activation.

# 2. Choose the correct publishing order

Deployment workflow Protection and packaging order
Regular folder deployment Protect the managed assemblies, then stage the protected output with its required runtime files.
Build or installer integration Use the Build Integration Manager. After Build protects final build output; use After Compile when packaging takes assemblies from obj.
ReadyToRun, including single-file deployments Compile → protect → ReadyToRun → final packaging and signing. Follow ReadyToRun for integration and cross-assembly protection.
.NET SDK single-file application without ReadyToRun Publish first, open the bundle in Reactor, select the assemblies to protect, and deploy the new protected bundle. See Single-File Publishing.
Library or NuGet package Package the protected DLL while preserving the public API required by consumers. See Libraries and NuGet.

For trimmed applications, follow Trimming Problems. In the publish-first single-file workflow, configure Eziriz.Reactor.TrimHelper before publishing. Application-specific reflection and serialization may also require trimming configuration.

# 3. Stage the complete protected application

Keep files from the same protection run together, including the protected assemblies, application host, .deps.json, and .runtimeconfig.json where applicable. Do not overwrite them with original build files.

Add required external files from the same input build: native libraries, configuration, resources, language folders, plug-ins, and application data. For .NET Framework, retain required files such as MyApp.exe.config. See Application Startup Problems.

For single-file deployment, use the new protected bundle and its required external files. Do not package Reactor's per-assembly inspection folders or restore original DLLs for embedded dependencies. See Merge, Embed, or Bundle?.

# 4. Keep symbols and build artifacts private

Do not include PDB files by default. Distribute them only for a specific, tested diagnostic requirement that private symbol storage cannot meet. PDBs can expose source paths and line mappings or help tools display available original source. See dotPeek Shows Original Source Code.

Check more than loose .pdb files: <DebugType>embedded</DebugType> embeds symbols in the assembly. Review single-file bundle contents, embedded source, Source Link, public symbol uploads, and symbol packages. Removing sidecar PDBs alone is not enough.

File or artifact Release policy
Protected application and required runtime dependencies Include. Deliver an application license when required by your licensing workflow.
PDBs and ReadyToRun profiler symbols (.ni.pdb, .r2rmap) Keep private unless distribution is specifically required.
.NET Reactor mapping files Keep private for stack-trace deobfuscation; they reveal original and obfuscated names.
Reactor-generated .hash files Exclude; they are used by build integration, not the deployed application.
Original assemblies, source, Reactor project files, master keys, signing private keys, and build-machine licensing files Exclude.

Retain diagnostic files privately for the exact release. PDBs from an unprotected build may not match transformed assemblies; verify them against the protected output. Exclude private artifacts during packaging rather than deleting your only copies.

# 5. Sign, verify, and archive the release

Configure strong-name signing as required. Apply final Authenticode signing after the last file-changing step, including ReadyToRun or bundle creation, and sign the installer separately. See Code Signing.

Install or extract the actual customer package into a clean location. Verify its protected assemblies or bundle, signatures, and important application workflows without rebuilding or replacing the tested files. See Verify Protected Output.

Archive the exact shipped files under a release ID with matching mapping files, required symbols, protection settings, tool versions, target runtime, and build logs. A mapping from another protection run is not a substitute. See Debugging.