I'm newbie in c# and I'm stuck on this conundrum
I've recently made a Gui Program in c# that include several tabs and some other stuff
Now I want to make one of the tabs as a exe file that i would be able to run via cmd .
the entire code i want to put in file is comprised of one class
something like that
class E2p
{
main program( take 2 arg )
{some Code
make a CSV file in appDirectory
}
I want to turn it to EXE file so I can run it from CMD like that
E2pChck.exe -i 10.0.0.127 -r RandomWord
How can I do it ??
I'm not 100% sure what you're after, but I think you mean that you want to be able to run your exe from the command line with a couple of arguments.
These arguments are passed into your application in the Main method, which you'll find in Program.cs. In a command line application the arguments parameter is provided for you, but you can add it to a Windows Forms application.
class Program
{
static void Main(string[] args)
{
string firstArgument;
string secondArgument;
const int NumberOfArgumentsRequired = 2;
// you can access the arguments using the args array,
// but we need to make sure we have enough arguments,
// otherwise we'll get an index out of range exception
// (as we're trying to access items in an array that aren't there)
if (args.Length >= NumberOfArgumentsRequired)
{
firstArgument = args[0];
secondArgument = args[1];
}
else
{
// this block will be called if there weren't enough arguments
// it's useful for setting defaults, although that could also be done
// at the point where the strings were declared
firstArgument = "This value was set because there weren't enough arguments.";
secondArgument = "So was this one. You could do this at the point of declaration instead, if you wish.";
}
string outputString = string.Format("This is the first: {0}\r\nAnd this is the second: {1}", firstArgument, secondArgument);
Console.WriteLine(outputString);
Console.ReadKey();
}
}
If you typed E2pChck.exe -i 10.0.0.127 -r RandomWord into the command line then:
args[0] would be "-i"
args[1] would be "10.0.0.127"
args[2] would be "-r"
args[3] would be "RandomWord"
I know this doesn't technically answer the question, but the OP asked for an example of starting a process.
You would put this code in your button handler (probably on a separate thread so your UI doesn't hang)
System.Diagnostics.ProcessStartInfo csvGenerationProcInfo = new System.Diagnostics.ProcessStartInfo();
csvGenerationProcInfo.Arguments = "-i 10.0.0.127 -r RandomWord";
csvGenerationProcInfo.FileName = "E2pChck.exe";
System.Diagnostics.Process csvGenerationProc = System.Diagnostics.Process.Start(csvGenerationProcInfo);
csvGenerationProc.WaitForExit();
Or, if you don't need all the features of ProcessStartInfo you can just use:
System.Diagnostics.Process.Start("E2pChck.exe", "-i 10.0.0.127 -r RandomWord");
Hope that helps!
Related
I need to create a console application that can take multiple different launch arguments (which can be added using the batch file). I so far tried this, but it seems like I don't understand it correctly.
Code:
static void Main(string[] args)
{
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.Arguments = LaunchArguments.Operation_AddLocale;
processStartInfo.Arguments = LaunchArguments.Operation_CreateTextFile;
processStartInfo.UseShellExecute = false;
if (processStartInfo.Arguments == LaunchArguments.Operation_CreateTextFile)
{
Console.WriteLine("Creating a text file.");
File.Create("file.txt");
Console.Write("Done!");
}
if (processStartInfo.Arguments == LaunchArguments.Operation_AddLocale)
{
if (Directory.Exists("locale"))
{
try
{
File.Create("locale.txt");
}
catch (Exception ex)
{
Console.WriteLine("An error occured: ");
Console.Write(ex.ToString());
Console.Write(ex.Message.ToString());
Console.ReadLine();
}
}
else
{
Console.WriteLine("Incorrect Input, quitting");
Console.WriteLine("This application only accepts arguments of type '-CreateTextFile; -AddLocale'");
Console.Beep();
Console.ReadLine();
}
}
I made a constant string 'Operation_AddLocale' and 'Operation_CreateTextFile'.
by batch file:
#echo off
start SW_project_generator.exe -AddLocale
This all should do that if I launch the application via this batch file, it will do the operations that are in the 'if (processStartInfo.Arguments == LaunchArguments.Operation_AddLocale)' and if the batch file would add the '-CreateTextFile' argument, it will go to the 'if (processStartInfo.Arguments == LaunchArguments.Operation_CreateTextFile)'.
However, when I launch this app via my batch file, it will always just use the first argument (which is the '-CreateTextFile') and creates a text file and then goes to the else option.
Application's Output:
Creating a text file.
Done!Incorrect Input, quitting
This application only accepts arguments of type '-CreateTextFile; -AddLocale;'
Alright so, my question is, how to make this working, that if I create a batch file give it a argument of type '-AddLocale' it will just go to the 'AddLocale' operations and if I give it something else that is defined in the app, like the 'CreateTextFile', it'll go to it's 'if' statement. And finnaly, if the launch argument will be equal to nothing or wrong one, it'll show the quitting message.
Thanks everyone for help.
I have a c# method that sets the brightness of all monitors using a third-party executable.I call it using the method below. The problem is that I need to call this executable with different parameters to change the brightness. But my code creates a new process each time I call SetBrightness. How does one use an exiting process that is already running, and pass different parameters to execute it again? I don't see any method inthe Process class that makes this easy.
Edit: When I run this exe using the command line, the process stays open in the Windows System Tray, and I see the process is running in Task Manager. When I run my code, however, I sometimes see two instances of the exe in Task Manager. So I guess what I'm trying to do is always call the same instance but with different parameters. Restarting the exe every time is not an option because it takes too long to start up each time.
public bool SetBrightness(short monitorStartIndex, short monitorEndIndex, short brightness)
{
// Construct the parameter string used by the tool so that it updates all monitors in one call.
// Example "1 b75 2 b75" will set brightness to 75 for monitors 1 and 2.
StringBuilder arguments = new StringBuilder();
for (int i = monitorStartIndex; i <= monitorEndIndex; i++)
{
arguments.Append(i).Append(" ");
arguments.Append(string.Format("b{0}", brightness)).Append(" ");
}
var path = Path.GetDirectoryName(Environment.GetCommandLineArgs()[1]);
var final = Path.Combine(path, "External Assemblies\\ClickMonitorDDC_3_9.exe");
var p = new Process
{
StartInfo =
{
FileName = final,
Arguments = arguments.ToString(),
UseShellExecute = false,
RedirectStandardOutput = true
}
};
try
{
p.Start();
}
catch (Exception e)
{
Trace.TraceError("Error while changing the brightness using ClickMonitorDDC_3_9.exe. Inner Exception : " + e.Message);
return false;
}
return true;
}
You will want to use the WaitForExit method available in the Process class. If you attempt to use the third-party executable from the command line using the same type of parameters as you have in your code, it should return to the prompt as it is setting the parameters and exiting. You would just call your method whenever you want to change the brightness and wait until it's set and exit out.
Change your code as seen below:
try
{
p.Start();
p.WaitForExit()
}
I would like to have commands within the executable itself for example:
shorten http://stackoverflow.com/
and the url will be parsed as an argument, if I set it to return the argument, it should return me http://stackoverflow.com/
Another example is
foo bar
and it will check what is the main command which is foo and subcommands under it, which is bar and will execute the command.
This should be done within the executable and not calling the executable in the directory. I would like to have multiple custom commands within the executable and not create one for each command.
I understand how to have arguments if each command was an executable, but I would like a few commands and subcommands within 1 executable. Is this possible?
EDIT:
This is what I want:
static void Main(string[] args)
{
for (int i = 0; i < args.Length; i++)
{
if (args[i] == "short")
{
Console.WriteLine(args[i + 1]);
}
}
Console.Read();
}
which will return me the arguments of short. So if I type short link it will return me link.
However this will only work if I call the executable through the command line like C:\Path\ConsoleApplication1.exe not if I open up the application and type short link, which will not return me anything and close.
How do I make it work when I open up the application and type it in?
You can use Console.ReadLine:
var input = Console.ReadLine();
To get command and argument(s) use String.Split :
var command = input.Split()[0];
var argument1 = input.Split()[1];
etc.
Currently I'm porting a c++ exe launch to c#. I'm able to read through and understand the c++ code, but I'm struggling to find the c# equivalent. I believe that the original code launches the exe by utilizing the command prompt.
I think it would be best to display the code that I am porting, so here it is:
// This is basically running an exe to compile a file that I create
short rtncod;
int GPDataAge = FileAge(SelectedPath + GPDATA); //Checks age of GPDATA if it exists
STARTUPINFO si; // Startup information structure
PROCESS_INFORMATION pi; // Process information structure
memset(&si, 0, sizeof(STARTUPINFO)); // Initializes STARTUPINFO to 0
si.cb = sizeof(STARTUPINFO); // Set the size of STARTUPINFO struct
AnsiString CmdLine = Config->ReadString("Configuration","CRTVSM","CRTVSM.EXE . -a"); // Windows version requires path
rtncod = (short)CreateProcess(
NULL, // pointer to name of executable module
CmdLine.c_str(), // pointer to command line string
NULL, // pointer to process security attributes
NULL, // pointer to thread security attributes
FALSE, // handle inheritance flag
CREATE_NEW_CONSOLE, // creation flags
NULL, // pointer to new environment block
NULL, // pointer to current directory name
&si, // pointer to STARTUPINFO
&pi); // pointer to PROCESS_INFORMATION
if (!rtncod) /*If rtncod was returned successful**/ {
int LastError = GetLastError();
if (LastError == 87 /* Lookup 87 error **/ && AnsiString(SelectedPath + GPDATA).Length() > 99)
ShowMessage("CRTASM could not run due to extremely long path name. Please map or move the folder to shorten the path");
else
ShowMessage("Could not compile VSMInfo.dat =>" + IntToStr(LastError));
}
else /* If successful **/ {
unsigned long ExitCode;
// CartTools will 'lock up' while waiting for CRTASM
do {
rtncod = GetExitCodeProcess(pi.hProcess,&ExitCode);
} while (rtncod && ExitCode == STILL_ACTIVE);
if (rtncod == 0) {
rtncod = GetLastError();
ShowMessage("Could not watch CRTVSM compile VSMInfo.dat =>" + IntToStr(GetLastError()));
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
if (GPDataAge == FileAge(SelectedPath + GPDATA)) // date/time didn't change!
Application->MessageBox(AnsiString("Output blocking file (" + SelectedPath + GPDATA") failed to be updated. Check operation of CRTVSM.EXE before using "GPDATA" with SAM/CMS!").c_str(),"CRTVSM Error",MB_OK|MB_ICONHAND);
All of this may not be relevant, and you may not know where my personal elements come from, but that is okay as I am only concerned with the MICROSOFT process elements (such as CreateProcess and STARTUPINFO).
So far I have looked at the Process.Start method provided in this question, but do not think that it allows me to go through the same processes as the ones listed above.
My question is, what class or methods can I use to customize my exe launch in a equivalent manner to the launch that is performed in the c++ code above?
UPDATE: Currently, I have the executable file located inside a folder that I created in the solution of my program. To launch the executable I am using the ProcessStartInfo class.
//The folder that the exe is located in is called "Executables"
ProcessStartInfo startInfo = new ProcessStartInfo("Executables\\MYEXECUTABLE.EXE");
Process.Start(startInfo);
Whenever I run the above lines of code I get a Win32Exception was unhandled, and it says that "The system cannot find the file specified".
The C++ code isn't using a command 'prompt', per se, but launching a process by providing a path the the executable to CreateProcess. You can accomplish the same thing in C# with the Process class. Configure Process.StartInfo and call the Start method.
Regarding launching the executable with a specific path: if you don't specify a full path then you are at the mercy of the working directory. If the exe is the same directory as the running executable, or a subdirectory of it, then you can construct the path like this:
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"Executables\MYEXECUTABLE.EXE");
ProcessStartInfo startInfo = new ProcessStartInfo(path);
Process.Start(startInfo);
Adding on to jltrem, an example of Process.Start is:
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.110).aspx
using System;
using System.Diagnostics;
using System.ComponentModel;
namespace MyProcessSample
{
class MyProcess
{
// Opens the Internet Explorer application.
void OpenApplication(string myFavoritesPath)
{
// Start Internet Explorer. Defaults to the home page.
Process.Start("IExplore.exe");
// Display the contents of the favorites folder in the browser.
Process.Start(myFavoritesPath);
}
// Opens urls and .html documents using Internet Explorer.
void OpenWithArguments()
{
// url's are not considered documents. They can only be opened
// by passing them as arguments.
Process.Start("IExplore.exe", "www.northwindtraders.com");
// Start a Web page using a browser associated with .html and .asp files.
Process.Start("IExplore.exe", "C:\\myPath\\myFile.htm");
Process.Start("IExplore.exe", "C:\\myPath\\myFile.asp");
}
// Uses the ProcessStartInfo class to start new processes,
// both in a minimized mode.
void OpenWithStartInfo()
{
ProcessStartInfo startInfo = new ProcessStartInfo("IExplore.exe");
startInfo.WindowStyle = ProcessWindowStyle.Minimized;
Process.Start(startInfo);
startInfo.Arguments = "www.northwindtraders.com";
Process.Start(startInfo);
}
static void Main()
{
// Get the path that stores favorite links.
string myFavoritesPath =
Environment.GetFolderPath(Environment.SpecialFolder.Favorites);
MyProcess myProcess = new MyProcess();
myProcess.OpenApplication(myFavoritesPath);
myProcess.OpenWithArguments();
myProcess.OpenWithStartInfo();
}
}
}
I am trying to rewrite the following program in C instead of C# (which is less portable). It is obvious that "int system ( const char * command )" will be necessary to complete the program. Starting it with "int main ( int argc, char * argv[] )" will allow getting the command-line arguments, but there is still a problem that is difficult to understand. How do you successfully escape arguments with spaces in them? In the program below, arguments with spaces in them (example: screensaver.scr "this is a test") will be passed to the script as separate arguments (example: screensaver.scr this is a test) and could easily cause problems.
namespace Boids_Screensaver
{
static class Program
{
[STAThread]
static void Main(string[] args)
{
System.Diagnostics.Process python = new System.Diagnostics.Process();
python.EnableRaisingEvents = false;
python.StartInfo.FileName = "C:\\Python31\\pythonw.exe";
python.StartInfo.Arguments = "boids.pyw";
foreach (string arg in args)
{
python.StartInfo.Arguments += " " + arg;
}
python.Start();
}
}
}
Windows is all messed up. Every program has its own rules.
The correct way to do this under windows is to use _spawnv
Its equivalent under unix like OSes is fork() followed by execv.
screensaver.scr "spaced argument" nonspaced_argument
argc = 2
argv[0] = "screensaver.scr"
argv[1] = "spaced argument"
argv[2] = "nonspaced_argument"
Sorry my English :).