我知道已经有人问过这个问题,但到目前为止我找不到解决方案。
我想要做的是卸载 Windows 服务并使用 C# 删除带有 Windows 服务的文件夹。
Windows 服务卸载
public static void Uninstall(string exeFilename)
{
var commandLineOptions = new string[1] { "/LogFile=uninstall.log" };
if (!Directory.Exists(exeFilename)) return;
var fileNames = Directory.GetFiles(exeFilename);
var serviceFile = fileNames.FirstOrDefault(f => f.EndsWith(".exe"));
var serviceFileName = Path.GetFileName(serviceFile);
var serviceName = Path.GetFileNameWithoutExtension(serviceFile);
var serviceExists = ServiceController.GetServices().Any(s => s.ServiceName == serviceName);
if (!serviceExists) return;
var installer =
new AssemblyInstaller($"{exeFilename}\\{serviceFileName}", commandLineOptions)
{
UseNewContext = true
};
installer.Uninstall(null);
installer.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
文件夹和文件删除
public static void DeleteFolder(string folderPath)
{
if(!Directory.Exists(folderPath)) return;
try
{
foreach (var folder in Directory.GetDirectories(folderPath))
{
DeleteFolder(folder);
}
foreach (var file in Directory.GetFiles(folderPath))
{
var pPath = Path.Combine(folderPath, file);
File.SetAttributes(pPath, FileAttributes.Normal);
File.Delete(file);
}
Directory.Delete(folderPath);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误
Access to the path 'c:\services\x\x.exe' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at System.IO.File.Delete(String path)
Run Code Online (Sandbox Code Playgroud)
这个错误是随机发生的。.exe 文件不是只读的,有时文件会被删除。
有谁知道出了什么问题?
停止 Windows 服务并不等同于退出进程。一个可执行文件可以容纳多个 Windows 服务(它本质上是服务的物理外壳)。
因此,您遇到的情况似乎是该服务可能停止正常,并且卸载可以继续并且文件的删除可以继续,但只能直到它到达可执行文件的点为止,而尚未执行有机会退出。
停止、退出、卸载都是异步的,需要时间完成才能进入下一步。
你要做的就是遵循这个公式
Uninstall().DeleteFolder()您的实现对我来说足够的 。退出进程
编写一个看起来像这样的方法。你可能想要调整它。
void Exit(Process p)
{
for (int i = 0; i <= 5; i++)
{
// doesn't block
if (p.HasExited) return;
// doesn't block; pass true to terminate children (if any)
p.Kill(true);
// wait 5 seconds then try again
Thread.Sleep(5000);
}
}
Run Code Online (Sandbox Code Playgroud)
毕竟,你应该很高兴去。
服务是否已停止/可执行文件是否已停止以及程序是否具有管理员访问权限?如果您没有管理员访问权限,请参阅: 如何强制我的 .NET 应用程序以管理员身份运行? 以管理员身份运行。卸载程序时,几乎总是需要管理员权限。如果仍然失败,则您不是该文件的所有者,您必须将所有者更改为您自己或管理员。您可以在此处以编程方式执行此操作:在 C# 中获取/设置文件所有者
| 归档时间: |
|
| 查看次数: |
162 次 |
| 最近记录: |