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

By the c# code Windows service toggle and trying to remove a directory used by that service.

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

   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();
            }
        }
    }

但是当我试图删除目录时,出现异常

Unhandled Exception: System.IO.IOException: The process cannot access the file ' backup.wal' because it is being used by another process.

我可以在服务管理器window中看到服务真的停止了。但为什么它仍然抱怨它无法访问。确保我在管理员模式下 运行 app/code。我试过了请告诉我如何才能真正强制删除该目录。

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

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

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

controller.Stop();

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

您必须等到服务停止。我只是查看了我编写的一些代码,这些代码执行此操作并在生产环境中运行了几年并更改了您的代码:

   if (controller.Status != ServiceControllerStatus.Stopped)
   {
       controller.Stop();

       // we do not need Refresh
       // controller.Refresh();

      controller.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30));
   }

对我来说,这是您 "file in use" 问题最明显的原因。

但是,另请参阅 Lalithanand Barla 关于检查某些内容是否仍在使用此目录中的内容的建议。

还有一个可能的问题:

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

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

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

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