If you are still opening a desktop GUI, hunting for your release DLL, and clicking an "Obfuscate" button every time you want to publish a C# or VB.NET application, you are leaving your CI/CD pipeline vulnerable to simple human error.
In my day-to-day work as a Senior Software Developer building tools at Rustemsoft, I constantly see teams accidentally ship unprotected intermediate language (IL) simply because someone forgot a manual step. When we designed Opaquer .NET Obfuscator as the successor to Skater, one of the primary goals was to make protection invisible to the developer's daily workflow.
The easiest way to achieve this zero-touch security is by wiring Opaquer's Command Line Interface (CLI) directly into your Visual Studio Post-Build events. Here is the hands-on guide to setting it up.
The Concept: In-Place Overwrites
The trick to seamless automation is overwriting the compiler's output immediately. By telling Opaquer to read the newly built assembly and write the obfuscated version back to the exact same file path, the rest of your pipeline (testing, packaging, publishing) doesn't need to be updated. It just blindly consumes the protected binary.
Note: You will need the Pro or Enterprise edition of Opaquer for this, as the free Basic edition only includes the GUI, not the CLI engine.
Step 1: The One Visual Studio Setting You Must Change
Before adding any scripts, there is a crucial "gotcha." Opaquer modifies your assemblies in place. If Visual Studio is configured to build multiple projects in parallel, another project in your solution might try to lock or read your DLL while Opaquer is right in the middle of rewriting it.
To prevent these file-lock exceptions, you must restrict parallel execution.
- Go to Tools → Options → Projects and Solutions → Build and Run.
- Change the Maximum number of parallel project builds to 1.
Step 2: The Post-Build Command
Right-click your project in Solution Explorer, head to Properties, and find the Build Events tab. In the Post-build event command line box, you are going to drop in the following script:
DOS
if "$(ConfigurationName)" == "Release" (
"C:\Program Files (x86)\RustemSoft\Opaquer\Opaquer.exe" ^
-SOURCE="$(TargetPath)" ^
-OUTPUT="$(TargetPath)" ^
-KEY="$(ProjectDir)KeyFile.snk" ^
-WRITELOG="$(TargetDir)Opaquer.log" ^
-ALLPRIVATE ^
-CONCEALSTRINGS ^
-FLOW
)
What is happening here?
• if "$(ConfigurationName)" == "Release": We only run this on Release builds. You don't want to slow down your local Debug loops with heavy control-flow obfuscation.
• -SOURCE and -OUTPUT: Both point to $(TargetPath), executing the in-place overwrite we talked about earlier.
• -KEY: If your assembly is strong-named, obfuscation breaks the signature. Pointing to your .snk file ensures Opaquer re-signs it on the way out.
• -ALLPRIVATE, -CONCEALSTRINGS, -FLOW: This combo enforces private member renaming, string encryption, and control-flow mangling without needing to reference a saved GUI profile.
Step 3: Making it CI/CD Friendly
While pasting the command directly into Visual Studio works, I always recommend extracting it into a .bat file for production codebases. This keeps your .csproj files clean, makes the obfuscation logic easily version-controlled, and allows headless agents (like Azure DevOps or GitHub Actions) to trigger it easily.
Create an obfuscate.bat file in your project directory:
DOS
@echo off
setlocal
set OPAQUER="C:\Program Files (x86)\RustemSoft\Opaquer\Opaquer.exe"
set ASSEMBLY=%~dp0bin\Release\net8.0\MyApp.dll
set KEYFILE=%~dp0KeyFile.snk
set LOGFILE=%~dp0bin\Release\net8.0\Opaquer.log
echo Obfuscating %ASSEMBLY% ...
%OPAQUER% -SOURCE="%ASSEMBLY%" -OUTPUT="%ASSEMBLY%" -KEY="%KEYFILE%" -WRITELOG="%LOGFILE%" -ALLPRIVATE -CONCEALSTRINGS -FLOW
if %ERRORLEVEL% neq 0 (
echo Opaquer failed with exit code %ERRORLEVEL%
exit /b %ERRORLEVEL%
)
echo Done. Log written to %LOGFILE%
endlocal
Then, in your Visual Studio Post-Build event, just call the script: call "$(ProjectDir)obfuscate.bat"
A Quick Warning on Setup Projects
If you are utilizing Visual Studio Setup/Deployment projects to build MSI installers, be careful. Relying on the "Primary Output" of a project can sometimes cause the setup builder to snatch the assembly before the post-build obfuscation finishes.
To fix this, either obfuscate your application project completely before building the installer, or attach a Pre-Build event directly to the deployment project itself so the binaries are secured right before packaging.
By pushing this logic into your build pipeline, you guarantee that whatever code leaves your machine is encrypted, protected, and ready for production.
Top comments (0)