简体   繁体   中英

Process.Start() Hangs Service When Command Waits for User Input

I have an app where users can enter a dos command to be run at a later time by a service. Here is an example of what a user can enter:

在此输入图像描述

This works well, but since a service runs the command, the /Q parameter must be there because there is no human interaction. I'm trying to figure out how the service can gracefully handle when the /Q is missing. As it stands now, the service actually hangs, and has to be stopped (a couple of times) and then started again. This happens because a command without /Q ends up waiting for user input.

This is the (slimmed-down) code to run a command:

using (Process process = new Process())
{
    string processOutput = string.Empty;

    try
    {
        process.StartInfo.FileName               = "file name (cmd in this case)";
        process.StartInfo.Arguments              = "parameters (with the \Q)";
        process.StartInfo.UseShellExecute        = false;
        process.StartInfo.RedirectStandardError  = true;
        process.StartInfo.RedirectStandardInput  = true;
        process.StartInfo.RedirectStandardOutput = true;

        process.Start();

        processOutput = process.StandardOutput.ReadToEnd();

        process.WaitForExit();
    }
    catch (Exception ex)
    {
        Logger.LogException(ex);
    }

The catch block doesn't get hit. The service just hangs until I manually stop and start it.

Is it possible to handle this scenario so that the service doesn't hang? I'm not even sure what to try.

One approach would be to add the /Q if it's not found:

process.StartInfo.Arguments = arguments.AddQuietSwitch();

Extension Method:

private static Dictionary<string, string> _quietSwitchMap =
    new Dictionary<string, string> { { "rmdir", "/Q" }, { "xcopy", "/y" } };

public static string AddQuietSwitch(this string input)
{
    var trimmedInput = input.Trim();
    var cmd = trimmedInput.Substring(0, trimmedInput.IndexOf(" "));

    string switch;
    if (!_quietSwitchMap.TryGetValue(cmd, out switch)) { return input; }
    if (trimmedInput.IndexOf(switch, 0,
        StringComparison.InvariantCultureIgnoreCase) > 0 { return input; }

    return input += string.Format(" {0}", _quietSwitchMap[cmd]);
}

You could append

echo y | rmdir ...

to the command when /Q is not provided.

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