.NET 4.7启动ServiceBase服务后 无关项目DLL被锁无法编译
问题原因说明
- 首先确认是否为解决方案配置了统一的公共输出目录:多数多项目开发场景下会将所有项目的编译输出路径设置为同一个共享文件夹(例如
$(SolutionDir)/bin/$(Configuration)),你的ServiceBase服务启动时默认将这个共享输出目录作为应用程序根目录。 - .NET Framework默认对Windows服务关闭了程序集影子复制功能:运行时启动时会扫描应用程序根目录下的所有DLL文件,部分依赖注入框架、反射扫描逻辑还会主动加载目录下的所有程序集,即便这些程序集没有被服务项目显式引用,也会通过MMF(内存映射文件)机制锁定原始文件。
- 无关项目编译失败的直接原因:你编译独立项目时,MSBuild需要覆盖输出路径下的对应DLL文件,但该文件已经被运行中的服务持有锁,因此会触发写入失败的报错。
解决方法
- 调整独立项目的输出路径:将和服务无关的项目的编译输出路径改为独立目录,不要和服务项目共用输出文件夹,从根源上避免无关DLL出现在服务的扫描目录中。
- 为服务开启程序集影子复制:在服务的入口函数最开头添加影子复制开启逻辑,让运行时加载程序集的副本而非锁定原始文件,.NET 4.7下可用的实现代码如下:
static void Main() { // 开启影子复制,不会锁定原始DLL文件 AppDomain.CurrentDomain.SetShadowCopyFiles(); // 原有服务启动逻辑保持不变 ServiceBase[] servicesToRun = new ServiceBase[] { new CustomService() }; ServiceBase.Run(servicesToRun); }
- 单独部署服务运行文件:不要直接在编译输出目录启动服务,而是将服务运行需要的依赖文件复制到独立的运行目录后再启动服务,避免和编译输出路径产生冲突。
内容的提问来源于stack exchange,提问作者Doidel
相关产品推荐
相关产品推荐

