OdysseusYuan/LKY_OfficeTools · error · Exception

删除服务 {serv_name} 时,返回值为空!

Error message

删除服务 {serv_name} 时,返回值为空!

What it means

Thrown in Com_ServiceOS.Config.Delete when the stdout captured from `sc delete` via Com_ExeOS.Run.Cmd is null or empty (Com_ServiceOS.cs:349-351). Because Run.Cmd returns null only from its catch, this signals a cmd.exe/redirect infrastructure failure rather than an sc error. Delete has no try/catch, so the exception PROPAGATES to the caller.

Source

Thrown at LKY_OfficeTools/Common/Com_ServiceOS.cs:351

            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
                    {
                        throw new Exception($"删除服务 {serv_name} 失败!");
                    }
                }
                else
                {
                    throw new Exception($"没有找到名称为 {serv_name} 的服务,无法删除该服务!");
                }
            }

View on GitHub (pinned to 6f9a1bd471)

Solutions

  1. Wrap Config.Delete in try/catch (Delete does not catch its own throws).
  2. Ensure cmd.exe is on PATH and not blocked by policy; run elevated.
  3. Run `sc delete <name>` directly in a console to confirm sc itself works.
  4. Check Lib_AppLog for the exception captured by Run.Cmd's catch for the real cause.

Example fix

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

// after
try { Com_ServiceOS.Config.Delete(servName); }
catch (Exception ex) { /* log ex; fall back to `sc delete` via a shell if Cmd infrastructure failed */ }
Defensive patterns

Strategy: try-catch

Validate before calling

if (string.IsNullOrEmpty(Com_ExeOS.Run.Cmd("ver"))) { /* cmd broken; fix env */ return; }

Try / catch

try
{
    Com_ServiceOS.Config.Delete(servName);
}
catch (Exception ex) when (ex.Message.Contains("返回值为空"))
{
    // Cmd infrastructure failed; fall back to running `sc delete` via another shell.
}

Prevention

When it happens

Trigger: Run.Cmd throws because cmd.exe cannot launch, output redirection fails, or the process is terminated before writing stdout. A genuine sc failure (access denied / not found) still returns non-empty text and would hit error 7 instead.

Common situations: cmd.exe blocked by AppLocker/WDAC; stripped Windows image without cmd; stdio handle exhaustion under heavy process spawning; security software intercepting redirected console output.

Related errors


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