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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2002273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 11:21:41  来源:igfitidea点击:

Visual Studio locks output file on build

visual-studio

提问by Nevermind

I have a simple WinForms solution in VS 2010. Whenever I build it, output file (bin\debug\app.exe) ends up locked, and subsequent builds fail with a message like "The process cannot access the file 'bin\Debug\app.exe' because it is being used by another process."The only way to build the project is to restart VS after every build, which is veryawkward.

我在 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."The only way to build the project is to restart VS after after每一个构建,这是非常尴尬的。

I have found this old blog post http://blogs.geekdojo.net/brian/archive/2006/02/17/VS2005FileLocking.aspx- it seems that the problem is really old. Does anyone know what is happening here, or at least some workaround?

我找到了这篇旧博客文章http://blogs.geekdojo.net/brian/archive/2006/02/17/VS2005FileLocking.aspx- 看来问题真的很老了。有谁知道这里发生了什么,或者至少有一些解决方法?

Update

更新

I don't actually runthe file. Locking happens after build, not after debug (i.e. start VS - build - build - fail!) And I tried turning antivirus off. It doesn't help.

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

Update 2

更新 2

Process Explorer shows devenv.exe having loaded the file (in DLLs, not in Handles). It seems like some glitch during build prevented the unloading, but the (first) build completes without any messages other then "1 succeeded, o failed"/

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

采纳答案by Nevermind

I have created a new blank solution and added all the old files to it. This somehow solved the problem.

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

回答by Stormenet

Had the same issue, but found a solution (thanks to Keyvan Nayyeri):

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

But how to solve this? There are various ways based on your project type but one simple solution that I recommend to Visual Studio add-in developers is to add a simple code to their project's build events.

但是如何解决这个问题呢?根据您的项目类型,有多种方法,但我向 Visual Studio 加载项开发人员推荐的一种简单解决方案是向其项目的生成事件添加简单代码。

You can add following lines of code to the pre-build event command line of your project.

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

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

回答by Vladimir Datsyuk

It is not a virus issue. It is visual studio 2010 bug. It seems the issue is related to using visual studio gui designer.

这不是病毒问题。这是 Visual Studio 2010 的错误。问题似乎与使用 Visual Studio gui 设计器有关。

The workaround here is to move locked output file into another temporary one in pre-build event. It make sense to generate temporary file name randomly.

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

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

In case of using constant temporary file names you will just postpone locks:

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

That workaround works exactly once

该解决方法仅适用一次

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

I have also found a solution with 2 temporary files that works exactly 2 times.

我还找到了一个包含 2 个临时文件的解决方案,该文件正好可以运行 2 次。

回答by Shani Elharrar

The problem occurred to me too.

我也遇到了这个问题。

My scenario was this : Running windows 7 (But might also happened in Windows XP) and while working on a project with WPF User Control I could build all of the times, Until opening the XAML file of the User Control - From there, I've got one build, and then the files are locked.

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

Also, I've noticed that I was running Visual Studio (Devenv.exe) as Administrator, I've started to run Visual Studio without Administrator privileges and the problem was gone!.

另外,我注意到我以管理员身份运行 Visual Studio (Devenv.exe),我开始在没有管理员权限的情况下运行 Visual Studio,问题就解决了!.

Let me know if it helped you too. Good luck.

如果它对你也有帮助,请告诉我。祝你好运。

回答by Enyra

I had the same problem and I found out, that VS only locks the exe when I opened a Form or UserControl in VS before building. The solution was quite easy, I just had to close any Form/UserControl before I build the solution and it worked.

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

回答by Patrick from NDepend team

Base on the great Stormenet answer, I put up a small script that should work in all cases.

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

Here is the code to put in the pre build event text box

这是放在预构建事件文本框中的代码

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

Pre build event

预构建事件

Here is the script to copy in the file $(SolutionDir)\BuildProcess\PreBuildEvents.bat(of course you can modify this path):

下面是复制到文件中的脚本$(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%"

回答by naivists

What about virus scanners on your machine? Can you see any processes that are holding handles to your file (use Process Explorerto find out)?

你机器上的病毒扫描程序呢?你能看到任何持有文件句柄的进程吗(使用进程资源管理器找出)?

Maybe there is "app.exe" visible in your process list, i.e the last version you debugged is still running? When you develop applications which have multiple threads, this may happen if you don't joinall of them.

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

回答by McAden

I've seen this on either a greedy virus scanning software, or if app.exe isn't shutting down properly. Make sure the process isn't still running.

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

回答by Godeke

I had this problem and resolved it with some custom code. See here: Visual Studio 2010 build file lock issues

我遇到了这个问题并用一些自定义代码解决了它。请参阅此处:Visual Studio 2010 构建文件锁定问题

Compile the utility in the accepted answer and reference it during the build step as described to workaround the problem. I still turn off VS 2010 at lunch to clean up the morning's work.

在已接受的答案中编译该实用程序,并在构建步骤中参考它,如解决问题所描述的那样。我仍然在午餐时关闭 VS 2010 来清理早上的工作。

The reason for the custom code was that the often recommended solution only worked once and then the renamed files were also locked, preventing the rename. Here we just append the data-time info to the file so the renamed versions can't conflict.

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

回答by Robert MacLean

There is also a known issue 533411where the usage of automatically updating build numbers can cause the locking issue. Workaround from bug report

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

Temporary workaround would be disable assembly version update after the rebuild. In AssemblyInfo.cs file, remove the wild card from the AssemblyVersion attribute, for example:
replace this:
[assembly: AssemblyVersion("1.4.*")]
[assembly: AssemblyFileVersion("1.4")]
with this:
[assembly: AssemblyVersion("1.4.0.0")]
[assembly: AssemblyFileVersion("1.4.0.0")]

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

回答by Onyximo

If your $(TargetPath) points to a DLL that uses COM ensure you have a default constructor. Not sure why the default constructor is not inferred there. Adding the default constructor worked for me in this scenario.

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