Using SmartAssembly with Single-File Applications (.NET)
Published 30 March 2020
Single-file publishing bundles an application and its dependencies into a single executable file. It can be used for both framework-dependent and self-contained applications. In both cases, a Runtime Identifier (RID) must be specified to target a specific platform and architecture.
This feature is available in modern .NET releases, including .NET 10.
This article explains how to protect a single-file .NET application with SmartAssembly.
You can download a working example of protecting a single-file .NET application with SmartAssembly.
See our GitHub repository: https://github.com/red-gate/SmartAssembly-demos/tree/master/msbuild-integration-demos/net10-single-file
Getting started
First, let's look at a typical .NET 10 application.
Suppose we have a .NET 10 application called ConsoleApp, defined by the following project file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>
</Project>To publish this application we would use the following command:
dotnet publish .\ConsoleApp.csproj -c Release -r win-x64 --self-contained true
The command builds the application in Release mode and publishes it for 64-bit Windows.
After the publishing is done, go to the output directory (this would be ConsoleApp\bin\Release\net10.0\win-x64\publish\ for the app above). Take notice of how many files are present in the directory.
The process of publishing the self-contained .NET application can be visualized as follows:
Using single-file executable
Now let's publish our application as single-file. All we need to do is add a PublishSingleFile property with value set to true.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile> <!-- add this line -->
</PropertyGroup>
</Project>Let's issue the publish command again:
dotnet publish .\ConsoleApp.csproj -c Release -r win-x64
After publishing is complete, the publish directory contains a single executable that includes the application and its dependencies.
Let's see how the publishing process has changed after enabling single-file:
Integrating SmartAssembly
The final step is to protect the assembly before the single-file executable is generated.
SmartAssembly runs after the managed assembly is built and before the single-file bundling process occurs. This is shown on the diagram below:
Step 1: Creating a SmartAssembly project
- Open SmartAssembly.
- Click New Project.
- Click Browse Assembly.
- Navigate to your application's output directory, choose the appropriate assembly (for the app above it'd be: \ConsoleApp\bin\Release\net10.0\win-x64\ConsoleApp.dll) and Open.
- Click Set Destination.
- Navigate to your application's \obj\ directory (for the app above it'd be: \ConsoleApp\obj\Release\net10.0\win-x64\ConsoleApp.dll) and Save. If the file already exists click Yes to overwrite.
- Configure the project as needed. Enable any protections your application may need.
- Click Save to save the project. It's recommended to save the project in the same location as Visual Studio's project file, under the same name (for the app above it'd be: \ConsoleApp\ConsoleApp.saproj).
"Dependencies Merging" and "Dependencies Embedding" should not be used when protecting a single-file assembly. Merging or embedding assemblies can result in unexpected behavior and isn't recommended for this type of applications.
Step 2: Integrating SmartAssembly into the publish process
- Open your application's project in Visual Studio.
- Right-click the project name and select Manage NuGet packages...
- Switch to the Browse tab.
- Type RedGate.SmartAssembly.MSBuild and click Install next to it.
That's it! After performing the steps above, your project file should look like the following:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="RedGate.SmartAssembly.MSBuild" Version="8.*">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; buildTransitive; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>Now let's issue the publish command once again:
dotnet publish .\ConsoleApp.csproj -c Release -r win-x64
If the publish process succeeds, SmartAssembly protects the assembly before the single-file bundling and publish steps complete.
If you're running multiple consecutive builds of the same project you should clean the project before or after each build. Because SmartAssembly obfuscates the assembly into \obj\ directory, the obfuscated version might be picked up by the build command next time leading to double-obfuscation and other unexpected results.
To clean the project either manually remove the \obj\ directory or issue the following command (using the same configuration and runtime identifier used for publish):
dotnet clean .\ConsoleApp.csproj -c Release -r win-x64
If everything went well, you should see additional output messages in the command line confirming that SmartAssembly has successfully protected your application (paths were shortened for clarity):
ConsoleApp -> C:\[..]\ConsoleApp\bin\Release\net10.0\win-x64\ConsoleApp.dll
C:\PROGRA~1\Red Gate\SmartAssembly 8\SmartAssembly.com
"C:\[..]\ConsoleApp\ConsoleApp.saproj" /msbuildSmartAssembly v8.4.12.7302 Professional
Copyright c Red Gate Software Ltd 2005-2026
Loading project
C:\[..]\ConsoleApp\ConsoleApp.saprojInput=C:\[..]\ConsoleApp\bin\Release\net10.0\win-x64\ConsoleApp.dll
Loading...
Starting...
Analyzing...
Preparing...
Creating assembly...
Copying additional files...
OK
The output confirms that SmartAssembly protected the managed assembly before the single-file bundling and publish process completed.
This documentation contains proprietary information and is protected by copyright law.
Copyright © 2026 Red Gate Software Limited. All rights reserved


