簡體   English   中英

刪除帶有文件的 Windows 服務文件夾會引發錯誤

[英]Delete windows service folder with files throws error

我知道已經有人問過這個問題,但到目前為止我找不到解決方案。

我想要做的是卸載 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();
    }

文件夾和文件刪除

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

我得到的錯誤

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)

這個錯誤是隨機發生的。 .exe 文件不是只讀的,有時文件會被刪除。

有誰知道出了什么問題?

停止 Windows 服務並不等同於退出進程。 一個可執行文件可以容納多個 Windows 服務(它本質上是服務的物理外殼)。

因此,您遇到的情況似乎是該服務可能停止正常,並且卸載可以繼續並且文件的刪除可以繼續,但只能直到到達可執行文件的點為止,而尚未執行有機會退出。

停止、退出、卸載都是異步的,需要時間完成才能進入下一步。

你要做的就是遵循這個公式

  1. 如果可以,請確保您的代碼以提升的權限運行; 如果你不能,你可能會遇到Access Denied 您還可以嘗試更改目標可執行文件的所有權。
  2. 停止或確保服務已停止。 如果有多個服務,請停止所有服務。
  3. 等待停止實際發生。 這並不總是立竿見影的。
  4. 調用Uninstall()
  5. 等待一段時間。 檢查進程是否正在運行。 如果是,您將調用Process.Kill() (請參閱下面的實現)。
  6. 最后,您可以調用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);
    }
}

畢竟,你應該很高興去。

服務是否停止/可執行文件停止,程序是否具有管理員訪問權限? 如果您沒有管理員訪問權限,請參閱: 如何強制我的 .NET 應用程序以管理員身份運行? 以管理員身份運行。 卸載程序時,幾乎總是需要管理員權限。 如果仍然失敗,則您不是該文件的所有者,您必須將所有者更改為您自己或管理員。 您可以在此處以編程方式執行此操作: 在 C# 中獲取/設置文件所有者

我認為你必須先停止服務。 嘗試使用

sc stop <service name>

停止服務。 然后卸載應該可以工作。 如果您的卸載代碼不起作用,請嘗試使用 installutil.exe。 它也可以提供您的錯誤輸出。 如果 exe 當前正在執行,則無法刪除它,因此當您嘗試刪除它時,請確保 exe 未在執行。

您可以使用安裝項目,它會自動生成卸載程序並為您提供一系列可能性。

服務安裝程序示例

您必須在市場上下載插件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM