在我们的生产版本中,根目录中的一个非常大(10 兆字节)的静态内容文件有时会被 IIS 锁定,无法通过清理任务删除。这可能是因为它当时正在主动为一个或多个客户端提供服务。
构建过程会在清理之前停止网站
c:\Windows\System32\inetsrv\appcmd.exe stop site http://oursite.com
然而,这才不是释放文件——我们必须重新启动 IIS 以使进程放弃其锁。
appcmd.exe
允许您彻底关闭 IIS;我们不要想做这个!
有没有其他方法可以让 IIS 释放锁定的文件,而无需重新启动 IIS?简单地停止并启动单个网站肯定无法释放文件锁定。
答案1
有一些工具(例如 Sysinternal 的 Process Explorer)可以查找并强制关闭文件句柄,但是执行此操作后应用程序(您的应用程序和本例中的 IIS)的状态和行为是不确定的。有些应用程序不会在意,有些应用程序会出错,有些应用程序会严重崩溃。
正确的解决方案是接受中断并允许 IIS 干净地释放锁定并自行清理以保持服务器稳定性。如果这不可能,您可以在同一台机器上创建另一个站点,或者设置一个包含新内容的新机器,然后移动域名/IP 以将新内容“推广”到生产环境。
答案2
我使用一个小工具叫“处理”去做这个。
您基本上将锁定的文件的名称传递给它,它会告诉您哪些进程正在使用它:
handle c:\weird.file
Something.exe pid: 1000 100: C:\weird.file
Something.exe pid: 1000 101: C:\weird.file
然后传递 -c 开关让它关闭句柄:
handle.exe -c 101 -p 1000 -y
handle.exe -c 100 -p 1000 -y
您可能很难在没有包装程序来解析输出的情况下将其纳入构建脚本,但希望这会有所帮助。
答案3
我不确定你指的是在临时程序集中编译 aspx 文件。我们正在使用ASP.NET 部署项目,它预先编译所有 aspx/ascx 文件。
在将二进制文件从“publish”复制到“bin”文件夹时,我们临时启用了一个 app_offline.htm 文件,该文件在所有程序集复制完成后被删除(只需几秒钟)。这样我就再也没有遇到过文件锁定的情况。
编辑:
您可以尝试使用 appcmd.exe 回收应用程序池,而不是停止网站:
C:\Windows\System32\inetsrv\appcmd.exe recycle apppool "My App Pool Name"