c# How does Process.Start() method automatically know where files are located? - 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.

Related

How can I add a static 'Main' method suitable for an entry point?

I am getting an error on my code that says "Error CS5001
Program does not contain a static 'Main' method suitable for an entry point"
I am coding in C# using Microsoft Visual Studio and .NET. This is my code.
using System.IO;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using System;
class projectsummer
{
[CommandMethod("OpenDrawing", CommandFlags.Session)]
public static void OpenDrawing()
{
string strFileName = "C:\\DRAFT.dwg";
DocumentCollection acDocMgr = Application.DocumentManager;
if (File.Exists(strFileName))
{
acDocMgr.Open(strFileName, false);
}
else
{
acDocMgr.MdiActiveDocument.Editor.WriteMessage("File " + strFileName +
" does not exist.");
}
}
}
I am not sure how to go about this error. Thank you!
Looking at this post and your previous question, let's try and break down what's going on.
You created a new Console application in Visual Studio. You did not tick "Do not use top level statements". This gave you a Program.cs file that was essentially empty (there was no "Main" method visible).
You erased the Hello World code given to you, and went to make a static method - the code from your previous question.
Damien_The_Unbeliever commented that based on the error, you put your method inside a "top level statement" file, and to put your method inside a class.
You wrap your method (which is still inside Program.cs) in a class, and now suddenly you get a Can't Find Entry Point error.
User Ryan Pattillo posted a great explanation of the original issue - where your method was "by itself" in the Program.cs file. You should follow their advice, but you should also ensure that this class is in its own file.
You should end up with this:
Program.cs
// this is the entire contents of the file
using ConsoleApp1;
ProjectSummer.OpenDrawing();
ProjectSummer.cs
using System.IO;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using System;
namespace ConsoleApp1
{
public class ProjectSummer
{
[CommandMethod("OpenDrawing", CommandFlags.Session)]
public static void OpenDrawing()
{
// ...
}
}
}
Change ConsoleApp1 to the name of your project.
The entry point of your application, which right now is the only file that has "top level statements", remains Program.cs, thus you fix the Can't Find Entry Point error.
Another adjustment you can make, which seeing you're new to C# might be useful, is to not use top level statements at all. Modify your Program.cs to this:
namespace ConsoleApp1
{
internal static class Program
{
// this is your program's entry point
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
ProjectSummer.OpenDrawing();
}
}
}
Change ConsoleApp1 to the name of your project.
You cannot use the AutoCAD .NET API out of process. To be able to use the AutoCAD .NET libraries, you have to build a "class library" project (DLL) and NETLOAD this DLL from a running AutoCAD process. See this topic about in-process vs out-of-process and you can start from this other one to see how to create an AutoCAD .NET project.

Specifying cs file to build with dotnet CLI

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");
}
}

C# DirectoryNotFoundException was unhandled in Windows 10 machine

C# application.exe not working in Win10,but it worked on my Win7. I tried to debug in Win10 it shows me this error which is correct in win7.
using System;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
string fullComputerName = Environment.MachineName;
//Create a Folder Path
string createFolderPath = #"C:\\Users\\" +fullComputerName+"\\Documents\\Cheques";
//Create a File Inside of a Folder
string createTxtFile= createFolderPath + "\\ChequeForDeposit.TXT";
try
{
if(!Directory.Exists(createFolderPath))
{ return; }
Directory.CreateDirectory(createFolderPath);
}
catch { }
finally { }
if(!File.Exists(createTxtFile))
{ File.Create(createTxtFile); }//The error is here
}
}
}
when i check in my win7 pc, it creates a folder and a text file. But not in Win10. it is so strange.
Your try/catch does not ensure that directory folder will exist (may generate an exception when you try to create the folder). So before creating the file, check immediately folder is exists.
Your condition is incorrect. If folder not exists then you should return, otherwise create.
try
{
if(Directory.Exists(createFolderPath) && !File.Exists(createTxtFile))
{
File.Create(createTxtFile);
}
}
Also check the permission issue. e.g. Check the permissions for the desktop folder. In Windows Explorer right click on the desktop folder, select properties and there go to the security tab. You should have write permission for that folder.
i think the folder C:\Users\ is Protected system folder by design. either you have to run as Administrator or create the file in some other drive, for eg:
#"D:\Users\" +fullComputerName+"\Documents\Cheques"

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.

Starting an .exe from the same folder of my C# program

I made a small program in c# with a button that is supposed to open another .exe file.
It works fine if I use:
private void start_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start(#"path to file");
}
But not if I want it to run an .exe from the same folder, i basically wanted something like:
private void start_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start(#"program.exe");
}
What am I missing, I've tried a solution from this website:
var startIngo = new ProcessStartInfo();
startIngo.WorkingDirectory = // working directory
// set additional properties
Process proc = Process.Start(startIngo);
But Visual c# doesn't recognize "ProcessStartInfo" at all...
What your looking for is:
Application.StartupPath
It will return the startup path that your executable was started in.
If you are using WPF, try this instead:
String appStartPath = System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
You can do:
var startupPath = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetEntryAssembly().Location);
var programPath = System.IO.Path.Combine(startupPath, "program.exe");
System.Diagnostics.Process.Start(programPath);
ProcessStartInfo is in the System.Diagnostics namespace - you need to import that namespace at the top of your cs file using a using System.Diagnostics; statement for the compiler to recognise ProcessStartInfo without specifying the namespace explicitly where you use the class.
You could also try System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
To get your local path. For example
//in your imports/using section
using System.IO
using System.Reflection
using System.Diagnostics;
//in your code to execute
Process.start(Path.GetDirectoryName(Aseembly.GetExecutingAssembly().GetName().CodeBase) + "\\program.exe")
There are two cases:
The application was started directly - start up path can be extracted from the command-line.
The application was started indirectly - e.g. from a unit-test, start up path can not be extracted from the command-line, however you can read it from the current directory into a static variable during the start-up (before the user has a chance to change it (e.g. using a file open/save dialog)).

Categories