Failing to read input from .net-core console application in vscode - c#

I've been trying to get dotnet new console example project (for vscode) to work in Ubuntu 17.10.
I can get the default program to run:
using System;
namespace dotnet_console
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello world!");
}
}
}
But when i change it to read input as well, it gets really wonky...
using System;
namespace dotnet_console
{
class Program
{
static void Main(string[] args)
{
Console.Write("Name: "); // 1
var name = Console.ReadLine(); // 2
Console.WriteLine("Hello {0}!", name); // 3
}
}
}
The program builds, but it won't print Name:. However if i put breakpoints on line 1, 2 & 3, i can see that the program runs through ALL of them, but nothing prints. That is until i stop the debugging. Then it prints
Name:
The program '[16322] dotnet-console.dll' has exited with code 0 (0x0).
What is happening here? I'm guessing its a vscode thing, because it works as expected when ran from the terminal using dotnet run.

The Documentation states the following:
By default, processes are launched with their console output
(stdout/stderr) going to the VS Code Debugger Console. This is useful
for executables that take their input from the network, files, etc.
But this does NOT work for applications that want to read from the
console (ex: Console.ReadLine). For these applications, use a setting
such as the following
I found a solution for the problem here.
And the following Quote from the linked Documentation also states that changing the console property from the launch.json to either "externalTerminal" or "integratedTerminal "is going to help.
When this is set to externalTerminal the target process will run in a
separate terminal.
When this is set to integratedTerminal the target process will run
inside VS Code's integrated terminal. Click the 'Terminal' tab in the
tab group beneath the editor to interact with your application.

Correct - 'internalConsole' is not meant for programs that want to take console input. Here is the official documentation: https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window

Related

C# Console-Application with no console but winforms

We have an application that is a WinForms-Application. It accepts startup parameters and can perform certain jobs with no UI by using the command line.
Now, we also want some console-output, like for example when using application.exe /help.
The Issue we are now facing is: How to bring both worlds together in a "nice" way:
When setting the Output Type to "Windows Application",all the UI stuff works fine, but Console.WriteLine() doesn't show results when used from cmd.
When setting the Output Type to "Console", generally both things work, BUT: The Application (when used in UI-Mode so to say) raises a console window, that stays open until the application terminates.
Is there a way to bypass the visibility of the console-window?
In the real world, I can find applications using one of three approaches - but I don't like either of them:
Leave the console window open when running in UI-Mode, who cares?
Use user32.dll to hide the window (it still flashes, tho)
Use Windows-Application as Output-Type and show Console-Output as "message boxes", when used from the command line.
I've figured out a solution, thx to #Luaan s comment:
I'm now using the Output Type Windows Application (so, no console window) - but simply registering the Console with the Applications "Parent" Console.
This now behaves as expected:
No console is shown during normal startup.
When used from within an existing console window (ps / cmd) the output is printed, because that consoles are then technically the parent-console of the application.
public class GUIConsoleWriter
{
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
private static extern bool AttachConsole(int dwProcessId);
private const int ATTACH_PARENT_PROCESS = -1;
public static void RegisterGUIConsoleWriter()
{
AttachConsole(ATTACH_PARENT_PROCESS);
}
}
And then, firstline in Main():
static void Main(String[] args)
{
GUIConsoleWriter.RegisterGUIConsoleWriter();
}
Now, using regular Console.WriteLine() works. Ofc. this is limited to writing output, but for the scope of my projects that is sufficent, as input has to be provided with arguments, no interactive console-options.
When another application needs to fetch output programmatically, you ofc. can't do myApp.exe /doSomething but need to do cmd /C myApp.exe /doSomething because the application itself doesn't own a console.
AND you have to manually take care to "exit" your application, after providing output, otherwhise the process won't return.

Only part of a program executing

I'm following this tutorial https://mva.microsoft.com/en-us/training-courses/c-fundamentals-for-absolute-beginners-16169?l=83b9cRQIC_9706218949
and I can't get the program working although I have copied the exact code as in the tutorial.
I have Ubuntu 16.04 so I'm using Visual Studio Code. And I have .NET SDK version 2.1.403.
Here's the code for my program:
using System;
namespace Decision
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Miina's Big Giveaway");
Console.Write("Choose a door: 1, 2 or 3 ");
string userValue = Console.ReadLine();
if (userValue == "1")
{
string message = "You won a new car!";
Console.WriteLine(message);
}
Console.ReadLine();
}
}
}
The problem is that the program isn't writing the line "Choose a door...". Only when I stop the execution of the program, the line "Choose a door ..." appears in the debug terminal.
And if I try typing "1" while the program is still running nothing happens although it should go through the commands in the if statement. I can't figure out where's the problem.
Update on the debugging
When I'm debugging a light bulb appears next to the Console.Write -line. I'm not sure what that means.
Picture of the debugging result
Update
The program is working correctly when I run it through the terminal. So I guess I have to use the terminal with the Visual Studio Code. But it would be nice to use debugger, so if anyone knows how I could get it to work, let me know.
I suspect that Console.Write isn't being flushed (stdout on Linux is unbuffered, and is only flushed on a line ending).
Try Console.Out.Flush() as a work-around. It's not pretty, though.

C# Console Application Crashing

