Run .NET in vscode - c#

When I click on ctrl + alt + n in vscode to run the C# code, the encoding constantly flies and the output gives me this
[Running] scriptcs "d:\Code\main.cs"
"scriptcs" �� ���� ����७��� ��� ���譥�
��������, �ᯮ��塞�� �ணࠬ��� ��� ������ 䠩���.
[Done] exited with code=1 in 0.382 seconds
the code itself is the usual "hello world"
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
}
}
Before that, I downloaded the Run code and C# extensions from Microsoft

After Console.WriteLine("Hello World")
just add Console.ReadKey()

Related

Node JS run a c# program

I have written a simple program in C# that saves to a text file every 5 seconds. I have also made a program in electron using node.js, is there a way I can start the C# program through electron?
I have tried compiling the C# program as an exe and running it that way but I couldn't get it to work.
Any help will be greatly appreciated!
Answer
The problem was that my C# file needed to be run as an administrator, I used the function below;
var exec = require('child_process').execFile;
var fun =function(){
console.log("fun() start");
exec('HelloJithin.exe', function(err, data) {
console.log(err)
console.log(data.toString());
});
}
fun();
You could just run a command with nodejs that starts the c# program.
const { exec } = require("child_process");
exec("cmd /K 'C:\SomeFolder\MyApp.exe'", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
DISCLAIMER: i haven't tested it because i am not on windows right now
source:
superuser
stackabuse

Unable to display an input from a user using Console.ReadLine()

I am new to C# and the .NET Code / VSCcode.
Currently using VSCode to run and build C# codes.
I am unable to take user input using Console.ReadLine() after declaring a particular variable to hold it. The terminal generates this error code at the end of the program:
The program '[4544] forth.dll' has exited with code 0 (0x0).
using System;
namespace forth
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.WriteLine("This is the first program we are trying to build");
var name = Console.ReadLine();
Console.WriteLine("Hello " + name, "you successfully entered a name");
Console.WriteLine("Hello " + name, "you successfully entered a name");
Console.WriteLine("you can press enter to exit the program");
Console.ReadLine();
}
}
}
Output "please enter your name" and displays "Hello + the user's name"
The program should exist afterwards
Try moving the comma after name to inside the string, and appending the second string to the first:
Console.WriteLine("Hello " + name + ", you successfully entered a name");
At the moment you will be using the WriteLine(string, string) overload, when I think you just want WriteLine(string)
When you created your project you picked the wrong type. You need to pick "New Console Application".
Right now you are building a library and a library does not have a Main method. Well, it can have, but it's not called. So create a new project, pick the correct type and copy your code over.

Output from xUnit tests run with Visual Studio test runner not shown in Output window

