7

So the program I'm working on can be launched using command lines in CMD using the following code.

string[] commandLines = Environment.GetCommandLineArgs();

However I want to be able to return a message to the CMD window where the command lines came from after handling them. Any help would be appreciated.

Edit: I'm running the program as a Windows Application, not a console application.

WittyAdrian
  • 123
  • 8
  • Is there a reason writing to `stdout` is not sufficient? – IllusiveBrian Sep 10 '14 at 18:39
  • 2
    @Namfuak Question is related to c#. – ntl Sep 10 '14 at 18:39
  • @ntl OK, I mean that Jeffrey Wieder's answer seems too simple considering the question is receiving so many upvotes, so perhaps there is some complication that prevents the OP from using it. Sorry for poor terminology. – IllusiveBrian Sep 10 '14 at 18:42
  • Is the executable project's output type "Console Application" or "Windows Application"? – Weeble Sep 10 '14 at 18:46
  • My solution works if executing a console application. I had assumed that the poster was executing a console application from the cmd window. – Jeffrey Wieder Sep 10 '14 at 19:02
  • 2
    http://stackoverflow.com/questions/14199850/writing-output-to-the-console-from-a-c-sharp-winforms-application or http://stackoverflow.com/questions/4362111/how-do-i-show-a-console-output-window-in-a-forms-application – RenniePet Sep 10 '14 at 19:45

3 Answers3

4

I ended up solving the problem by using one of the answers RenniePet posted as a comment to my question. I'll list the solution down here for anyone trying to reproduce it.

[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern bool AttachConsole(int dwProcessId);

private const int ATTACH_PARENT_PROCESS = -1;

StreamWriter _stdOutWriter;

// this must be called early in the program
public void GUIConsoleWriter()
{
    // this needs to happen before attachconsole.
    // If the output is not redirected we still get a valid stream but it doesn't appear to write anywhere
    // I guess it probably does write somewhere, but nowhere I can find out about
    var stdout = Console.OpenStandardOutput();
    _stdOutWriter = new StreamWriter(stdout);
    _stdOutWriter.AutoFlush = true;

    AttachConsole(ATTACH_PARENT_PROCESS);
}

public void WriteLine(string line)
{
    GUIConsoleWriter();
    _stdOutWriter.WriteLine(line);
    Console.WriteLine(line);
}

After you've added this code to your program you can simply start returning lines by using, for example, the following.

WriteLine("\nExecuting commands.");
WittyAdrian
  • 123
  • 8
1

You can use the .NET SendKeys class to send keystrokes to an application you do not own. The target application must be active to be able to retrieve the keystrokes. Therefore before sending you have to activate your target application. You do so by getting a handle of the window and pinvoking into SetForegroundWindow with your handle.

Here is some example code to get you started:

    [DllImport("user32.dll", EntryPoint = "FindWindow")]
    private static extern IntPtr FindWindow(string lp1, string lp2);

    [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    private void button1_Click(object sender, EventArgs e)
    {
        IntPtr handle = FindWindow("ConsoleWindowClass", "Eingabeaufforderung");
        if (!handle.Equals(IntPtr.Zero))
        {
            if (SetForegroundWindow(handle))
            {
                // send 
                SendKeys.Send("Greetings from Postlagerkarte!");
                // send key "Enter"
                SendKeys.Send("{ENTER}");
            }
        }
    }
Postlagerkarte
  • 6,600
  • 5
  • 33
  • 52
  • Thanks for your answer. This does actually work, however it displays anything that you're doing as extra lines. So if you'd want to display a message that'd be "echo blabla" which would result in two lines. So technically this works, but I prefer to look for something more clean. – WittyAdrian Sep 11 '14 at 00:17
  • I don't understand what you mean. SendKeys does not send a carriage return. So as long as you don't send the {enter} command everything is put on one line. – Postlagerkarte Sep 11 '14 at 07:36
  • But at some point I will have to press enter, at which point it'll present me with an error because "Greetings from Postlagerkarte!" is not a valid command. Just as an example. I ended up using another solution which I've posted below. – WittyAdrian Sep 11 '14 at 22:06
  • You would have to use the echo command of the shell to avoid that. So you could send "echo hello && echo again" + {enter} and it would not be interpreted as a command. However If you never going to send a real command you are indeed better of with the AttachConsole api. – Postlagerkarte Sep 11 '14 at 22:40
  • It would though, because I've tried exactly that. That would result in what I mentioned in my initial comment, namely "echo Greetings from Postlagerkarte!" and then in the line below that "Greetings from Postlagerkarte!" i.e. you see it twice. Once as the command and one as the result of that command. But nevertheless, I solved it so it's okay. – WittyAdrian Sep 13 '14 at 02:37
0

You want to use the Console class to interface with it if running a console application.

Console.WriteLine("Text");

If you are running a windows form application read here.

Community
  • 1
  • 1
Jeffrey Wieder
  • 2,336
  • 1
  • 14
  • 12
  • I am running a windows form application, but the answer to the question you linked only makes me able to show a new window with my desired message in it. Not allowing me to display it in the existing CMD window. – WittyAdrian Sep 10 '14 at 20:22