On Visual Studio, the C# Console application keeps on terminating when I try to run a program. I tested this by just writing Hello World, shown here:
(screenshot of what I wrote)
When I run it, the command prompt window appears for a second, then immediately closes. Is there a way to fix this?
When a console application runs it executes the code and exits, console applications do not have a message loop to keep them alive, it is the same as creating a batch file and double clicking it, the command window will open and then close when execution finishes. If you want then console window to hang around afterwards then you need to use Console.ReadLine(); which will wait for user input before closing (i.e. pressing Enter).
You code (which should be in your question) simply outputs some text to the console and then exits.
Suggested reading Creating a Console Application
class Program
{
static void Main (string[] args)
{
Console.WriteLine("Hello World");
Console.ReadLine();
}
}
The application is not crashing, it runs and then exits. If you want read the output after it's done you can use Console.ReadLine();
using System;
namespace Hello_World
{
class Program
{
static void Main (string[] args)
{
Console.WriteLine("Hello World");
Console.ReadKey();
}
}
}
The issue is not crashing really but that all the instructions are executed then the program exits. If you desire to pause, you could insert the statement:
Console.ReadKey();
which will wait for you to type a key to exit.

why can't this c# program be piped to like the "more" command? (And what C functionality does/might 'more' or 'uniq' use to handle piped data?)

If I look at a command that takes stdin, be it the more command in windows, or the uniq command in linux, you can enter the command, hit ENTER, then enter a line and it echos it back
But you can also echo some text pipe it to the command and the command outputs that and exits. I'm trying to write a C# program that does that.. i'll get to that. But i'll further describe the behaviour i'm trying to produce in my program (And i'd like to know what C functionality those programs use or might use to get that behaviour, and to what extent it exists in C#)
For example
C:\abc>more<ENTER>
a<ENTER>
a
b<ENTER>
b
c<ENTER>
c
^C
and
C:\abc>echo a|more<ENTER>
a
C:\abc>
same thing with uniq
$ echo a|uniq
a
$ uniq
a
a
b
b
c
c
I am trying to get that behaviour in a C sharp program
C:\abc>type b.csc
using System;
public class Example
{
public static void Main()
{
Console.ReadLine();
}
}
C:\abc>
But of course that program you enter one line and hit ENTER and it's the end of the program
C:\abc>b.exe
asdf
C:\abc>
So I tried adjusting it
C:\abc>type b2.csc
using System;
public class Example
{
public static void Main()
{
string a;
while(true) {
a=Console.ReadLine();
System.Console.WriteLine(a);
}
}
}
C:\abc>
And it's ok for the behaviour when just running it and hitting ENTER without pipe
C:\Users\harvey>csc b2.csc
Microsoft (R) Visual C# Compiler version 4.0.30319.18408
for Microsoft (R) .NET Framework 4.5
Copyright (C) Microsoft Corporation. All rights reserved.
C:\abc>b2.exe<ENTER>
a<ENTER>
a
b<ENTER>
b
^C
C:\abc>
But if I do
C:\abc>echo a|b2.exe
Then it clears the whole screen
I would like it to do the same as what the more command does or the uniq command does when piping to it.
I'm wondering what kind of function those programs use.
What C functionality they use, and whether C# has an equivalent
Ideal answer would include C and C# code that produces that behaviour.
This code seems to do it. ReadLine() in a loop with testing for null to break it.
The System.Console.ReadLine() msdn documentation says that it returns "The next line of characters from the input stream, or null if no more lines are available." That is not very precise.. But msdn documentation gets more precise where it says specifically Ctrl-Z. (one might miss that since it writes it as Ctrl+Z). IF Ctrl-C is hit then the program terminates. So, it's only with Ctrl-Z where ReadLine() returns null.
https://msdn.microsoft.com/en-us/library/system.console.readline(v=vs.110).aspx
"If the Ctrl+Z character is pressed when the method is reading input from the console, the method returns null. This enables the user to prevent further keyboard input when the ReadLine method is called in a loop. "
All control characters are listed here https://www.cs.tut.fi/~jkorpela/chars/c0.html
public class asdf
{
public static void Main()
{
string a;
while(true) {
a=System.Console.ReadLine();
System.Console.WriteLine(a);
if(a==null) break;
}
System.Console.WriteLine("blah");
}
}
output
C:\abc>echo a|b2.exe
a
C:\abc>

Open two console windows from C#

[DllImport("kernel32.dll")]
private static extern Int32 AllocConsole();
I can open cmd.exe with this command. But i can open only one console window and write in it. How can i open another one? Is any clean and fast solution for opening two console windows?
So you can do multiple console windows within one single C# windows app, but to do so you would have to have a few things. Process.start(), and command-line parameters.
If you do it this way you can have your app create another instance of itself, but with different command line parameters to have each part do different things.
Here is a simplistic example of how to do it.
namespace Proof_of_Concept_2
{
class Program
{
static void Main(string[] args)
{
if (args.Length!= 0)
{
if (args[0] == "1")
{
AlternatePathOfExecution();
}
//add other options here and below
}
else
{
NormalPathOfExectution();
}
}
private static void NormalPathOfExectution()
{
Console.WriteLine("Doing something here");
//need one of these for each additional console window
System.Diagnostics.Process.Start("Proof of Concept 2.exe", "1");
Console.ReadLine();
}
private static void AlternatePathOfExecution()
{
Console.WriteLine("Write something different on other Console");
Console.ReadLine();
}
}
}
Here is a screenshot of it working.
In conclusion,
Getting 2 console windows is easy, getting them to talk to each other is a separate question in and of itself. But I would suggest named pipes. Relevant Stackoverflow Post
You have to change your thinking because the 2 Consoles once run on different processes don't automatically talk to each other. Whatever calculation you are doing on one of them, the other one is completely unaware.
You can do
Process.Start("cmd.exe");
as many times as you would like. Is this what you mean?
Unfortunately not, sorry — you cannot have more than one console window per application in Windows.
Run the Console app (first window)
Got to bin > debug and open the YourApplication.exe file (second window)

Categories

Resources