Bob Horn
Bob Horn

Reputation: 34297

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:

enter image description here

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.

Upvotes: 3

Views: 213

Answers (2)

Josh
Josh

Reputation: 11

You could append

echo y | rmdir ...

to the command when /Q is not provided.

Upvotes: 1

Mike Perrenoud
Mike Perrenoud

Reputation: 67898

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

Upvotes: 3

Related Questions