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

通过c#code Windows服务切换并尝试删除该服务使用的目录。,c#,service,delete-file,C#,Service,Delete File,我正在尝试删除服务使用的目录。因为目录被服务使用。这就是我必须停止服务的原因。我可以通过以下代码启动或停止服务 static void ToggleHostService(HostStatus serviceStatus) { var hostServiceName = "ServiceHost"; if (serviceStatus == HostStatus.run) { using (var contr

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

   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();
controller.Stop();
在删除目录之前,还要检查
是否(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));
   }
对我来说,这是造成“正在使用的文件”问题的最明显原因

但是,也看看Lalithanand Barla关于检查某个东西是否仍然使用此目录中的某个东西的建议

还有一个可能的问题:

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

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

我并没有一个很好的解决方案,也许在这段时间内需要一些睡眠(一秒钟左右)来重试删除操作


还可能存在这样的可能性,即服务不仅有挂起的线程,而且在启动过程中还会启动另一个进程。然后它将变得更加困难。

尝试process explorer进行调试…它将为您提供打开的句柄以及它打开了什么进程如何在程序中查找打开的句柄我尝试了它,但仍然得到相同的错误。我都试了120秒。好吧,我明白了。我忽略了您的通知“我可以在服务管理器窗口中看到服务确实已停止”。然而,您应该调用WaitForStatus()。是否每次都是同一个文件(backup.wal)?似乎是一个PostGreSQL文件。提前写日志?正如其他人指出的,您应该真正检查打开的文件句柄…如何以编程方式检查任何繁忙的文件或目录?