通过 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 期间启动了另一个进程。那就更难了。
我正在尝试删除服务使用的目录。因为该目录被服务使用。这就是为什么我必须停止服务。我可以通过以下代码启动或停止服务。
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 期间启动了另一个进程。那就更难了。