I created a fresh .NET Core Class Library project named FooBarBaz. I've then used the package manager console to run:
Install-Package xunit xunit
Install-Package xunit xunit.runners.visualstudio
This is the only code I have added:
using Xunit;
using Xunit.Abstractions;
namespace FooBarBaz
{
public class Class1
{
private readonly ITestOutputHelper output;
public Class1(ITestOutputHelper output)
{
this.output = output;
output.WriteLine("OUTPUT FROM MY CONSTRUCTOR");
}
[Fact]
public void SmokeTest()
{
output.WriteLine("OUTPUT FROM MY TEST");
Assert.True(true);
}
}
}
This is based straight on the xUnit.net documentation example. I know that the documentation goes on to talk about "Message Sinks" and whatnot, but I could've sworn I saw the message in the Output window of visual studio. In my real project this seems to work only erratically.
I know I can click the "Output" hyperlink after selecting a test and see it, but that's just one step extra, and that output doesn't have a monospace font either (which I'd like to have).
See this:
How do I configure xUnit to provide output in the Output window?
After typing the question and fiddling around some more, the completely obscure solution popped up: only tests that fail show ITestOutputHelper output in the Output window.
Try changing the assertion to Assert.True(false); and you'll get this:
Not sure why that's the default, or how you'd change it.
What Jeroen wrote regarding ITestOutputHelper is correct, so you can't use it for "live" messages. But I have a workaround for you:
If you're debugging anyway and activated "Debug" mode, nothing stops you from doing something like
loopCount++;
System.Diagnostics.Debug.WriteLine($"Processing Entries ({loopCount} of {loopMax}) ...");
This will show up in the "Debug" window (i.e. in the Output window there is a dropdown where you need to select "Show output from Debug"). It appears immediately, ideal for long running loops etc.
Don't worry, those messages show up only in "Debug" configuration. To disable them, select "Release", and they won't appear any more - so it is easy to turn them on or off.
You can also write a helper function like:
private void Print(string msg, string test = "")
{
Debug.WriteLine($"{nameof(NameOfTestClass)}{test}: {msg}");
output?.WriteLine(msg);
}
Which will write into debug console in real time, but at the same time write into the test runner's output space.
You can use it in your Facts and Theories like
Print("Something happened");
or
Print("Something happened", "-Test1");
And a complete test class would look like:
using LiveOut = System.Diagnostics.Debug;
// using LiveOut = System.Console;
public class Test_Class
{
ITestOutputHelper Output;
public Test_Class(ITestOutputHelper _output)
{
Output = _output;
}
private void Print(string msg, string test = "")
{
LiveOut.WriteLine($"{nameof(Test_Class)}{test}: {msg}");
Output?.WriteLine(msg);
}
[Fact]
void Test_Xunit()
{
void _print(string msg) => Print(msg, $"-{nameof(Test_Xunit)}");
for (int i = 1; i < 100; i++)
{
_print(i.ToString());
Assert.True(i > 0);
Thread.Sleep(20);
}
}
}
In this case, you can choose between two using commands:
using LiveOut = System.Diagnostics.Debug;
or
using LiveOut = System.Console;
Depending on your needs you will have the output either on the debug window or on the console window.

How can I access PowerShell standard error output in C#?

I know that Invoke-MyCmd throws an error and writes a message to standard error.
Let's say it's one line that invokes a Java program like this:
function Invoke-MyCmd
{
java Error
}
Error.java just prints an error message and exits:
import java.io.*;
public class Error {
public static void main(String[] args) {
System.err.println("Hello, error!");
}
}
I'm invoking Invoke-MyCmd from C# like so:
PowerShell ps = PowerShell.Create();
.
.
.
ps.AddCommand("Invoke-MyCmd");
Collection<PSObject> output = ps.Invoke();
The error text, I'm assuming because it comes from Java and not directly from Invoke-MyCmd, doesn't show up in ps.Streams.Error. I'm wondering if there's another way to read that error output from C#.
I'm blatantly copy/pasting this answer using this blog as a reference
Since this is a native executable being run by powershell, you need to translate the error code into an exception like so:
'Starting script...' | Write-Verbose
$ErrorActionPreference = 'Stop'
java Thing
if ($LastExitCode -ne 0) {
throw 'An error has occurred...'
}
'Finished script' | Write-Verbose
Your java application should also return non-zero when an error occurs.
import java.io.*;
public class Error {
public static void main(String[] args) {
System.err.println("Hello, error!");
return 1;
}
}

How to capture a Powershell CmdLet's verbose output when the CmdLet is programmatically Invoked from C#

BACKGROUND
I am using Powershell 2.0 on Windows 7.
I am writing a cmdlet in a Powershell module ("module" is new to Powershell 2.0).
To test the cmdlet I am writing Unit tests in Visual Studio 2008 that programmatically invoke the cmdlet.
REFERENCE
This Article on MSDN called "How to Invoke a Cmdlet from Within a Cmdlet" shows how to call a cmdlet from C#.
THE SOURCE CODE
This is a distilled version of my actual code — I've made it as small as possible so that you can see the problem I am having clearly:
using System;
using System.Management.Automation;
namespace DemoCmdLet1
{
class Program
{
static void Main(string[] args)
{
var cmd = new GetColorsCommand();
foreach ( var i in cmd.Invoke<string>())
{
Console.WriteLine("- " + i );
}
}
}
[Cmdlet("Get", "Colors")]
public class GetColorsCommand : Cmdlet
{
protected override void ProcessRecord()
{
this.WriteObject("Hello");
this.WriteVerbose("World");
}
}
}
COMMENTS
I understand how to enable and capture verbose output from the Powershell command line; that's not the problem.
In this case I am programmatically invoking the cmdlet from C#.
Nothing I've found addresses my specific scenario. Some articles suggest I should implement my own PSHost, but seems expensive and also it seems like a have to call the cmdlet as text, which I would like to avoid because that is not as strongly typed.
UPDATE ON 2009-07-20
Here is is the source code based on the answer below.
Some things are still not clear to me:
* How to call the "Get-Colors" cmdlet (ideally without having to pass it as a string to the ps objet)
* How to get the verbose output as it is generated instead of getting an collection of them at the end.
using System;
using System.Management.Automation;
namespace DemoCmdLet1
{
class Program
{
static void Main(string[] args)
{
var ps = System.Management.Automation.PowerShell.Create();
ps.Commands.AddScript("$verbosepreference='continue'; write-verbose 42");
foreach ( var i in ps.Invoke<string>())
{
Console.WriteLine("normal output: {0}" , i );
}
foreach (var i in ps.Streams.Verbose)
{
Console.WriteLine("verbose output: {0}" , i);
}
}
}
[Cmdlet("Get", "Colors")]
public class GetColorsCommand : Cmdlet
{
protected override void ProcessRecord()
{
this.WriteObject("Red");
this.WriteVerbose("r");
this.WriteObject("Green");
this.WriteVerbose("g");
this.WriteObject("Blue");
this.WriteVerbose("b");
}
}
}
The code above generates this output:
d:\DemoCmdLet1\DemoCmdLet1>bin\Debug\DemoCmdLet1.exe
verbose output: 42
UPDATE ON 2010-01-16
by using the Powershell class (found in System.Management.Automation but only in the version of the assembly that comes with the powershell 2.0 SDK, not what comes out-of-the-box on Windows 7) I can programmatically call the cmdlet and get the verbose output. The remaining part is to actually add a custom cmdlet to that powershell instance - because that was my original goal - to unit test my cmdlets not those that come with powershell.
class Program
{
static void Main(string[] args)
{
var ps = System.Management.Automation.PowerShell.Create();
ps.AddCommand("Get-Process");
ps.AddParameter("Verbose");
ps.Streams.Verbose.DataAdded += Verbose_DataAdded;
foreach (PSObject result in ps.Invoke())
{
Console.WriteLine(
"output: {0,-24}{1}",
result.Members["ProcessName"].Value,
result.Members["Id"].Value);
}
Console.ReadKey();
}
static void Verbose_DataAdded(object sender, DataAddedEventArgs e)
{
Console.WriteLine( "verbose output: {0}", e.Index);
}
}
[Cmdlet("Get", "Colors")]
public class GetColorsCommand : Cmdlet
{
protected override void ProcessRecord()
{
this.WriteObject("Hello");
this.WriteVerbose("World");
}
}
Verbose output is not actually output unless $VerbosePreference is set at least to "Continue."
Use the PowerShell type to run your cmdlet, and read VerboseRecord instances from the Streams.Verbose propery
Example in powershell script:
ps> $ps = [powershell]::create()
ps> $ps.Commands.AddScript("`$verbosepreference='continue'; write-verbose 42")
ps> $ps.invoke()
ps> $ps.streams.verbose
Message InvocationInfo PipelineIterationInfo
------- -------------- ---------------------
42 System.Management.Automation.Invocat... {0, 0}
This should be easy to translate into C#.
1. string scriptFile = "Test.ps1";
2. using (PowerShell ps = PowerShell.Create())
3. {
4. const string getverbose = "$verbosepreference='continue'";
5. ps.AddScript(string.Format(getverbose));
6. ps.Invoke();
7. ps.Commands.Clear();
8. ps.AddScript(#".\" + scriptFile);
9. ps.Invoke();
10. foreach (var v in ps.Streams.Verbose)
11. {
12. Console.WriteLine(v.Message);
13. }
14. }
Important lines are line 5 and 6. This basically set the $verbosepreference for the session and for upcoming new commands and scripts.
First off, if you are unit testing cmdlets, likely Pester is a better (and easier) option.
As per your many updates, all you are likely missing at this point is a strongly typed approach to reference the C# cmdlet
ps.AddCommand(new CmdletInfo("Get-MyCS", typeof(GetMyCS)));
DISCLAIMER: I know this works for PowerShell 5.0, but don't have experience with the older PowerShell 2.0.

Categories

Resources