【问题标题】:Can't build my service : Unable to copy file because it is being used by another process无法构建我的服务:无法复制文件,因为它正在被另一个进程使用
【发布时间】:2013-04-26 13:31:46
【问题描述】:

我在 c# .net 中构建了一个 Windows 服务。我添加了 Pre-Build 和 Post-Build 事件以在构建上自动部署我的服务。但有时我得到了这个错误:

无法将文件“[CompletPath...]\bin\Debug\Business.Data.dll”复制到 “bin\Debug\Business.Data.dll”。进程无法访问文件 'bin\Debug\Business.Data.dll' 因为它正在被另一个人使用 过程。

在 Pre-Build 事件中,我将关闭服务,杀死所有使用 Debug 目录中文件的任务并卸载服务。我在 Pre-Build 事件中运行的 .bat 中有代码:

SET executionPath=%~dp0
SET serviceName=%1
SET frameworkPath=%2
SET targetServicePath=%3
SET targetBinPath=%~4
set targetBinPath=%targetBinPath:~0,-2%

net stop %serviceName%
powershell -NonInteractive -executionpolicy Unrestricted -file "%executionPath%\unlockfiles.ps1" "%targetBinPath%"
%frameworkPath%\installutil.exe /u %targetServicePath%

Exit /b 0

在我安装和启动服务的构建后事件中,即使这不是问题,也有代码,因为我在构建时遇到错误,所以构建后事件没有执行。

SET serviceName=%1
SET frameworkPath=%2
SET targetServicePath=%3

%frameworkPath%\installutil.exe /ShowCallStack %targetServicePath%
net start %serviceName%

我并不总是遇到问题。我通常在第一次构建时遇到问题,我正在清理解决方案,再次构建并且通常在此之后它可以工作。

【问题讨论】:

  • 您是否尝试过使用一些软件来找出锁定文件的原因?是 Visual Studio 还是您的服务?如果没有,请尝试使用:technet.microsoft.com/en-us/sysinternals/bb896653.aspx
  • 我正在使用 handle.exe 来杀死使用文件夹中文件的每个进程...

标签: c# visual-studio-2010 windows-services filelock pre-build-event


【解决方案1】:

如果我是你,我会把这些过程分开。您无需卸载服务即可更新文件。

除了在构建完成后移动一些文件之外,我不太喜欢构建前/构建后事件。

我使用 xcopy /y /c "$(TargetPath)" "要复制到的位置"

如果没有记忆,我什至实际上不必停止服务来更新 dll,但是您可能需要在执行 xcopy 命令之前在后期构建中停止服务。

【讨论】:

  • 我改变了我的设置来做这样的事情,但这并不是更好。我正在杀死复制文件的目录中的所有进程(用handle.exe杀死它),复制文件,但有些文件仍然被锁定。即使我正在使用handle.exe 杀死所有进程......但是如果我正在杀死这些进程,等待30 秒并在这个小睡眠后复制。一切正常...
  • 只是出于兴趣,您是否在 VS 中安装并运行此服务以对其进行测试?如果是这样,我会考虑转而使用单元测试,以便您可以在 Visual Studio 中进行测试并使用 WiX 构建完整的安装程序进行部署。 Visual Studio 并不是真正的部署工具,而您正试图将其与您的流程一起转变。
  • 我在预构建事件中卸载我的服务并在构建后事件中安装它。我的目标不是测试我的服务,我想做的是在有人构建项目时自动更新 Windows 服务。主要原因是因为我们 5 岁才能使用同一个解决方案,当有人在编辑服务时,我们都希望在我们的计算机上更新服务。起初我们是手动更新它,但每次你编辑它时总是告诉每个人更新服务是一件很痛苦的事。这就是我们想要自动化流程的原因。
  • 我将为此添加另一个答案。
【解决方案2】:

如果我处于你的情况,我会开始采用更面向团队的解决方案。

我会花一些时间使用 Team City 之类的工具设置持续集成系统(此工具可免费用于多达 20 种构建配置。我真的对 JetBrains 的所有内容进行评价。

然后,每次您的团队中的一个人签入服务的新源代码时,构建系统(Team City)都会自动检测到它,并且会触发一组新的构建。

您可以有一个针对代码运行单元测试的调试版本,一个发布版本,然后还包括一个WiX Project,然后还为该服务构建一个安装程序。

完成这些过程后,您可以将其配置为将安装程序弹出到您网络上的已知位置,然后它还可以向您团队中的所有开发人员发送电子邮件,通知他们有新版本的服务可供安装。

WiX 是一个非常成熟的安装创作工具,Microsoft 将其用于他们的许多产品。该工具集有很多支持,将使您的整个过程更加紧凑、可重复和可预测。

完成所有这些需要一些时间,但确实值得付出努力。

【讨论】:

  • 我们已经在使用团队城市,并使用它在 QA、Staging 和 Demo 环境中部署新版本。 Windows 服务与 Team-city 一起自动部署……但主要问题是我们的本地计算机……我们不想在每次发生变化时都运行安装程序。我们是 5 开发人员,在 1 天内我们有 10 到 15 次签到。非常感谢所有这些帮助。
  • Ahhh 好的,要尝试的另一件事可能是将服务编译到不是 \bin\Debug 或 \bin\Release 目录的位置并从那里安装。我曾经遇到过 Visual Studio 过去在这些位置处理文件并将它们全部移动到解决方案目录树中的另一个位置(例如:\Service)可以修复它们的问题。求助没问题:)
  • 是的,这正是我最终所做的......就像你建议的那样,我正在将文件复制到另一个文件夹,并从那里安装服务......但是在 Pre-Build 事件中,在停止服务并杀死所有进程(使用 handle.exe)之后,我仍然需要睡眠 +/- 20 秒,然后才能复制文件...
  • 是的,老实说,这并不让我感到惊讶,我敢肯定,即使您的 net stop 命令已“完成”,Windows 仍需要一段时间来关闭服务并释放文件锁定.很高兴你把它整理好了。
猜你喜欢
  • 2013-08-21
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 2018-03-27
  • 1970-01-01
相关资源
最近更新 更多