在VS2012 c#项目的构建过程中,我一直得到这个错误
Error 41 Could not copy "obj\Debug\WeinGartner.WeinCad.exe" to
"bin\Debug\WeinGartner.WeinCad.exe".
Exceeded retry count of 10. Failed.
Error 42 Unable to copy file "obj\Debug\WeinGartner.WeinCad.exe" to
"bin\Debug\WeinGartner.WeinCad.exe". The process cannot access the file
'bin\Debug\WeinGartner.WeinCad.exe' because it is being used by another
process.
现在我知道该终止进程了
Weingartner.WeinCad.vhost.exe
(有时)有用,但这让我很紧张。有办法阻止这一切发生吗?
调试器设置为
使用Ms进程资源管理器查看是否需要在Windows 7中打开“应用程序体验”
在我的情况下,所有其他建议都不起作用(Windows 7, VS2019)
编译后,生成的. exe文件被重新锁定约一分钟。另一个奇怪的观察:当删除。exe文件时,它像往常一样消失在文件资源管理器中,但在刷新时(F5)重新出现。
您可以使用MS进程资源管理器来查找是否有任何进程持有生成的. exe文件的句柄。为此,查看进程资源管理器的“下窗格”,选择查看句柄而不是dll,并使用“查找”来搜索您的. exe文件。
这告诉我,这是Windows 7的“系统”进程,得到了一个句柄。exe。
一些研究显示,我必须打开Windows的“应用程序体验”服务(“自动启动”)才能永久摆脱这种奇怪的行为。
以下是更多信息:
在什么情况下,系统进程(PID 4)保留一个打开的文件句柄?
在我的情况下,它是Resharper单元测试运行器(加上NUnit测试,从来没有这样的问题与MsTests)。在杀死进程后,可以重建进程,而无需重新启动OS或VS2013。
其他测试运行程序,比如xUnit,也会导致同样的问题。
有帮助的方法是检查是否可以添加Dispose模式,例如,如果您正在添加DbFixture,而数据库联系人没有正确地处理。这将导致即使测试完成,程序集文件也被锁定。
请注意,您可以将IDisposable接口添加到DbFixture中,并让IntelliSense添加Dispose模式。然后,处理相关的包含属性,并显式地将它们赋值为null。
这将有助于以一种干净的方式结束测试,并在测试结束后立即解锁相关的锁定文件。
示例(DBFixture由xUnit测试使用):
public class DbFixture: IDisposable
{
private bool disposedValue;
public ServiceProvider ServiceProvider { get; private set; }
public DbFixture()
{
// initializes ServiceProvider
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// dispose managed state (managed objects)
ServiceProvider.Dispose();
ServiceProvider = null;
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
disposedValue = true;
}
}
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
// ~DbFixture()
// {
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
// Dispose(disposing: false);
// }
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
测试类本身也需要相同的模式——它需要自己的Dispose方法(如上面的DbFixture类所示):
public SQL_Tests(ITestOutputHelper output)
{
this.Output = output;
var fixture = new DbFixture(); // NOTE: MS Dependency injection framework didn't initialize when the fixture was a constructor param, hence it is here
_serviceProvider = fixture.ServiceProvider;
} // method
因此,它需要在自己的dispose方法中处置其本地属性_serviceProvider,因为测试类构造函数SQL_Tests实例化了它。
在Visual Studio Premium 2013 (Update 3)中,我用一个预构建的一行程序解决了这个问题:
(if exist "$(TargetDir)*old.pdb" del "$(TargetDir)*old.pdb") & (if exist "$(TargetDir)*.pdb" ren "$(TargetDir)*.pdb" *.old.pdb)
这将优雅地删除任何旧的PDB文件(如果可以的话),然后重命名任何带有.old的文件。pdb的扩展。一个很好的副作用是,如果旧的PDB仍然是锁定的,它只是在文件名中添加另一个.old块,并且在下次重新启动Visual Studio并进行构建时,它们都将被清除。
例如,构建/调试会话1离开MyProject。pdb锁定。
下次构建时:
MyProject的。MyProject.old.pdb
然后,构建/调试会话2启动,并且MyProject。pdb和MyProject.old.pdb仍然锁定:
MyProject.old.pdb—> MyProject.old.old.pdb
MyProject的。MyProject.old.pdb
最后,重新启动Visual Studio并进行一个新的构建将摆脱这两个问题,并像往常一样继续这个过程。
我在Visual Studio 2013中遇到过类似的错误消息。
大多数情况下,我发现这种情况发生在调试进程因为异常而停止时。
当clean+build不能为我解决这个问题时,我通过以下方法取得了成功:
关闭Visual Studio
删除bin和obj文件夹
重新开放Visual Studio。
此“bug”自Visual Studio 2003以来一直存在。
最后,我还发现我通常可以通过简单地重命名可执行文件然后删除它来克服这个问题。