Run C# code on linux terminal - c#

How can I execute a C# code on a linux terminal as a shell script.
I have this sample code:
public string Check(string _IPaddress,string _Port, int _SmsID)
{
ClassGlobal._client = new TcpClient(_IPaddress, Convert.ToInt32(_Port));
ClassGlobal.SMSID = _SmsID;
string _result = SendToCAS(_IPaddress, _Port, _SmsID );
if (_result != "") return (_result);
string _acoknoledgement = GetFromCAS();
return _acoknoledgement;
}
When I run a shell bash I use #!/bin/bash. There is how to do the same with C#?

Of course it can be done and the process is extremely simple.
Here I am explaining the steps for Ubuntu Linux.
Open terminal:
Ctrl + Alt + T
Type
gedit hello.cs
In the gedit window that opens paste the following example code:
using System;
class HelloWorld {
static void Main() {
Console.WriteLine("Hello World!");
}
}
Save and close gedit.
Back in terminal type:
sudo apt update
sudo apt install mono-complete
mcs -out:hello.exe hello.cs
mono hello.exe
Output:
Hello World!

NOTE: #adabru's answer below makes my solution obsolete unless you are using an older mono platform.
C# scripts can be run from the bash command line just like Python and Perl scripts, but it takes a small bit of bash magic to make it work. As Corey mentioned above, you must first install Mono on your machine. Then, save the following code in an executable bash script on your Linux machine:
if [ ! -f "$1" ]; then
dmcs_args=$1
shift
else
dmcs_args=""
fi
script=$1
shift
input_cs="$(mktemp)"
output_exe="$(mktemp)"
tail -n +2 $script > $input_cs
dmcs $dmcs_args $input_cs -out:${output_exe} && mono $output_exe $#
rm -f $input_cs $output_exe
Assuming you saved the above script as /usr/bin/csexec, an example C# "script" follows:
#!/usr/bin/csexec -r:System.Windows.Forms.dll -r:System.Drawing.dll
using System;
using System.Drawing;
using System.Windows.Forms;
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello Console");
Console.WriteLine("Arguments: " + string.Join(", ", args));
MessageBox.Show("Hello GUI");
}
}
Save the above code to a file such as "hello.cs", make it executable, change the first line to point to the previously saved bash script, and then execute it, you should see the following output along with a dialog saying "Hello GUI":
bash-4.2$ ./hello.cs foo bar baz
Hello Console
Arguments: foo, bar, baz
Note that the GUI requires that you be at run level 5. Here is a simpler C# script that runs at a pure text console:
#!/usr/bin/csexec
using System;
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello Console");
Console.WriteLine("Arguments: " + string.Join(", ", args));
}
}
Notice that the command line arguments are passed to the C# script, but the shebang arguments (in the first C# script above "-r:System.Windows.Forms.dll -r:System.Drawing.dll") are passed to the C# compiler. Using the latter functionality, you can specify any compiler arguments you require on the first line of your C# script.
If you are interested in the details of how the bash script works, shebang (#!) lumps together all arguments passed to it on the first line of the C# script, followed by the script name, followed by command line arguments passed to the script itself. In the first C# example above, the following 5 arguments would be passed into the bash script (delineated by quotes):
"-r:System.Windows.Forms.dll -r:System.Drawing.dll" "hello.cs" "foo" "bar" "baz"
The script determines that the first argument is not a filename and assumes it contains arguments for the C# compiler. It then strips off the first line of the C# script using 'tail' and saves the result to a temporary file (since the C# compiler does not read from stdin). Finally, the output of the compiler is saved to another temporary file and executed in mono with the original arguments passed to the script. The 'shift' operator is used to eliminate the compiler arguments and the script name, leaving behind only the script arguments.
Compilation errors will be dumped to the command line when the C# script is executed.

The #! (hashbang) tag is used to tell the shell which interpreter to use so that your perl, php, bash, sh, etc. scripts will run right.
But C# is not a scripting language, it is intended to be compiled into an executable format. You need to install at least a compiler and runtime if you want to use C#, and preferably an IDE (Integrated Development Environment) to help you develop and debug your applications.
Install Mono for the compiler and runtime, then MonoDevelop for the IDE.

After installing mono you can use csharp hello.cs. Starting with Mono 2.10, you can also use the shebang like this:
#!/usr/bin/csharp
Console.WriteLine ("Hello, World");
If you need assemblies, you can load them e.g. with the line LoadAssembly("System.IO.Compression") inside your script.
Reference: man csharp.

You can't execute C# like a script, you have to compile it first. For that, you could install mono.
You can then compile your program with mcs and execute it with mono.

First, you have to install mono
sudo apt install mono-complete
Commands to execute
mcs -out:$1.exe $1.cs
mono $1.exe
You can add these in a script to make the process easier. Create a shell sript and add the parent directory to the PATH environment variable.
Example:
export PATH=$PATH":$HOME/Desktop/customcommands"
And also give execute permission to the script file.
Shell script:
#!/bin/sh
dpkg -s mono-complete > /dev/null
if [ $? -eq 0 ]; then
echo
else
read -p "Package mono-complete not installed. Press y to install or n to quit." response
yes="y"
if [ "$response" = "y" ];
then
sudo apt install mono-complete
echo " "
echo " "
fi
fi
mcs -out:$1.exe $1.cs
mono $1.exe

Related

Get input from the user using ReadLine in c# code that runs as part of PowerShell script in PowerShell ISE

I need to prompting users for input in C# part of the code, but it doesn't work for me (gets empty input automagically) when run from PowerShell ISE. Code works as expected when run from just regular PowerShell command prompt (asks for the name)
$id = get-random
$code = #"
using System;
using System.Linq;
namespace Application
{
public class Program$id
{
public static void Main()
{
Console.WriteLine("Please enter your sweet name....");
String name = Console.ReadLine();
Console.WriteLine("Hello *"+name+" %" );
}
}
}
"#
Add-type -TypeDefinition $code -Language CSharp
iex "[Application.Program$id]::Main()"
When run in ISE the output is following (notice there is no chance to provide input):
PS C:\Users\Pavithra Kathirvel\Desktop> C:\Users\Pavithra Kathirvel\Desktop\demo.ps1
Please enter your sweet name....
Hello * %
As a beginner start with the basics in C# and powershell. If you are able to use one, it will be easier for you to learn the other. Also there are parts, which are in powershell faster than in c# and less code.
If you still want to execute your C# code in powershell, have a look at this link, it will run the script from a .cs file
Run a C# .cs file from a PowerShell Script
Also here is a really good tutorial for using c# in powershell:
https://blog.adamfurmanek.pl/2016/03/19/executing-c-code-using-powershell-script/

Is there a way to turn several csharp repl commands into a terminal alias?

Every day I make a GUID which I copy to my clipboard.
I do this by opening my terminal, writing csharp (see link below in case you are confused), writing GUID.NewGuid(), copying the output and writing quit.
Is there any way I can turn this whole procedure into a terminal alias?
Edit:
Just to clarify, I'm using this:
https://www.mono-project.com/docs/tools+libraries/tools/repl/
You can write and compile a console application, the question was geared towards whether you can inject statements directly into the command-line tool, not how to make a tiny executable.
There is an easy command from BSD to generate a UUID, it's available in macOS.
uuidgen
If you need to copy the UUID result to clipboard, use this:
uuidgen | pbcopy
So, what's the difference between UUID and GUID? Check out this thread.
Create a C# program
using System;
namespace guid
{
class MainClass
{
public static void Main(string[] args)
{
new MainClass().run();
}
private void run()
{
Console.WriteLine(Guid.NewGuid());
}
}
}
Compile to new-guid
Use in zsh like this
guid=$(./new-guid) #you may have to change the `.` to the appropriate path, depending on where the program is.
echo "${guid}"
Tested with zsh and mono-develop in Debian Gnu/Linux.
Note there are probably better ways to do this. One line purl script, or may be some Unix command.
Here's the answer I was looking for, in this case:
csharp -e 'Guid.NewGuid();' | pbcopy

How to cross compile mono for x86 android

I have tried many different ways. I completed a compile with the NDK and when I run it on an emulator with the adp shell, I get no output.
mono-3.10.0 from a tarball
Here are my environment variables:
export CC=i686-linux-android-gcc
export SYSROOT=/home/XXUSERNAMEXX/Develop/android-ndk-r10d/platform/android-17/arch-x86
export PATH=/tmp/my-android-toolchain/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Here is my configure:
./configure --disable-mcs-build --host=i686-linux-android --prefix=/home/XXUSERNAMEXX/vmshare/workspace/HelloJni/jni/mono-2.0 --target=i686-linux-android --build=i686-linux-gnu
then just
make
then
make install
Then build a C# sample of just:
// HelloAndroid.cs
// Outputs HelloAndroid.exe
using System;
namespace HelloAndroid
{
class MainClass
{
public static void Main (string[] args)
{
Console.WriteLine ("Hello World!");
}
}
}
then I copy
mono-sgen
libmonosgen-2.0.so
HelloAndroid.exe
to an android directory of
/data/data/com.example.helloandroid
change all the permissions to 755
change all the ownerships to system:system
then type
./mono-sgen HelloAndroid.exe
in the adp shell
then I just get nothing.
no errors, no output, just the command line returns
You need to compile the .NET Assemblies (System.dll ...) like for regular host and to put them into Android.
In addition define MONO_PATH to mono runtimes.

How to make program accept glob (wildcards) at command line?

I would like users to be able to run my program (from Windows cmd) with syntax like this
app.exe *.pdf
app.exe February/*.pdf March/*.pdf
app.exe contracts.pdf
The app would then do its business for each of the relevant files. In Unix this is called globbing and it's done by the shell.
How can I achieve this for a Windows C# command line app?
Hypothetical syntax
void Main(string[] args)
{
foreach(var file in args.SelectMany(arg => Glob.Expand(arg)))
{
Process(file)
}
}
take a look at NuGet package Microsoft.Extensions.FileSystemGlobbing
https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.filesystemglobbing.matcher
The easiest way to do this is to convert the command line parameter into a regular expression. See glob pattern matching in .NET for an example on how to convert the command line argument into a regular expression.

Compile C# code with code runner with Mono

I am trying to compile this simple C# code on OS X:
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("hello");
}
}
This was the code runner template.
I have installed Mono, and the run command is mono $compiler. I first tried using the default Compile.sh file, and it didn't work, so I've found on the web a guide that says to write a shell script like this one:
enc[4]="UTF8" # UTF-8
enc[10]="UTF16" # UTF-16
enc[5]="ISO8859-1" # ISO Latin 1
enc[9]="ISO8859-2" # ISO Latin 2
enc[30]="MacRoman" # Mac OS Roman
enc[12]="CP1252" # Windows Latin 1
enc[3]="EUCJIS" # Japanese (EUC)
enc[8]="SJIS" # Japanese (Shift JIS)
enc[1]="ASCII" # ASCII
file=$1
file=${file/\.cs/\.exe}
mcs "$1"
echo "$file"
exit 0
So I've changed it (backup-ed the old one), but I still get this error on the console:
bash: Run Command: No such file or directory
Unless you have a specific need to compile from the command line, I would strongly suggest using MonoDevelop instead of trying to figure out the appropriate command line parameters.

Categories