【问题标题】:How can I execute a batch script in a windows service in C#?如何在 C# 的 Windows 服务中执行批处理脚本?
【发布时间】:2011-08-25 08:16:10
【问题描述】:

我正在尝试在 C# Windows 服务中执行 .bat 脚本,但它似乎无法正常工作。

所以我尝试执行的脚本startup.bat 又调用另一个脚本call catalina.bat ...,而后者又执行start java ...

我可以手动执行 startup.bat,但我想将它作为 Windows 服务运行。当我尝试在 C# Windows 服务应用程序中执行此操作时,似乎什么也没发生。我的 Windows 服务代码如下所示:

public class MyService : ServiceBase
{
    public static void Main(string[] args)
    {
        ServiceBase.Run(new MyService());
    }

    protected override void OnStart(string[] args)
    {
        base.OnStart(args);
        this.RunScript(@"bin\startup.bat");
        Thread.Sleep(1000);
    }

    protected override void OnStop()
    {
        base.OnStop();
        this.RunScript(@"bin\shutdown.bat");
        Thread.Sleep(1000);
    }

    private void RunScript(string processFileName)
    {
        var startInfo = new ProcessStartInfo
        {
            FileName = "cmd.exe",
            Arguments = "/C " + Path.Combine(@"C:\server", processFileName),
            CreateNoWindow = true,
            ErrorDialog = false,
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            UseShellExecute = false,
            WindowStyle = ProcessWindowStyle.Hidden
        };

        startInfo.EnvironmentVariables.Add("CATALINA_HOME", @"c:\server");

        var process = new Process();
        process.StartInfo = startInfo;
        process.Start();
    }
}

我不明白为什么这不执行。我做错了什么?

是的,您可能会注意到我正在尝试在 Windows 上启动 Tomcat 作为使用 C# 的服务。好吧,我这样做是因为由于各种原因我无法使用 tomcat7.exe,但最好不要问我为什么要这样做。不管是什么原因,我在这里做的应该也可以,不是吗?

根据 Gabe 的建议进行更新:

如果我设置 UseShellExecute = true 我得到一个异常:

System.InvalidOperationException: The Process object must have the UseShellExecute property set to false in order to redirect IO streams.
    at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
    at System.Diagnostics.Process.Start()
    at MyService.RunScript(String processFileName)

所以我将 RedirectStandardError 和 RedirectStandardOutput 设置为 false,从而产生此错误:

System.InvalidOperationException: The Process object must have the UseShellExecute property set to false in order to use environment variables.
  at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
  at System.Diagnostics.Process.Start()
  at MyService.RunScript(String processFileName)

啊!我感到很生气!

【问题讨论】:

  • 我认为您需要UseShellExecute = true 才能使其工作。
  • 更新了如果我尝试这个会发生什么。谢谢。
  • 其实我更新了startup.bat,所以它不需要环境变量。还是什么都没有... :(
  • 真的需要stdio重定向吗?
  • 我的意思是在将 UseShellExecute 设置为 true 后,我将 RedirectStandardOutput 设置为 false。我还接受了一些老问题的答案……现在更好了吗?

标签: c# windows windows-services batch-file


【解决方案1】:

试试:

FileName = "%comspec%",
Arguments = "/C " + Path.Combine(@"C:\server", processFileName),

【讨论】:

    【解决方案2】:

    为了结束这个循环,问题确实是 Windows 安全权限问题。

    here 的建议似乎解决了我的问题。

    【讨论】:

      【解决方案3】:

      如果您的脚本作为交互式用户运行良好但不能作为服务运行,那么有几个明显的可能原因:

      1. 您的服务在无法执行脚本中的操作的用户帐户下运行。
      2. 您的脚本尝试与桌面交互,但由于会话 0 隔离而无法进行。

      这些建议基本上是猜测,但信息太少,很难做得更好。

      【讨论】:

      • 是的,抱歉,我不知道我还能提供什么其他信息。如果有帮助,可以通过从他们的站点下载Tomcat 7 zip 来复制我正在做的事情,然后尝试手动运行 bin\startup.bat 文件以查看它是否有效(端口 8080 应该打开),然后创建一个 Windows使用我发布的确切代码作为服务启动它的服务...我使用sc.exe create t1 binPath= my.exe DisplayName= myservice顺便安装了该服务。
      • 我不明白您为什么要尝试从服务安装服务?为什么?
      【解决方案4】:

      运行“cmd.exe”并将“startup.bat”作为参数传递。

      【讨论】:

      • 这通常需要/C startup.bat IIRC
      • 我在最初的帖子中使用 FileName = "cmd.exe", Arguments = "/C" + 命令更新了示例中的代码。仍然没有运气。我应该提到,当我从命令行运行 startup.bat 时,它会打开一个子命令行窗口。这可能是个问题吗?
      【解决方案5】:

      尝试在您的服务设置中设置“允许服务与桌面交互”。

      可能重复 - Run Batch-Files in Windows Service while logged off

      【讨论】:

      • 启用“允许服务与桌面交互”仍然无法正常工作。
      猜你喜欢
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-08
      • 1970-01-01
      • 2023-03-27
      • 2013-07-30
      • 2011-06-15
      相关资源
      最近更新 更多