通过 c# 代码 Windows 服务切换并尝试删除该服务使用的目录



我正在尝试删除服务使用的目录。因为该目录由服务使用。这就是为什么我必须停止服务。我可以通过以下代码启动或停止服务。

static void ToggleHostService(HostStatus serviceStatus)
{
var hostServiceName = "ServiceHost";
if (serviceStatus == HostStatus.run)
{
using (var controller = new ServiceController(hostServiceName))
{
if (controller.Status != ServiceControllerStatus.Running)
controller.Start();
controller.Refresh();
}
}
else if (serviceStatus == HostStatus.stop)
{
using (var controller = new ServiceController(hostServiceName))
{
if (controller.Status != ServiceControllerStatus.Stopped)
controller.Stop();
controller.Refresh();
}
}
}

但是当我尝试删除目录时,我得到异常

未处理的异常:System.IO.IOException:进程无法访问 文件" backup.wal",因为它正被另一个进程使用。

我可以在服务管理器窗口中看到服务确实已停止。但是为什么它仍然抱怨它无法访问。确保我在管理员模式下运行应用程序/代码。我试过请告诉我如何真正强制删除该目录。

我假设您有一个单独的应用程序或服务来删除目录。如果您之前出于某种原因正在使用该目录,则该应用程序或服务可能会锁定该文件夹。为了使用以下代码释放与目录相关的任何内容。这需要在删除目录之前写入:

GC.Collect();
GC.WaitForPendingFinalizers();

在删除目录之前,还要检查If(Directory.Exists())以处理相关异常。您也可以使用dispose()来释放目录使用的内存。

controller.Stop();

不会等到服务停止,它只是将服务置于"停止挂起"状态。

您必须等到服务停止。我刚刚查看了我编写的一些代码,这些代码可以做到这一点并在生产中运行几年并更改了您的代码:

if (controller.Status != ServiceControllerStatus.Stopped)
{
controller.Stop();
// we do not need Refresh
// controller.Refresh();
controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30));
}

对我来说,这是您的"文件使用中"问题的最明显原因。

但是,也看看Lalithanand Barla的建议,以检查某些东西是否仍然使用此目录中的某些内容。

还有一个可能的问题:

通常,Windows 服务会启动一个或多个工作线程/任务。在 OnStop() 方法中,服务应等到所有线程都停止。

如果您尝试停止的服务没有以这种方式运行,则可能存在仍处于活动状态的线程,这也会导致文件正在使用中。

我真的没有一个好的解决方案,也许在睡眠(一秒钟左右)之间重试删除操作。

还可能服务不仅具有挂起的线程,而且还会在 OnStart 期间启动另一个进程。那就更难了。

最新更新