I have been trying to run a Windows command, utilising Atmel Studios atprogram utility, which is not exactly relevant but helps for context.
The following is my code, and the idea is that the output from the command is pushed into a rich text box. This is completed within the "AddTestJigString(output)" section.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string command = cmd();
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.FileName = "CMD.exe";
startInfo.Arguments = "/c cd " + ((char)34) + Path.GetDirectoryName(Properties.Settings.Default.Preferredatprogram) + ((char)34) + " && atprogram.exe - t avrispmk2 - i isp - d ATtiny26 - v chiperase program -f 30 - 5004_U21_V0.7.hex write - fs--values 61F6";
process.StartInfo = startInfo;
process.Start();
string output = process.StandardOutput.ReadToEnd();
AddTestJigString(output);
process.WaitForExit();
}
Key line being;
startInfo.Arguments = "/c cd " + ((char)34) + Path.GetDirectoryName(Properties.Settings.Default.Preferredatprogram) + ((char)34) + " && atprogram.exe - t avrispmk2 - i isp - d ATtiny26 - v chiperase program -f 30 - 5004_U21_V0.7.hex write - fs--values 61F6";
If i change this to just;
startInfo.Arguments = "/c cd " + ((char)34) + Path.GetDirectoryName(Properties.Settings.Default.Preferredatprogram) + ((char)34) + " && atprogram.exe";
I get the output of the help / list of available commands within my rich text box from atprogram.exe, so i am doing something right. However as soon as any parmeters are added, the output is totally blank.
Thanks for the above responses.
In response, the arguments for this command are defintitly correct, as it is in use in a production environment as a batch script.
The issue is actually down to outputting the command to a rich text box or more basically redirecting the command output.
The following solution I managed to get working:
{
string comhex = Path.GetFullPath(Properties.Settings.Default.PreferredComHex);
return "/c atprogram -t avrispmk2 -i isp -d ATtiny26 -v chiperase program -f " + ((char)34) + comhex + ((char)34) + " write -fs --values 61F6 2>&1";
}
The key part being the "2>&1" that I have added to the end of the command string. This effectively tells the command to redirect both Standard Output (stdout) and Standard Error (stderr). With 2 being stderr and 1 being stdout.
For further reading / reference:
In the shell, what does " 2>&1 " mean?
https://support.microsoft.com/en-gb/help/110930/redirecting-error-messages-from-command-prompt-stderr-stdout
Related
The issue lies with the space between Test & Program. How do I get around this so Process.Start(Info); works as intended. I could change Test Program.exe to TestProgram.exe and this would work perfectly. Ive looked at similar questions but non seem to answer my question. Most mention String Replace or altering the string. I dont want to alter the string but regognise there is a space and process as normal.
Apoligies if this has been asked before but I cant seem to find it so please post the link if this has. Thanks
My code
private string program_name = "Test Program.exe";
ProcessStartInfo Info = new ProcessStartInfo();
Info.Arguments = "/C choice /C Y /N /D Y /T 0 & start " + program_name;
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = "cmd.exe";
Process.Start(Info);
In your specific example - which seems a little odd, if you don't mind me saying - the program you are executing is part of the argument list and needs to be wrapped in double quotes like so:
Info.Arguments = "/C choice /C Y /N /D Y /T 0 & start \"" + program_name + "\"";
Or, just in case program_name is already quoted:
var quoted_name = $"\"{program_name.Trim('"')}\"";
Info.Arguments = "/C choice /C Y /N /D Y /T 0 & start " + quoted_name;
If that's really what you're using rather than a contrived example (which is perfectly fine as an example) then it would be simpler to just run the program directly rather than passing it as a commandline to cmd.exe, in which case you don't need the quotes at all:
ProcessStartInfo Info = new ProcessStartInfo();
Info.WindowStyle = ProcessWindowStyle.Hidden;
Info.CreateNoWindow = true;
Info.FileName = program_name; // or program_name.Trim('"')
Process.Start(Info);
Since you're hiding the console window anyway there doesn't seem much point explicitly invoking cmd.exe and having it wait around for the program to complete.
Try this:
Info.Arguments = "/C choice /C Y /N /D Y /T 0 & start \"" + program_name + "\"";
I would like to execute a cqlsh copy command from c# source code. I would like to execute a Python script, which exists under the folowing path:
C:\Program Files\DataStax Community\python\python.exe" "C:\Program Files\DataStax Community\apache-cassandra\bin\cqlsh.py
That will give me this screenshot:
Once in cqlsh, I can then run the command "copy emp to emp.csv"
The idea, is that I would like to execute all this from c# code. Here is what I did:
try
{
Process p = new Process(); // create process (i.e., the python program
p.StartInfo.FileName = #"C:\Python27\python.exe";
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false; // make sure we can read the output from stdout
p.StartInfo.Arguments = #"C:\Program Files\DataStax Community\apache-cassandra\bin\cqlsh.py" + " " + "-e copy key_space.emp to 'D:/emp.csv'"; // start the python program with two parameters
p.Start(); // start the process (the python program)
p.WaitForExit();
}catch(Exception ex)
{
Console.WriteLine(ex.Message);
string strError = ex.Message;
}
There is no exception caught but also there is nothing happened in term of result.
Any help would be appreciated .
I'm pretty sure your problem is with this line:
bin\cqlsh.py" + " " + "copy emp to D:/emp.csv";
If you were to run this from the command line, cqlsh would require the -e flag to execute a command. In Windows it'd look something like this (assuming a keyspace name of "your_keyspace":
python bin\cqlsh.py -e "copy your_keyspace.emp to d:\emp.csv"
So to actually call that from your process, you would either have to escape the double quotes or just use single quotes:
bin\cqlsh.py" + " " + "-e 'copy your_keyspace.emp to d:\emp.csv'";
I'm new to c# as well as this website so I'll probably make some mistakes but hopefully I'll learn as well.
I'm trying to develop an app to extract from a .7z a file, read it and delete it before moving to the next (there is about 12k files in there, which take up a lot of space).
Now, I'm using .NET 2.0 and I haven't found easy solutions to extract single files from an archive. I came across a post explaining that you could use 7za.exe to do so from the command line, and so I did. Now, the problem is that if I try to do the same in my app 7za throws the "cannot use absolute pathnames" error. However, as I said, the same parameters work at the command prompt.
My idea is to get a list of all the files in the compressed folder and put it in a textfile. From there it is as easy as get the name of the first one, unzip it, read it, delete it and move to next. This is what I got to get the list:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = #"C:\Users\yadayada\Desktop\7za.exe"; //just testing
string parameters= "-y l " + path_file7z + " > " + path_file_destination + #"\file.txt";
//needeless to say, path_file7z and path_file_destination are strings with the correct path like "C:\Users\yadayada\Desktop"
startInfo.Arguments = parameters
process.StartInfo = startInfo;
process.StartInfo.UseShellExecute = false;
process.Start();
process.WaitForExit();
As I said, as the process ends I can see a console opening and closing. I took a screenshot to check what it said and the error I got was the one I said at the begining of the question.
Now, does anyone know why I get this error and how can I fix this?
SOLUTION
Ended un going for a not too elegant (being gentle) solution that works.
To list the names:
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = #"cmd.exe";
string parameters= "/k -y l " + path_file7z + " > " + path_file_destination + #"\file.txt";
//needeless to say, path_file7z and path_file_destination are strings with the correct path like "C:\Users\yadayada\..."
startInfo.Arguments = parameters
process.StartInfo = startInfo;
process.StartInfo.UseShellExecute = false;
process.Start();
Thread.Sleep(1000);
process.Kill();
Now, once this has been done the extract part is tanken care of by a method similar to the one provided by Igor's links:
public void ExtractFile(string source, string element, string destination)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = /*7zG.exe's path*/;
startInfo.Arguments = #"-y x " + source + " -o" + destination + " " + element + " -r";
process.StartInfo = startInfo;
process.StartInfo.UseShellExecute = false;
process.Start();
process.WaitForExit();
}
I think it is working well now. If I have further issues I'll update this with the solutions I come up with with the help provided. Thanks again!
Use this tutorial for 7zip:
https://stick2basic.wordpress.com/2013/04/25/how-to-extract-7z-file-to-a-folder-c-net/
Use this library if rar and zip are allowed:
http://dotnetzip.codeplex.com/
private void MyExtract()
{
string zipToUnpack = "C1P3SML.zip";
string unpackDirectory = "Extracted Files";
using (ZipFile zip1 = ZipFile.Read(zipToUnpack))
{
// here, we extract every entry, but we could extract conditionally
// based on entry name, size, date, checkbox status, etc.
foreach (ZipEntry e in zip1)
{
e.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
}
}
EDIT
This can help you:
Unzip a file in c# using 7z.exe
Happy to help you!
I've created a GUI app that basically loads a video file, launches 3 processes with arguments in sequential order, (ffmpeg, x264, mp4box) and has the ability to abort if needed.
I'm trying to figure out a way to launch these processes without them stealing focus from whatever program is opened. Not necessarily the original form itself...it could be IE, MS WORD, etc...I know about ProcessWindowStyle, however, all options still take focus away. I do not want to start these processes hidden either.
This is an example of my code for starting a process
Process ffmpegProcess = new Process();
ffmpegProcess.StartInfo.FileName = Settings.Default.ffmpeg;
ffmpegProcess.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
string outputaud = text2 + "_audio.aac";
string AudioBitrate = this.cBAudiobitrate.GetItemText(this.cBAudiobitrate.SelectedItem);
string ffargs = "-i " + quote + SourceFile + quote + " -filter_complex " + quote + "[0:2][0:3]amerge=inputs=2,pan=stereo|c0=c0+c1|c1=c0+c1[aout]" + quote + " -map " + quote + "[aout]" + quote + " -strict experimental -acodec aac -b:a " + AudioBitrate + "k " + quote + outputaud + quote;
ffmpegProcess.StartInfo.Arguments = ffargs;
ffmpegProcess.Start();
while (!ffmpegProcess.HasExited)
{
if (this.bw404p_withaudio.CancellationPending)
{
ffmpegProcess.Kill();
e.Cancel = true;
return;
}
Thread.Sleep(1000);
}
I know about using the Microsoft.VisualBasic Reference and Shell command with AppWinStyle as it has options for launching with no focus, I just can't seem to figure out how to modify my code to make it work with that.
Any ideas?
Thanks
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
Is that would you're looking for? More info below
How to start Process hidden?
http://www.dotnetperls.com/process-start
ProcessWindowStyle Enumeration
Long story short...
This doesnt work:
Process p = new Process();
p.StartInfo.FileName = #"External\PsExec.exe";
string file = String.Concat(Path.Combine(Environment.CurrentDirectory,"temp"),#"\iisreset",DateTime.Now.ToString("ddMMyyyy-hhmmssss"),".txt");
p.StartInfo.Arguments = String.Format("-s -u {0}\\{1} -p {2} \\\\{3} iisreset > \"{4}\"", Domain,UserName, Password, machineIP, file);
p.StartInfo.CreateNoWindow = true;
p.Start();
p.WaitForExit();
I'm getting a RPC Unavailable message.
But when I access the command line in the program folder, then i run this: (with the correct parameters), exactly like I specified in the filename/arguments...
External\PsExec.exe -s -u [user] -p [password] \\[ip] iisreset > "[path]"
It works!
Do I have to specify anything else in the C# Process ? What could be possibly happening?
Thanks in advance!
EDIT: It works if I put cmd as the FileName and /c PsExec.exe before the arguments. The problem is this way it always show the window.
Instead of using p.startinfo.arguments use p.standardinput.writeline(command)
string PSPath = #"C:\PSTools\PsExec.exe";
fullcommand = PSPath + " -u " + userName + " -p " + password + " \\\\" + remoteMachine + " -h cmd.exe /c " + command + "";
Console.Clear();
//Console.WriteLine(fullcommand);
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.FileName = "cmd.exe";
//process.StartInfo.Arguments = fullcommand;
process.Start();
process.StandardInput.WriteLine(fullcommand);
process.StandardInput.Flush();
process.StandardInput.Close();
Console.WriteLine("*****Command*****");
Console.WriteLine(fullcommand);
Console.WriteLine("*****Output*****");
Console.WriteLine(process.StandardOutput.ReadToEnd());
Console.WriteLine("*****Error*****");
Console.WriteLine(process.StandardError.ReadToEnd());
Console.WriteLine("*****Exit*****");
process.WaitForExit();
Console.WriteLine("Again ?");
You cannot redirect standard output using the arguments the way you are doing. That's not how things actually work.
At the command line, your arguments end when the command interpreter sees the >, and it begins the process of redirecting standard output to the filename.
To accomplish this in C# you need to use the RedirectStandardOutput property of the StartInfo class, then read from the Process.StandardOutput stream and write to a file.
The MSDN documentation for RedirectStandardOutput has a short example you can use to get started.
iisreset [machinename] -
you don't need psexec