How to Automatically Apply Shadow Copying Settings When Publishing ASP.NET Core Sites
TLDR
- Shadow Copying resolves the issue where ASP.NET Core runtime DLLs are locked, preventing updates.
- By pre-configuring
web.configin the project root, settings are automatically merged during deployment, eliminating the need for manual server-side modifications and making it ideal for CI/CD pipelines. - Shadow Copying configuration parameters vary by Hosting Bundle version: 7.0+ uses
enableShadowCopy, while 6.0 usesexperimentalEnableShadowCopy. - The Shadow Copying mechanism is not a version management tool; it is designed to "keep only the current version," attempting to delete other old folders in the directory upon each startup.
- Always manually clear the Shadow Copying directory after upgrading the .NET version to avoid 500.30 errors.
- Avoid writing files or logs within the application directory to prevent frequent, unnecessary application restarts triggered by Shadow Copying.
Solving DLL Locking and Automated Deployment Issues
When do you encounter this issue? When an ASP.NET Core application runs on IIS, the associated DLL files are locked, making it impossible to overwrite them directly without stopping the application pool.
The traditional approach involves manually modifying the web.config on the server, but this contradicts automated deployment principles and is prone to human error. A better approach is to pre-create a web.config containing the Shadow Copying settings in the root of your Web project. During publishing, MSBuild automatically merges this file as a base, ensuring the deployed configuration is accurate.
To set environment variables (such as ASPNETCORE_ENVIRONMENT) simultaneously, you can define <EnvironmentName> in your .pubxml. The published web.config will automatically merge the environment variables with the Shadow Copying settings:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath="dotnet" arguments=".\WebApi.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess">
<handlerSettings>
<handlerSetting name="enableShadowCopy" value="true" />
<handlerSetting name="shadowCopyDirectory" value="../ShadowCopy/" />
</handlerSettings>
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Staging" />
</environmentVariables>
</aspNetCore>
</system.webServer>
</location>
</configuration>2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
With this method, the CI/CD process only needs to execute standard commands:
dotnet publish -c Release -p:EnvironmentName=StagingVersion Difference Notes
The configuration parameter name depends on the Hosting Bundle version installed on the server, not the .NET version of the project itself:
- Hosting Bundle 7.0.0 and above: Use
enableShadowCopy. - Hosting Bundle 6.0.0: Use
experimentalEnableShadowCopy.
Regarding the Shadow Copying Folder Management Mechanism
When do you encounter this issue? When developers mistakenly believe that shadowCopyDirectory automatically maintains multiple versions for rollback purposes, or worry that the folder will grow indefinitely.
According to the AspNetCoreModuleV2 source code analysis, the original intent of Shadow Copying is not version management. Once the system selects a new sequential folder as the execution path, it immediately starts a thread to delete all other folders in that directory. If multiple folders are found coexisting in the directory, it is usually because the cleanup thread has not finished executing, or old files failed to delete due to being locked, rather than an intentional design to retain them.
WARNING
- After upgrading the .NET version, you must manually delete the Shadow Copying folder; otherwise, IIS will trigger a 500.30 error, and the Event Viewer will show a
directory_iteratorpath-not-found exception. - When using Shadow Copying, avoid writing files or logs in the application directory, as every file change may trigger the Shadow Copying mechanism, causing unnecessary application restarts.
Change Log
- 2025-03-18 Initial documentation created.
- 2025-04-08 Added notes on Shadow Copying anomalies caused by .NET version upgrades.
- 2025-06-27 Added warnings about avoiding file writes in the application directory when using Shadow Copying.
- 2026-01-22 Added common misconceptions and source code explanations regarding the Shadow Copying folder management mechanism.
