OdysseusYuan/LKY_OfficeTools · error · Exception

服务 {serv_name} 因无法停止,导致卸载失败!

Error message

服务 {serv_name} 因无法停止,导致卸载失败!

What it means

Thrown in Com_ServiceOS.Config.Delete when Action.Stop(serv_name) returns false before issuing `sc delete` (Com_ServiceOS.cs:340-343). Unlike Create/Modify, Delete has NO try/catch, so this exception PROPAGATES to the caller. Stop returns false when the service is absent, when control.Stop() throws (e.g. not enough privilege), or when the service does not reach Stopped within the 10s poll window.

Source

Thrown at LKY_OfficeTools/Common/Com_ServiceOS.cs:342

                    }
                }
                catch (Exception Ex)
                {
                    new Log(Ex.ToString());
                    return false;
                }
            }

            internal static bool Delete(string serv_name)
            {
                if (Query.IsCreated(serv_name))
                {
                    //已经创建服务,才能删除

                    //先停止服务
                    if (!Action.Stop(serv_name))
                    {
                        throw new Exception($"服务 {serv_name} 因无法停止,导致卸载失败!");
                    }

                    string cmd_del = $"sc delete \"{serv_name}\"";
                    var del_result = Com_ExeOS.Run.Cmd(cmd_del);

                    //非空判断,若返回值为空,则为假
                    if (string.IsNullOrEmpty(del_result))
                    {
                        throw new Exception($"删除服务 {serv_name} 时,返回值为空!");
                    }

                    //判断是否删除成功
                    if (del_result.Contains("成功") || del_result.ToLower().Contains("success"))
                    {
                        return true;
                    }
                    else
                    {

View on GitHub (pinned to 6f9a1bd471)

Solutions

  1. Wrap the Config.Delete call in try/catch since Delete does not swallow its own exceptions.
  2. Stop the service manually first with `sc stop` / `net stop` and wait for Stopped before calling Delete.
  3. Run the host process elevated so control.Stop() has the required privilege.
  4. Kill a hung service host (taskkill /F) if graceful stop never completes, then retry Delete.

Example fix

// before
Com_ServiceOS.Config.Delete(servName);

// after
try { Com_ServiceOS.Config.Delete(servName); }
catch (Exception ex) when (ex.Message.Contains("无法停止"))
{
    // force-stop then retry once
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-stop to avoid the failure path
if (Com_ServiceOS.Query.IsCreated(servName) && !Com_ServiceOS.Action.Stop(servName))
{ /* warn: graceful stop failed; consider force */ }

Try / catch

try
{
    Com_ServiceOS.Config.Delete(servName);
}
catch (Exception ex) when (ex.Message.Contains("无法停止"))
{
    // Stop returned false before delete; force-stop host or widen timeout, then retry.
}

Prevention

When it happens

Trigger: Calling Config.Delete on a service that will not stop within 10 seconds (long shutdown), depends on other running services, requires elevation to stop, or whose process is hung and ignores the stop control.

Common situations: Uninstall routine while the service's host process is hung; stopping a service blocked by dependent services; non-elevated host process; service in StopPending forever.

Related errors


AI-assisted analysis of OdysseusYuan/LKY_OfficeTools@6f9a1bd471 (2026-08-13). Data as JSON: /api/errors/63013589b56059ae. Report an issue: GitHub.