Visual Studio在构建时锁定输出文件

时间:2010-01-04 21:13:32

标签: visual-studio

我在VS 2010中有一个简单的WinForms解决方案。每当我构建它时,输出文件(bin \ debug \ app.exe)最终被锁定,后续构建失败并显示消息 "The process cannot access the file 'bin\Debug\app.exe' because it is being used by another process." 构建项目的唯一方法是在每次构建之后重新启动VS,这非常笨拙。

我发现这篇旧帖子http://blogs.geekdojo.net/brian/archive/2006/02/17/VS2005FileLocking.aspx - 似乎问题真的很老了。有谁知道这里发生了什么,或者至少有一些解决方法?

更新

我实际上并没有运行该文件。锁定发生在构建之后,而不是在调试之后(即启动VS - 构建 - 构建 - 失败!) 我尝试关闭防病毒软件。它没有帮助。

更新2

Process Explorer显示已加载文件的devenv.exe(在DLL中,而不在Handles中)。看起来构建期间的一些小故障阻止了卸载,但是(第一个)构建完成时没有任何消息,然后“1成功,o失败”/

16 个答案:

答案 0 :(得分:68)

有同样的问题,但找到了解决方案(感谢Keyvan Nayyeri):

但如何解决这个问题呢?根据您的项目类型有多种方式,但我建议Visual Studio加载项开发人员使用一个简单的解决方案是在项目的构建事件中添加一个简单的代码。

您可以将以下代码行添加到项目的预构建事件命令行中。

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

答案 1 :(得分:24)

这不是病毒问题。这是visual studio 2010的bug。这个问题似乎与使用visual studio gui设计师有关。

此处的解决方法是在预构建事件中将锁定的输出文件移动到另一个临时文件中。随机生成临时文件名是有意义的。

del "$(TargetPath).locked.*" /q 
if exist "$(TargetPath)"  move "$(TargetPath)" "$(TargetPath).locked.%random%"
exit /B 0

如果使用常量临时文件名,您只需推迟锁定:

该解决方法只运行一次

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

我还找到了一个包含2个临时文件的解决方案,可以正常工作2次。

答案 2 :(得分:5)

我也遇到了问题。

我的情况是这样的:运行Windows 7(但也可能发生在Windows XP中)并且在使用WPF用户控件进行项目时我可以构建所有时间,直到打开用户控件的XAML文件 - 从那里,我有一个版本,然后文件被锁定。

另外,我注意到我以管理员身份运行Visual Studio(Devenv.exe),我已经开始运行没有管理员权限的Visual Studio,问题就消失了!

让我知道它是否对你有所帮助。祝你好运。

答案 3 :(得分:3)

您机器上的病毒扫描程序怎么样?你能看到任何持有文件句柄的进程(使用Process Explorer查找)吗?

也许在您的进程列表中可以看到“app.exe”,即您调试的最后一个版本仍在运行?当您开发具有多个线程的应用程序时,如果您没有join所有这些线程,则可能会发生这种情况。

答案 4 :(得分:3)

我在贪婪的病毒扫描软件上看到过这种情况,或者app.exe没有正常关闭。确保该过程仍未运行。

答案 5 :(得分:3)

我遇到了同样的问题,我发现VS在构建之前在VS中打开Form或UserControl时只锁定了exe。 解决方案非常简单,我只需要在构建解决方案之前关闭任何Form / UserControl,它就可以工作。

答案 6 :(得分:3)

基于伟大的Stormenet answer,我提出了一个适用于所有情况的小脚本。

以下是放入预构建事件文本框

的代码
$(SolutionDir)\BuildProcess\PreBuildEvents.bat  "$(TargetPath)"  "$(TargetFileName)"  "$(TargetDir)"  "$(TargetName)"

Pre build event

以下是要在文件$(SolutionDir)\BuildProcess\PreBuildEvents.bat中复制的脚本(当然您可以修改此路径):

REM This script is invoked before compiling an assembly, and if the target file exist, it moves it to a temporary location
REM The file-move works even if the existing assembly file is currently locked-by/in-use-in any process.
REM This way we can be sure that the compilation won't end up claiming the assembly cannot be erased!

echo PreBuildEvents 
echo  $(TargetPath) is %1
echo  $(TargetFileName) is %2 
echo  $(TargetDir) is %3   
echo  $(TargetName) is %4

