Godeke
Godeke

Reputation: 16281

Visual Studio 2010 build file lock issues

I have a Visual Studio 2008 project that I "upgraded" to Visual Studio 2010. Since the upgrade I have been having a lot of problems with the project (a project that was and still is trooper in 2008 I might add).

The first problem is that building the main executable locks the executable, causing further rebuilds to fail. This is described in a related question: Visual Studio locks output file on build where I picked up the workaround:

if exist "$(TargetPath).locked" del "$(TargetPath).locked"
if exist "$(TargetPath)" if not exist "$(TargetPath).locked" move "$(TargetPath)" "$(TargetPath).locked"

Except this workaround works exactly once. The .locked file then is locked by devenv.exe as well and must be moved. I have been working around this by adding .1.locked, .2.locked, etc. The only time that the locks are removed so the files can be deleted is on shutdown of devenv.exe (it takes a few seconds after the UI vanishes, then the files can be removed).

The fact that the debugger does not have to be used to cause this problem points to a pretty serious issue with the 2010 build system.

Some theories I think I can discount:

UPDATE: This project has the same symptoms on a machine with no antivirus and no backup utility. The machines in the office are running XP SP3 32bit, my local machine is Windows 7 64 bit. This appears to be OS independent.

I have a secondary problem that starts to occur once the files get locked: the form designers stop loading with a "can't find assembly" error. I suspect these are related to the earlier locking issue as the designers fire right up prior to a build, but making any changes and rebuilding will cause all the designers to collapse with that error (even ones I have open and as the current view).

It is pitiful to watch a form close to the white error screen just because you changed "dummy=1" to "dummy=2" where "dummy" does absolutely nothing but force a recompile in a completely unrelated assembly.

Update: I have tried a few more remedies: Enable .NET source stepping is not checked, so that isn't the issue. Removing the .SUO (solution user options) simply works for as long as a restart would normally remove the problem (two builds: the first because there is no locked file and the second because there is one, but it can be renamed by the script).

Error   28  Unable to copy file "obj\Debug\PolicyTracker3.exe" to "bin\Debug\PolicyTracker3.exe". 
The process cannot access the file 'bin\Debug\PolicyTracker3.exe' because it is being used by another process.  

Upvotes: 21

Views: 13743

Answers (7)

John Russell
John Russell

Reputation: 2247

I'm a little late to the party, but this issue occurred for the first time after we upgraded to VS2015. It never happened with VS2010!

We frequently develop with multiple instances of VS open at the same time - it's a client/server application and we're making changes to both tiers simultaneously.

After upgrading to VS2015, the two instances of VS would "lock each other out" of obj\Debug and one instance would end up not being able to build the common ("shared") projects, i.e. our DTO, entity framework projects.

I tried the pre-build script and it worked on occasion. It just was not reliable for our case - sometimes the dll was so locked that it could not even be renamed/moved.

I ended up simply using different solution build configurations for each solution (copied from Debug). This created new solution specific obj and bin directories and completely avoided the contention over dlls corresponding to common projects.

Hope this helps someone else.

Upvotes: 0

user3447701
user3447701

Reputation: 51

In my case, I have a highly customized build for an extension in Visual Studio 2010 that worked without issue in Visual Studio 2008. At one point of the build, some of the output assemblies are loaded into a separate app domain for documentation generation and then the domain unloaded. The domain unloading was working properly, confirmed by inspecting the app domain list before and after.

Visual Studio 2010 appears to hold file handle locks on any assemblies loaded with the file-based Assembly.Load* APIs that operate on file handles or paths. I could see the file handle appear in ProcessExplorer as soon as the Assembly.Load executed, and the handle never released, even after the AppDomain was unloaded.

I was able to work around the problem by loading the raw assembly bytes using a FileStream and the byte[] Assembly.Load overload.

Upvotes: 1

Christopher Mahan
Christopher Mahan

Reputation: 7619

I saw an answer at:

http://social.expression.microsoft.com/Forums/en-US/blend/thread/844dfea0-efa2-440d-97ce-49ac7108dae3

(see the post by Navit Saxena)

He mentions closing the XAML files (design surfaces) and that seems to work for me. I know it's not all that great, but at least I don't have to restart VS.

Upvotes: 0

gix
gix

Reputation: 5797

Unfortunately renaming/moving the locked file did not work for me (the handles were opened with only FILE_SHARE_READ), but what worked was just killing those (presumably leaked) handles in the Visual Studio process. You can use KillHandle to automate this step.

Upvotes: 2

Gilles
Gilles

Reputation: 11

Already in Ms Connect: http://connect.microsoft.com/VisualStudio/feedback/details/551819/vs2010-locks-static-library-after-debug-session

workaround is to disable 'source stepping', but does not work for me).

Upvotes: 1

Godeke
Godeke

Reputation: 16281

Until a patch rolls around for this, I have the following workaround. Simply call using something like "C:\MyBin\VisualStudioLockWorkaround.exe" "$(TargetPath)" (replacing MyBin with the location you place the executable).

Create this as a C# console application and is used in the Pre-Build section in the same way the original pre-build rename was (see the top of the original question for details).

 using System;
 using System.IO;

 namespace VisualStudioLockWorkaround
 {
  class Program
  {
   static void Main(string[] args)
   {
    string file = args[0];
    string fileName = Path.GetFileName(file);
    string directory = Path.GetDirectoryName(args[0]);
    if (!Directory.Exists(directory)) //If we don't have a folder, nothing to do.
    {
     Console.WriteLine(String.Format("Folder {0} not found. Exiting.", directory));
     return;
    }
    if (!File.Exists(file)) //If the offending executable is missing, no reason to remove the locked files.
    {
     Console.WriteLine(String.Format("File {0} not found. Exiting.", file));
     return;
    }
    foreach (string lockedFile in Directory.EnumerateFiles(directory, "*.locked"))
    {
     try //We know IOExceptions will occur due to the locking bug.
     {
      File.Delete(lockedFile);
     }
     catch (IOException)
     {
      //Nothing to do, just absorbing the IO error.
     }
     catch (UnauthorizedAccessException)
     {
      //Nothing to do, just absorbing the IO error.
     }                                        
    }

    //Rename the executable to a .locked
    File.Move(file, Path.Combine(directory, String.Format("{0}{1:ddmmyyhhmmss}.locked", fileName, DateTime.Now)));
   }
  }
 }

Upvotes: 15

Hans Passant
Hans Passant

Reputation: 941465

There's a known file handle leak bug in the .NET framework source stepping feature. Easy to avoid by turning the option off in Tools + Options + Debugger. That is however unlikely to be your problem if you never got the debugger going.

It is quite unclear why Visual Studio would be interested at all in the build output, let alone load and lock it. Maybe you opened the .exe once? Delete the hidden .suo file in the solution directory to be sure. There isn't any feedback report on connect.microsoft.com that matches your issue, I'd recommend you start your own one. They'll need something reproducible for them to take a look at it, make sure you include a sample project that exhibits this behavior.

Upvotes: 3

Related Questions