Visual Studio 2010构建文件锁定问题

时间:2010-06-22 17:31:35

标签: visual-studio-2010

我有一个Visual Studio 2008项目,我“升级”到Visual Studio 2010.自升级以来,我一直遇到很多项目问题(一个项目过去和现在仍然是警察,我可能会添加)。

第一个问题是构建主可执行文件会锁定可执行文件,从而导致进一步的重建失败。这在相关问题中有所描述:Visual Studio locks output file on build我选择了解决方法:

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

除了此解决方法完全一次。然后.locked文件也被devenv.exe锁定,必须移动。我一直在通过添加.1.locked,.2.locked等来解决这个问题。唯一一次删除锁以便文件可以删除是关闭devenv.exe(它UI消失后需要几秒钟,然后可以删除文件。

调试器不必用于导致此问题的事实表明2010版本系统存在相当严重的问题。

我认为可以打折的一些理论:

  • 防病毒或其他后台任务:如果这是一个问题,它似乎会失败。然而,作为一个完整的我删除了avast!系统完全没有运气。

更新:此项目在没有防病毒且没有备份实用程序的计算机上具有相同的症状。办公室的机器运行XP SP3 32bit,我的本地机器是Windows 7 64位。这似乎与操作系统无关。

  • 调试器正在锁定文件:重现此操作所需的全部内容是重复构建过程而不进行调试。 ProcessExplorer显示devenv.exe是锁的持有者,而不是vshost,并且杀死vshost.exe无论如何都不会删除锁。

我有一个次要问题,一旦文件被锁定就会开始出现:表单设计者停止加载“无法找到程序集”错误。我怀疑这些与早期的锁定问题有关,因为设计师将之前的发送到构建版本,但是进行任何更改和重建都会导致所有设计者因该错误而崩溃(即使是我打开的那些)并且作为当前的观点)。

观看靠近白色错误屏幕的表单是可怜的,因为您将“dummy = 1”更改为“dummy = 2”,其中“dummy”绝对没有任何内容,只是强制重新编译完全无关的程序集。

更新:我已经尝试了一些补救措施:未选中启用.NET源步进,因此这不是问题。删除.SUO(解决方案用户选项)只需重启通常可以解决问题(两个构建:第一个因为没有锁定文件而第二个因为有一个,但它可以由脚本重命名)。

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.  

7 个答案:

答案 0 :(得分:15)

在修补程序为此之前,我有以下解决方法。只需使用类似"C:\MyBin\VisualStudioLockWorkaround.exe" "$(TargetPath)"的内容进行调用(将MyBin替换为放置可执行文件的位置)。

将其创建为C#控制台应用程序,并在预构建部分中使用与原始预构建重命名相同的方式(有关详细信息,请参阅原始问题的顶部)。

 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)));
   }
  }
 }

答案 1 :(得分:3)

.NET框架源步进功能中存在已知的文件句柄泄漏错误。在Tools + Options + Debugger中关闭选项可以轻松避免。如果你从来没有调试过,那么这不太可能是你的问题。

目前还不清楚为什么Visual Studio会对构建输出感兴趣,更不用说加载和锁定它了。也许你打开过一次.exe?删除解决方案目录中隐藏的.suo文件以确保。 connect.microsoft.com上没有任何与您的问题相符的反馈报告,我建议您开始自己的问题。他们需要一些可重复的东西来查看它,确保你包含一个展示这种行为的示例项目。

答案 2 :(得分:2)

不幸的是,重命名/移动锁定的文件对我来说不起作用(仅使用FILE_SHARE_READ打开句柄),但有效的方法就是在Visual Studio进程中杀死那些(可能是泄漏的)句柄。您可以使用KillHandle自动完成此步骤。

答案 3 :(得分:1)

已经在Connect女士中: http://connect.microsoft.com/VisualStudio/feedback/details/551819/vs2010-locks-static-library-after-debug-session

解决方法是禁用“源步进”,但对我不起作用。)

答案 4 :(得分:1)

就我而言,我在Visual Studio 2010中有一个高度自定义的扩展,在Visual Studio 2008中没有问题。在构建的某个阶段,一些输出程序集被加载到一个单独的应用程序域中以便进行文档编制生成然后卸载域。域名卸载工作正常,通过检查之前和之后的应用程序域列表进行确认。

Visual Studio 2010似乎在使用基于文件的Assembly.Load * API加载的任何程序集上保存文件句柄锁,这些API在文件句柄或路径上运行。一旦Assembly.Load执行,我就可以看到文件句柄出现在ProcessExplorer中,并且即使在卸载AppDomain之后句柄也从未释放。

我能够通过使用FileStream和byte [] Assembly.Load重载加载原始程序集字节来解决此问题。

答案 5 :(得分:0)

我在以下地址看到了答案:

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

(见Navit Saxena的帖子)

他提到关闭XAML文件(设计图面),这似乎对我有用。我知道这并不是那么好,但至少我没有重启VS.

答案 6 :(得分:0)

我参加聚会有点晚了,但这个问题在我们升级到VS2015之后第一次出现了。它永远不会发生在VS2010上!

我们经常开发多个VS同时打开的实例 - 它是一个客户端/服务器应用程序,我们同时对这两个层进行更改。

升级到VS2015之后,VS的两个实例将“互相锁定”obj \ Debug,一个实例最终无法构建公共(“共享”)项目,即我们的DTO,实体框架项目

我尝试了预构建脚本,它偶尔会运行。它对我们的情况来说并不可靠 - 有时dll被锁定甚至无法重命名/移动。

我最终只是为每个解决方案使用不同的解决方案构建配置(从Debug复制)。这创建了新的解决方案特定的obj和bin目录,并完全避免了对应于常见项目的dll的争用。

希望这有助于其他人。