set dir=C:\temp\LockedAssemblies

if not exist %dir% (mkdir %dir%)

REM delete all assemblies moved not really locked by a process
del "%dir%\*" /q

REM assembly file (.exe / .dll) - .pdb file - eventually .xml file (documentation) are concerned
REM use %random% to let coexists several process that hold several versions of locked assemblies
if exist "%1"  move "%1" "%dir%\%2.locked.%random%"
if exist "%3%4.pdb" move "%3%4.pdb" "%dir%\%4.pdb.locked%random%"
if exist "%3%4.xml.locked" del "%dir%\%4.xml.locked%random%"

REM Code with Macros
REM   if exist "$(TargetPath)"  move "$(TargetPath)" "C:\temp\LockedAssemblies\$(TargetFileName).locked.%random%"
REM   if exist "$(TargetDir)$(TargetName).pdb" move "C:\temp\LockedAssemblies\$(TargetName).pdb" "$(TargetDir)$(TargetName).pdb.locked%random%"
REM   if exist "$(TargetDir)$(TargetName).xml.locked" del "C:\temp\LockedAssemblies\$(TargetName).xml.locked%random%"

答案 7 :(得分:2)

还有一个已知问题533411,其中使用自动更新内部版本号会导致锁定问题。来自错误报告的解决方法

  

临时解决方法是在重建后禁用程序集版本更新。在AssemblyInfo.cs文件中,从AssemblyVersion属性中删除通配符,例如:
  替换这个:
      [assembly:AssemblyVersion(“1.4。*”)]
      [assembly:AssemblyFileVersion(“1.4”)]
  用这个:
      [assembly:AssemblyVersion(“1.4.0.0”)]
      [assembly:AssemblyFileVersion(“1.4.0.0”)]

答案 8 :(得分:2)

我遇到了这个问题并使用一些自定义代码解决了这个问题。见这里:Visual Studio 2010 build file lock issues

在接受的答案中编译实用程序,并在构建步骤中引用它以解决问题。我仍然在午餐时关掉VS 2010来清理早上的工作。

自定义代码的原因是经常推荐的解决方案只工作一次,然后重命名的文件也被锁定,阻止了重命名。这里我们只是将数据时间信息附加到文件中,以便重命名的版本不会发生冲突。

答案 9 :(得分:0)

唯一对我有用的是退出Visual Studio 2012,删除有问题的项目的BIN和OBJ文件夹,然后再次打开Visual Studio。

问题解决了......直到下一次。

答案 10 :(得分:0)

如果$(TargetPath)指向使用COM的DLL,请确保您具有默认构造函数。不知道为什么默认构造函数不会在那里推断出来。在这种情况下,添加默认构造函数对我有用。

答案 11 :(得分:0)

关闭Visual Studio,重新打开并重新加载最新的解决方案可以解决这个问题。 (Visual Studio 2013 Ultimate)

答案 12 :(得分:0)

我遇到了在VS2017中开发xamarin应用程序的相同事情。

恰好是Windows Defender使用devenv.exe锁定了exe / dll。

你可以去Win Defender并添加

from scipy import signal 
fs = 50000 # Sample frequency (Hz)
f0 = 50.0  # Frequency to be removed from signal (Hz)
Q = 30.0  # Quality factor
w0 = f0/(fs/2)  # Normalized Frequency
# Design notch filter
b, a = signal.iirnotch(w0, Q)

到流程排除列表。

答案 13 :(得分:0)

这是我找到的解决方案

  1. 取消选中项目设置中的Visual Studio Hosting Process,如下所示
  2. enter image description here

    1. 杀了exe。它将是来自taskmanager的applicationname.vshost.exe
    2. enter image description here

      1. 现在您可以重建应用程序并运行。
      2. 注意:您可以重新启用此选项,没有任何问题。

答案 14 :(得分:0)

我设法通过禁用McAfee LiveSafe实时扫描来解决此问题。我的.exe文件会像OP描述的那样锁定,我无法删除文件,这意味着我无法构建解决方案。禁用McAfee功能后问题就消失了。

然后我当然继续完全卸载McAfee,因为我的PC是新的,并且已经安装了该程序,所以只安装了McAfee。

答案 15 :(得分:-8)

我创建了一个新的空白解决方案,并将所有旧文件添加到其中。这在某种程度上解决了这个问题。