Improve your .NET code quality with NDepend

A Visual Studio script that saves time and pain

After years of pain, I finally found a clean-and-definitive way to get rid of the dreadful issue Could not copy assembly, the process cannot access the file because it is used by another process!

Locked assembly

I have no idea how many .NET developers are coping with this issue, but on our side it used to be daily and there are many situations where an assembly file gets locked:

  • sometimes VS just load in-process the assembly, or the PDB file or the .xml documentation file, for an unknown reason (usually after a debug session)
  • sometimes the culprit seems to be vshost.exe
  • sometimes the culprit is the test runner process
  • sometimes, after a smoke test session, one just forgets to close all processes that hold assemblies…
  • …or sometimes it is just a zombie process that should have stopped but just didn’t!
  • and when developing a VS extension, all of those situations are happening more often

When the culprit process was not obviously identified, I started Process Explorer to kill it! And when the culprit process is my current VS instance, it means I need to restart it and interrupt current work for significant time and then lose my mental focus!!

The clean-and-definitive solution to this problem, is this script to copy in a .bat file. This script must be invoked from the VS project pre-build-events. It just moves the assembly file, the .pdb file and the .xml documentation file to a dumb location (if the .pdb or .xml file is missing no problem).

The key is that when a process locks a file, Windows authorizes to move and rename the file. I found the original idea from this stackoverflow answer, that itself found it from a Keyvan Nayyeri blog post that seems to have been removed.

To invoke this script just add this in all your VS project pre-build events command line. If you wish the script name and location to be different, just adapt $(SolutionDir)\BuildProcess\PreBuildEvents.bat.


Notice that this script does the job no matter the actual configuration (Debug or Release) and no matter if the compilation is started from VS or from any other script.


Published by

Patrick Smacchia

Patrick Smacchia created NDepend in 2004. The tool became commercial in 2007. Since then, Patrick dedicates all his passion and energy to NDepend dev, providing a relentless effort to make it a more useful and usable product, release after release. Patrick graduated in Mathematics and Software engineering in 1998. At that time he was already writing code for more than a decade. Today, with more than 5.000 client companies, including many of the fortune 500 ones, NDepend offers deeper insight and understanding about their code bases to a wide range of professional users worldwide.


    1. I don’t guarantee it works for all VS users, but at least it works for us ๐Ÿ™‚
      What problem exactly are you dealing with?

      1. Compile complete — 0 errors, 1303 warnings
        $(TargetPath) is “E:\Bistro\bin\Debug\Bistro.exe”
        $(TargetFileName) is “Bistro.exe”
        $(TargetDir) is “E:\Bistro\bin\Debug\”
        $(TargetName) is “Bistro”
        Se han movido 1 archivos.
        Se han movido 1 archivos.
        El sistema no puede encontrar el archivo especificado.
        C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3102,5): warning MSB3112: Two or more assemblies have the same identity ‘Bistro, Version=, Culture=neutral, ProcessorArchitecture=x86’.
        C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3102,5): warning MSB3181: Two or more files have the same target path ‘E:\Bistro\bin\Debug\Bistro.exe’.
        C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3390,5): warning MSB3026: Could not copy “obj\x86\Debug\Bistro.exe” to “bin\Debug\Bistro.exe”. Beginning retry 1 in 1000ms. The process cannot access the file ‘bin\Debug\Bistro.exe’ because it is being used by another process.
        C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3390,5): error MSB3027: Could not copy “obj\x86\Debug\Bistro.exe” to “bin\Debug\Bistro.exe”. Exceeded retry count of 10. Failed.
        C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3390,5): error MSB3021: Unable to copy file “obj\x86\Debug\Bistro.exe” to “bin\Debug\Bistro.exe”. The process cannot access the file ‘bin\Debug\Bistro.exe’ because it is being used by another process.

  1. I was struggling with this (worst?) issue and lost almost a day (Earlier whenever I faced this issue, it used to drive me crazy and I ended up doing all sort of things). However, this time it was different as I could figure out a way to solve the issue.

    The solution was to : Click on Project Properties and DESELECT “Enable Visual Studio Hosting Process”
    That’s it ๐Ÿ™‚

  2. Hi,

    “I started Process Explorer to kill it!”
    Sometimes, the culprit is the Process explorer itself. Especially when you open the Properties window for the process and navigate through the tabs (probably it’s the Threads tab), then it may happen that the Process Explorer loads the PDB and does not free it up anymore.
    As a result, you see that specific error in VS, eg. when you try to re-build your solution.
    To fix that, just close the Process Explorer process (and also its taskbar icon).

Leave a Reply

Your email address will not be published. Required fields are marked *