0

Is there a way for a Console app know whether it has been called from a batch file as opposed to directly at the command prompt?

The reason for asking is to find a way to decide whether to initiate a Console.ReadLine loop or similar to await further input, or whether to exit immediately.

Alternatively, is there a way for a batch file to continue sending input to a Console App that is awaiting further input via ReadLine?

Yes, I know - that's 2 questions. If anyone comments that there's an answer to the second question I'll ask that separately.

rohancragg
  • 5,030
  • 5
  • 36
  • 47

4 Answers4

5

Why not pass in a commandline argument to the console app to determine whether to quit immediately or wait.

Geoff Appleford
  • 18,538
  • 4
  • 62
  • 85
1

The batch file can set an environment variable and you can check that in your console application:

in the batch file:

set waitOnDone=0
yourExeFile -arguments

in your Console Application:

var env = System.Environment.GetEnvironmentVariable("waitOnDone");
if (String.IsNullOrEmpty(env) ||  env != "0")
{
    // do something
}
fardjad
  • 20,031
  • 6
  • 53
  • 68
1

Possibly your problem is to read only from stdin if there is a redirecton (from your batch file).

This can also be solved (with dotnet) by detecting if there is an input stream.

Solution from @Hans Passant, SO: how to detect if console in stdin has been redirected

using System.Runtime.InteropServices;

public static class ConsoleEx
{
    public static bool OutputRedirected
    {
        get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stdout)); }
    }
    public static bool InputRedirected
    {
        get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stdin)); }
    }
    public static bool ErrorRedirected
    {
        get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stderr)); }
    }

    // P/Invoke:
    private enum FileType { Unknown, Disk, Char, Pipe };
    private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 };
    [DllImport("kernel32.dll")]
    private static extern FileType GetFileType(IntPtr hdl);
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetStdHandle(StdHandle std);
}

And it can be used like this

if (ConsoleEx.InputRedirected)
{
  string strStdin = Console.In.ReadToEnd();
}
Community
  • 1
  • 1
jeb
  • 78,592
  • 17
  • 171
  • 225
  • 2
    Attribution is required at SO, you can't just copy an answer without providing a link to the author's profile and a link to the answer. – Hans Passant Oct 19 '11 at 10:04
  • I tried this but I can't seem to produce a scenario where ConsoleEx.InputRedirected is ever True? Batch file contains MyApp.exe -arg test – rohancragg Oct 19 '11 at 10:14
  • @Hans Passant: You are right, but I copied this from my sources, I can't find the original SO link anymore – jeb Oct 19 '11 at 10:18
  • @Hans: Ok I found it, it's yours :-) – jeb Oct 19 '11 at 10:22
  • Two second search: http://stackoverflow.com/questions/3453220/how-to-detect-if-console-in-stdin-has-been-redirected/3453272#3453272 – Hans Passant Oct 19 '11 at 10:22
1

If the batch file knows the input then save the input to a file and feed that to your program like

prog.exe <argument.txt

in the batch file. I think you need not change the source code for this.

ferosekhanj
  • 1,086
  • 6
  • 11