代码之家  ›  专栏  ›  技术社区  ›  Godeke

Visual Studio 2010生成文件锁定问题

  •  20
  • Godeke  · 技术社区  · 14 年前

    我有一个visualstudio2008项目,我“升级”到visualstudio2010。自从升级后,我一直有很多问题与该项目(一个项目,在2008年是和现在仍然是士兵,我可能会补充)。

    第一个问题是构建主可执行文件会锁定可执行文件,导致进一步的重建失败。相关问题对此进行了描述: 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"
    

    但这个解决方法确实有效 删除 正在关闭devenv.exe(UI消失后需要几秒钟,然后才能删除文件)。

    不必使用调试器来导致此问题的事实表明,2010构建系统存在一个相当严重的问题。

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

    更新:此项目在没有防病毒和备份实用程序的计算机上具有相同的症状。办公室里的机器运行的是XP SP3 32位,我的本地机器是windows7 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 回复  |  直到 7 年前
        1
  •  15
  •   Godeke    14 年前

    在为这个问题提供补丁之前,我有以下解决方法。只需使用 "C:\MyBin\VisualStudioLockWorkaround.exe" "$(TargetPath)" (将MyBin替换为放置可执行文件的位置)。

     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)));
       }
      }
     }
    
        2
  •  3
  •   Hans Passant    14 年前

    在.NET framework源代码单步执行功能中有一个已知的文件句柄泄漏错误。通过在Tools+Options+Debugger中关闭该选项可以轻松避免。但是,如果您从未启动调试器,那么这不太可能是您的问题。

        3
  •  2
  •   gix    13 年前

    不幸的是,重命名/移动被锁定的文件对我来说不起作用(句柄打开时只有file\u SHARE\u READ),但起作用的只是在visualstudio进程中杀死那些(可能是泄漏的)句柄。你可以用 KillHandle 自动执行此步骤。

        4
  •  1
  •   Gilles    13 年前
        5
  •  1
  •   user3447701    11 年前

    在我的例子中,我为Visual Studio 2010中的一个扩展提供了一个高度定制的构建,该构建在Visual Studio 2008中没有问题。在构建过程中,一些输出程序集被加载到一个单独的应用程序域中,用于生成文档,然后卸载该域。域名卸载工作正常,通过前后查看app域名列表确认。

    Visual Studio 2010似乎对任何加载了基于文件的Assembly.Load*API的程序集都持有文件句柄锁,这些API对文件句柄或路径进行操作。在执行Assembly.Load时,我可以看到文件句柄出现在ProcessExplorer中,并且即使在卸载AppDomain之后,句柄也从未释放。

        6
  •  0
  •   Christopher Mahan    13 年前

    我看到一个答案:

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

    (见纳维特萨克塞纳的帖子)

    他提到关闭XAML文件(设计图面),这似乎对我很有用。我知道这不是很好,但至少我不必重新启动VS。

        7
  •  0
  •   John Russell    9 年前

    我来晚了一点,但这个问题是我们升级到VS2015后第一次出现的。VS2010从未发生过!

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

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

    我试过预构建脚本,有时也能奏效。对于我们的情况来说,这是不可靠的—有时dll被锁定,甚至无法重命名/移动。

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