I have created a WPF application which I would like to run from the command line, so I can schedule this command to be executed using Windows Task Scheduler.
For example, using a command line:
start "App.exe" "ID=1"
My questions is, how do I configure my WPF application to handle a call like this and is this the right syntax I should be using from making the call from the command line.
In a WPF application, you can access the command line by using the static members of the Environment class...
public MainWindow()
{
var args = Environment.GetCommandLineArgs();
if (args.Length == 1)
{
MessageBox.Show("No argument provided");
Environment.Exit(0);
}
string arg1 = args[1]; // your argument
InitializeComponent();
}
This snippet shows how to do it. Remember that the name of the assembly is always the first argument, so you are interested in args[1] and args[2] etc etc.
The Environment class also has another member: Environment.CommandLine which has the entire command line as a string.
For your second question, your syntax is fine.
Related
I created an c# wpf application that accepts command line parameters. If I open cmd and call the application with multiple parameters, the parameters are passed in correctly.
But if I do that same thing but from a batch file it passes the parameters as one parameter combined together rather then multiple parameters. I had the application output the parameters and it looks like all the spaces (which is what separates each command line parameter) were changed to a weird á character.
is there something special I need to do to get the parameters passed correctly?
I have tried resaving the file with ASCII encoding but that didn't change anything.
I also tried adding this line to the batch file
chcp 1253>NUL
that changed it so the á wasn't there but it still had it was one parameter.
seems like the spaces are just not getting passed as a space.
here is what my batch file line looks like, each parameter is separated by a space.
start /wait C:\MyTestApp.exe /SILENT /BOOLAGREEMENT=TRUE /BOOLGAOPTIN=TRUE
--UPDATE--Adding steps to reproduce...
this is just generic code similar to what I did just condensed
create c# wpf app.
in App.xaml.cs override OnStartup
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
this.ShutdownMode = System.Windows.ShutdownMode.OnMainWindowClose;
bool shutdownapp = false;
MessageBox.Show(string.Join(",", e.Args));
}
build exe.
now launch cmd and cd to the location of the exe.
MyTestApp.exe /param1=test1 /param2=test2
you should get a message box that says
/param1=test1,param2=test2
now create a batch file that has something like this...then run it
test.bat
#echo off
start /wait c:\MyTestApp.exe /param1=test1 /param2=test2
this time the message box should have this...
/param1=test1/param2=test2
Start sees all of that as a CMD to Start.
Is there a reason you actually need to use start? generally, there isn't and you can just call the executable directly.
eg TestMyApp.cmd
#(
SETLOCAL
ECHO OFF
)
REM Call your Command here with all arguments:
"C:\MyTestApp.exe" /SILENT /BOOLAGREEMENT=TRUE /BOOLGAOPTIN=TRUE
If you sincerely require Start.
Then you should be aware that it treats all of that command as a single string, by nature, which is what you're running into, so you should be calling a new CMD instance explicitly instead in that case:
START "" /WAIT CMD /C ""C:\MyTestApp.exe" /SILENT /BOOLAGREEMENT=TRUE /BOOLGAOPTIN=TRUE"
But that is a lot of extra work to go through if not needed.
Alternatively, you can also just run a CMD instance directly:
CMD /C ""C:\MyTestApp.exe" /SILENT /BOOLAGREEMENT=TRUE /BOOLGAOPTIN=TRUE"
Or Use CALL:
CALL "C:\MyTestApp.exe" /SILENT /BOOLAGREEMENT=TRUE /BOOLGAOPTIN=TRUE
I'm trying to implement a way for me to start my WPF application with specific arguments through the Windows task schedular and CMD. I've added the code below.
protected override void OnStartup(StartupEventArgs e)
{
Logger.Info(e.Args.Length);
for (int i = 0; i != e.Args.Length; ++i)
{
if (e.Args[i] == "test")
{
Logger.Info($"G");
}
else
{
Logger.Info($"B");
}
}
}
When I start publish the application and start it through CMD or schedule it in task schedular with arguments, the e.Args.Length is 0. But when I add an argument in Properties > Debug > Command line arguments, it does work.
Any idea what I'm missing?
According to the Comments of the Question i assume the problem is that the Start-Arguments are passed wrong. A ClickOnce Application doesent work like a .exe File and can not be started with parameters from the CMD due to security reasons
(Source)
I suggest you take a look at this, it describes nicely how arguments can be passed to the application via query strings.
You need to use Environment class in System Namespace and use GetCommandLineArgs() method to retrieve the arguments.
For example,
Args = Environment.GetCommandLineArgs();
For runining the application form cmd with command arguments, use below format -
C:\StackOverflow\Bin\Debug> StackOverflow.exe arg1 arg2
I have a simple application that opens a TCP connection and communicates via Telnet to another system. The application is to read a file that contains parameters and a simple scripting language to issue commands based on prompts from the connection.
Written in VS2013 using .NET 4
My application works as designed with one little exception.
I am publishing to a location using VS2013 which works well enough but the idea is to read a command line passed to my application that contains the path/file for the script to execute and that doesn't work as expected.
Finding out the hard way, the standard args[] parameters are not passed when it's published this way.
I have searched out multiple solutions that don't work both on here and other sites.
This is the basis (excerpt from page) of my current implementation to read the command line (found here: http://developingfor.net/2010/06/23/processing-command-line-arguments-in-an-offline-clickonce-application/). This seems to be similar to all solutions I've found, each with some variation that doesn't work.
string[] args = null;
if (ApplicationDeployment.IsNetworkDeployed)
{
var inputArgs = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData;
if (inputArgs != null && inputArgs.Length > 0)
{
args = inputArgs[0].Split(new char[] { ',' });
}
}
else
{
args = e.Args;
}
This SHOULD return args[] with parameters passed. I believe it would also include the actual command with path to the application. The Split function is because the author wishes to pass arguments separated by commas and not spaces.
My incarnation of this is a bit longer to include some checks to see if we actually get arguments from being compiled as an exe instead. If I compile to EXE and supply a command line, all is fine. Here is my code, not very concise as I've made lots of changes to debug and make this work.
I haven't figured out how to debug in the ide as network deployed with a command line so my debug code is via messagebox.
[STAThread]
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if (args.Length == 0) //If we don't have args, assume onclick launch
{
if (ApplicationDeployment.IsNetworkDeployed) //are we oneclick launched?
{
var cmdline = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData; //this should hold the command line and arguments????
if (cmdline != null && cmdline.Length > 0) //we have something and it contains at least 1 value
{
//This is all debug code to see what we get since we can't trace in this mode
MessageBox.Show(cmdline.Length.ToString()); //how many objects do we have?
foreach (String s in cmdline)
{
MessageBox.Show(s); //show us the value of each object
}
Application.Run(new frmMain(args)); //launch the form with our arguments
}
else
{
//quit application
MessageBox.Show("No command line.1"); //debug so we know where we failed
Application.Exit();
}
}
else
{
//quit application
MessageBox.Show("No command line.2"); //debug so we know where we failed
Application.Exit();
}
}
else
{
Application.Run(new frmMain(args)); //launch form with args passed with exe command line
}
}
Running the code above like this:
sTelent.application 1234
I have also explored the URL passing method which seems to only apply if launched from a web server, which this application is not.
At first I got NULL for my object:
AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData
After more research I discovered that in my project properties under the Publish section there is an option button and under Manifests I can choose "Allow URL Parameters to be passed to application"
I checked this box and while I get different behavior, I don't get the desired behavior.
With that option checked I now get 2 messages boxes: The first showing the number of objects in cmdline and that number is 1 and the second showing the value of that one object which contains only the path/command to my application. No other objects and definitely not my arguments.
Am I totally off base? How do I get my command line arguments from an offline clickonce published application?
It seems that you must put the argument on the .appref-ms and not on not the .application or .exe for this to work correctly for clickonce based applications.
I created a short cut on my desktop by copying the installed application link found under All Programs. That should create an icon on your desktop with the same name as your application.
Then, open a command prompt, type in “%userprofile%\Desktop\My App Name.appref-ms” word for word (of course replace "my app name" with your application name). It should then pass the arguments. You can also put the command within a .bat file. I'm sure that you can also reference the link directly, it typically is located under c:\users[user profile]\appdata\roaming\Microsoft\windows\start menu\programs[app name]
Is it possible to create custom Command Prompt parameters for an application written and compiled in Visual Studio C#. I want the users of my application to be able to do stuff in it just by command line.
For example, if the user types in CMD application_name.exe -parameter to do the code that was assigned to parameter.
Yes, this is what string[] args is for in Program.cs.
The easiest way to ensure you have everything you need is to create your application from the Console Application template in Visual Studio.
To do this:
Go to File -> New Project...
Select Console Application from the list of available templates
Name your Solution
Hit OK to finish creating the Project
This will ensure you have all the references needed and that the Program.cs class is setup properly.
Here is a psuedo example of what you can do in the Main method of your program in order to accept parameters at the command line:
static void Main(string[] args)
{
if (args.Length <= 0) //Checking the Length helps avoid NullReferenceException at args[0]
{
//Default behavior of your program without parameters
}
else
{
if (args[0] == "/?")
{
//Show Help Manual
}
if (args[0] == "/d")
{
//Do something else
}
//etc
}
}
Then at the command prompt the user can type:
yourProgamName.exe /?
yourProgramName.exe /d
As mentioned in an answer that was removed, there is a great library for handling complex Command Line options Here:
NDesk Options
That is what the "args" parameter is for in your main method.
If your users run "application_name.exe -parameter" then args[0] will be "-parameter". You can use this to branch your application to the correct code.
Check out this question to see examples and good libraries for handling lots of command line parameters/arguments.
and if you don't have access to you main() for some reason, you can get your command line from Environment.CommandLine.
I have been working on a project of making my own IP cam pop up.
I have this working but now want to start this from the command line but pass the specific camera ip in.
My programming skills are limited and am very new to C#
The code that takes the string is
this.textBox_IP.Text = "xxx.xxx.xxx.xxx"
I have been stuck on this for a few days now of how to pass the ip in, so at the cmdline
IpCam.exe xxx.xxx.xxx.xxx
Would anyone have a solution of how to go about this
The signature of the default startup method of a C# program is
static void Main(string[] args)
The command line arguments appear in args, so if you just pass one parameter
args[0]
would contain the IP address in your example.
It would be advisable to check
args.Length >= 1
to make sure that at least one parameter has been entered.
For more advanced advice on parsing the command line, see
Best way to parse command line arguments in C#?
It is better to do this from the Main Form Load Event in GUI Apps
Its simple just pass the ip as commandline argument eg:myprogram.exe yourip
and you can get the ip from the arguments using
string[] args = Environment.GetCommandLineArgs();
But args[0] will not contain the ip,it will contain the your program name myprogram.exe
To get the ip you will have to read the second argument
string myip=args[1];
Add this in Form Load
string myip=null;
string[] myargs = Environment.GetCommandLineArgs();
string myip=myargs[1];
textBox_IP.Text =myip;