简体   繁体   中英

How can I execute a batch script in a windows service in C#?

I'm trying to execute a .bat script in a C# windows service but it doesn't seem to be working.

So the script I am trying to execute, startup.bat , in turn calls another script, call catalina.bat ... , which in turn executes start java ...

I can execute startup.bat manually but I want to run it as a Windows service. When I try to do that in a C# windows service application, nothing seems to happen. My Windows service code looks like this:

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

I don't understand why this doesn't execute. What am I doing wrong?

And yes, you may notice I'm trying to launch Tomcat on Windows as a service with C#. Well I'm doing that because I haven't been able to use tomcat7.exe for various reasons but it's probably better to not ask why I'm doing such things. Whatever the reason is, what I'm doing here should also work, shouldn't it?

Update in response to Gabe's suggestion:

If I set UseShellExecute = true I get an exception:

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)

So I set RedirectStandardError and RedirectStandardOutput to false, which yields this error:

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)

argh! I feel exasperated!

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

To close the loop on this, the problem was indeed Windows security permission issues.

The suggestion made here seemed to resolve my issue.

Try setting "Allow service to interact with desktop" in your service setting.

Possible duplicate - Run Batch-Files in Windows Service while logged off

Try:

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

If your script runs fine as an interactive user but not as a service then there are a couple of obvious possible causes:

  1. Your service is running under a user account that is unable to perform the actions in the script.
  2. Your script tries to interact with the desktop but can't because of session 0 isolation.

These suggestions are essentially guesses but with so little information it's hard to do better.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM