Suppose I have two files in my current working directory:
// file1.cs
Console.WriteLine("file1");
//file 2.cs
Console.WriteLine("file2");
In powershell, I do a dotnet new and delete the automatically generated Program.cs file. Then I do a dotnet build and get an error:
Only one compilation unit can have top level statements
I understand why this occurs, but I would like to be able to have full control of which .cs file is being targetted, while the other ones get ignored.
Is there any way to achieve this without having to create a whole new project for every file?
Doing this with .NET doesn't seem to be possible as of now. An issue on the dotnet/sdk GitHub has requested for this feature to be implemented.
However, you can use the C Sharp Compiler to compile a Windows executable and specify a .cs file with csc file1.cs
file1.cs:
using System;
Console.WriteLine("File 1");
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/top-level-statements
These files both use top-level statements. It implies that they both contain the Main method where program execution starts. You can only have one entry point. Generally, C# code is going to be contained within classes. Define a class in one (or both) files and put your methods within.
// Program.cs
public class Program
{
static void Main()
{
Console.WriteLine("Program.cs");
}
}
// Util.cs
public class Util
{
public static void Display()
{
Console.WriteLine("Util.cs");
}
}
I would like to create a library out of go-code and use it inside a C# winforms project.
For the error scroll to the bottom.
Setup
GO 1.10.2
tdm-gcc-5.1.0-3
Windows 10 / x64
Go-project called exprt
What I've tried
I've created a minimal go-tool that creates a file in the working-dir:
package main
import (
"os"
"C"
)
func main() {
// nothing here
}
//export Test
func Test() {
os.OpenFile("created_file.txt", os.O_RDONLY|os.O_CREATE, 0666);
}
The next steps were taken from Building a dll with Go 1.7.
I've then compiled to c-archive with the following command: go build -buildmode=c-archive which gives me exprt.a and exprt.h.
After that I've created a file called goDLL.c (1:1 as in the link above) and inserted this code:
#include <stdio.h>
#include "exprt.h"
// force gcc to link in go runtime (may be a better solution than this)
void dummy() {
Test();
}
int main() {
}
Lastly I've run this command to create my final dll:
gcc -shared -pthread -o goDLL.dll goDLL.c exprt.a -lWinMM -lntdll -lWS2_32
which gave me "goDLL.dll".
My problem
In C# I've created a winforms-project with 1 button that calls this declared function (copied the dll to the debug-folder):
[DllImport("goDLL.dll")]
private static extern void Test();
Error
System.BadImageFormatException: "An attempt was made to load a program with an incorrect format. (HRESULT: 0x8007000B)"
Sorry for that big block of text but this was the most minimal test I could think off.
I appreciate every help in here.
Well, in the given answer here https://social.msdn.microsoft.com/Forums/vstudio/en-US/ee3df896-1d33-451b-a8a3-716294b44b2b/socket-programming-on-64bit-machine?forum=vclanguage there is written:
The implementation is in a file called ws2_32.dll and there are 32-bit and 64-bit versions of the DLL in 64-bit Windows.
So the build as described in my question is correct.
Solution
The C#-Project has to be explicitly set to x64. AnyCPU won't work and throw the error shown in the question above.
Everything is working now. I'm leaving the question and answer as this is a full explanation of how to get go-code running out of C#.
If I feed Process.Start(); the parameters "Firefox", Notepad or "cmd" it runs those programs like their location is built in, but with other programs I have to specify the program's directory for it to work.
How does it automatically know where some programs located, and why only those programs and not others?
My code:
using System;
using System.Diagnostics;
namespace Testing
{
public class MainClass
{
static void Main()
{
Process.Start("Firefox"); // Works
Process.Start("Notepad"); // Works
Process.Start(#"C:\Users\user\Desktop\Steam"); // Works too
Process.Start("Steam"); // This line gives me "The System cannot find the file specified"(run-time error)
}
}
}
I think it depends on Environment variables in Windows.
or type PATH in cmd and observe paths, where *.exe files can be found automatically.
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
I downloaded the newest version of LuaInterface from their site, and referenced LuaInterface.dll and Lua51.dll. The interpreter itself works fine, but when I try to require("luainterface"), I get this exception :
error loading module 'luainterface' from file '.\luainterface.dll':
The specified procedure could not be found.
Here's the example code which produces this behavior :
static void Main(string[] args)
{
Lua lua = new Lua();
lua.DoFile("test.lua");
}
The test.lua script just has this :
luanet = require("luainterface");
Also, I've made sure that LUA_PATH points to where luanet.dll is.
What could be the problem?
For .dll's are looked for in LUA_CPATH in any case...
http://www.lua.org/manual/5.1/manual.html#pdf-package.cpath