I'm trying to make a call from one process to start another, supplying starting arguments as separate parameters in a ProcessStartInfo. The starting call uses a URL registered in Windows to find the second program, entered into FileName. I then add a string containing 4 parameters to Arguments. As I have understood it, the spaces in the string indicate the separation of the arguments.
Program 1
//Create starting information
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo() {
FileName = "urlHandle:",
Arguments = "/argA valueA /argB valueB"
};
//Start second program
System.Diagnostics.Process.Start(startInfo);
Program 2
//Print received arguments to a file
Environment.GetCommandLineArgs().ToList().ForEach(a => writer.WriteLine(a + ",\t"));
The second program starts as intended (meaning the URL is working), but the output is incomplete.
[path to .exe of second program],
urlHandle:,
It contains the path to the program, the string set as FileName , but everything put into Arguments is missing.
Does anybody have any ideas why the arguments disappear?
Note 1: If I would add the arguments into the FileName, I would receive them as one string. In order to trigger the behaviour I want in the second program, I must supply it with several parameters instead of one. I know this is possible from testing it manually from the terminal.
Note 2: I'm using .Net Framework, so trying ArgumentList from .Net Core is not an option.
After some more tests I have found the issue. The error does not lie in how I set up and use ProcessStartInfo, but rather in that I am using a custom URL protocol.
In the Windows registry one defines the number of parameters that can be sent via the URL call ("C:\[path to my .exe]" "%1"). The first argument is the Filename, and is as such the only thing sent via the protocol. In order to send more, one is required to add "%2", "%3", etc.
Note: The path itself becomes argument 0 in the receiving program, while the actual sent parameters start at argument 1 and beyond.
Related
I'm trying to create a C# console app to do some proccess. I want to open my demo.exe and send some parameters from a .BAT file to that cosole.
I know the .bat should be something like:
demo.exe -a cclock -cc 1306 -mc 1750
But, I don't have any idea to make my .exe to get the parameters I'm sending.
This is where the arguments to Main method helps.
In an standard C# program entry method is like,
static int Main(string[] args)
Here args[] is the array of arguments passed to your executable via command line.
So in your example,
demo.exe -a cclock -cc 1306 -mc 1750
args is a string array containing following,
{"-a", "cclock", "-cc", "1306", "-mc", "1750"}
You can retrieve these value in this manner,
args[0] = "-a"
args[1] = "cclock"
args[2]= "-cc" ...... and so on
You can use these value for the rest of your code.
Remember that whatever values you pass are broken into separate string values on each occurrence of white-space. Also whatever value you pass will be taken as string. So you have to do your own validation and parsing.
Your application's Main method (typically in Program.cs) can accept a parameter string[] args, which you can access to get the command line parameters used to launch your app. Alternatively, you can also use Environment.GetCommandLineArgs() anywhere in the application to do the same thing.
This seems trivial, but google only gives me powershell-related stuff and how to implement pipelines within programs.
I'm trying to consume input arguments from the (standard command processor cmd.exe for Windows 7, not powershell) command line pipeline on windows like 'more' does.
I'm trying to get this to work with two self-created .exe files:
randgen (creates a random number and writes it to the console)
wordwrite (the c# program that I want to consume this random number from the pipeline)
And using two common windows executables to test and model the behaviour:
echo (writes input to console)
more (displays output one screen at a time, can consume input from the pipeline)
Here's the current content of my Main function in wordwrite:
static void Main(string[] args)
{
string ouname = args[0];
DocWrite(ouname);
}
and the behaviour trying to naively pipe output from randgen into wordwrite:
D:\code>randgen | wordwrite
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
at ADDoc.ADOUDoc.Main(String[] args)
(plus a popup telling me wordwrite.exe has stopped working)
Which is the behaviour of trying to consume a null array of arguments as input:
D:\code>wordwrite
Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.
at ADDoc.ADOUDoc.Main(String[] args)
So the output of randgen isn't being read from the pipeline correctly as an argument to the wordwrite executable's args array (thanks #Peter Duniho for explaining the difference between stdin and how argument assignation works). Contrast that with the behaviour of the 'more' executable:
D:\code>randgen | more
56929227
That said, this 'pipeline-awareness' seems to be inherent to the 'more' executable itself, as another common windows executable, echo.exe, is just as pipeline-blind as wordwrite.exe:
D:\code>randgen | echo
ECHO is on.
D:\code>echo blah
blah
D:\code>echo
ECHO is on.
Here we can see that the attempt to use the pipeline is effectively the same as providing no arguments for echo.exe (contrasted in the middle with behaviour when an argument is provided).
Which suggests there is something I can add the the body of my Main function in wordwrite.exe to enable pipeline-consuming behaviour like the 'more' executable does. Does anyone know how this is done?
You can read data 'from the pipeline' (effectively, the stdin stream*) by using the Console.ReadLine() method, like so:
static void Main()
{
string ouname = Console.ReadLine();
DocWrite(ouname);
}
*The pipeline is a tool to direct the output of one process (stdout) to the input (stdin) of another one. So when you think of 'consuming input from the pipeline', think 'assign stdin to a variable that you then do stuff with'.
Reference:
C# Console receive input with pipe
I want to build my solution file from other c# code using msbuid I have tried
var msbuild_path = #"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe";
var solution_path = #"D:\Sumit\WorkingCopy\Final\Final.sln";
Process.Start(msbuild_path + " " + solution_path);
but this one throws an error Please help me out!!
According to https://msdn.microsoft.com/en-us/library/h6ak8zt5(v=vs.110).aspx , the Process.Start method takes two arguments:
public static Process Start(string fileName, string arguments)
So you should change your code to
Process.Start(msbuild_path, solution_path);
What you were doing before was actually trying to run a file named "C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe(space)D:\Sumit\WorkingCopy\Final\Final.sln", but no such file exists with that name. The msbuild.exe may exist, but "msbuild.exe D:\Sumit...\Final.sln" is not the filename you meant to pass as the command filename. Also, the argument string was empty, so the system assumed you did not want to pass any arguments to "msbuild.exe D:\Sumit...\Final.sln". But the error message was because the two filenames were mashed into one filename.
Windows allows filenames to contain embedded spaces, which frequently causes problems in dealing with command-line arguments.
I have a windows form application
Lets call it B
Now i have another application. Lets call it A
A will start B as a new process
Now i want to pass named parameter list to B and use them in B
How can i do that ?
What i mean is example parameter list
{job:"computer engineer",age:"32",experience:"3 years"}
Also these parameter list should be optional. Sometimes i may pass 5 parameters sometimes 0
And how will i read these parameters at start up on B application
So what is the way of doing this ? thank you
c#
Assuming you're calling your "B" process with Process.Start, the following should work:
System.Diagnostics.Process.Start(string fileName, string arguments)
And your "B" processes main thread should accept an array to house possible arguments that you can then iterate over.
static void Main(string[] args)
{
//your code to decipher arguments here
}
There are two ways I can think of doing this.
First is to use command line arguments. If you were to call you process (from the command line) as:
your.exe -job "computer engineer" -age 32 -experience "3 years"
You would then duplicate this in your code by settings the arguments in your process's start options. You would then have to set up your process to look for all of these flags, remembering that they can all be optional, and so on.
The second option (and this is a bit more flexible) is to make a file that holds the values you are passing over, and read it from your launched process. You could make this XML, or straight values.
Edit: here is an example of the first option
Process p = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "your exe path";
startInfo.Arguments = "your argument list";
p.StartInfo = startInfo;
p.Start();
I don't want to tell you how to format your argument string; that should be up to you to decide. However, I will recommend a library to use that might make the parsing on the receiving end a bit easier.
I created the service called SMS serivice where i want to hit the url through the C# program
i use the following code for the same when i attach the service to the program and debug through it, I found that the code what i used is not hiting the borwser
My program :-
using System.Diagnostics;
string proc;
strUrlPath = "http://devices.panhealth.com/DeviceReading.aspx?Source=" + strSMS ";
proc= Process.Start("IExplore.exe",strUrlPath);
Still url is not hit.
but when this url copy past into IE it is working fine i want to hit it through program as following.
You can use the System.Net.WebRequest class instead.
WebRequest request = WebRequest.Create("http://devices.panhealth.com/DeviceReading.aspx?Source=" + strSMS);
just wonder...
string proc;
but
Process.Start
outputs a Process variable type.
from Object Browser info:
public static System.Diagnostics.Process Start(string fileName, string arguments)
Member of System.Diagnostics.Process
Summary: Starts a process resource by
specifying the name of an application
and a set of command-line arguments,
and associates the resource with a new
System.Diagnostics.Process component.
Parameters: fileName: The name of an
application file to run in the
process. arguments: Command-line
arguments to pass when starting the
process.
Returns: A new
System.Diagnostics.Process component
that is associated with the process,
or null, if no process resource is
started (for example, if an existing
process is reused).
and, unless you have changed your %PATH% system variable to include the IE path, you need to use the full path
Process p;
p = Process.Start(#"C:\Program Files (x86)\Internet Explorer\iexplore.exe", "http://www.google.com/");
I agree with Max - use either the WebRequest class. This has many advantages, not least because you can check the HTTP status code returned by the request to find out whether the request was successful.