I'm using a commandline execute to run a reg delete /f. Now when I do it via commandline it works as intended, but if I run it from C# I still get a prompt.
Now I'm wondering where the erorr lies....thus why do I still get a prompt when I call the command via C# despite the /f parameter being used.
Edit: A small info here: .NET Framework is 3.5
The code that is being used is as follows:
LaunchProcessAndWait(#"cmd",
#"/c reg delete " + "\""
+ #"HKLM\Software\Policies\Microsoft\Internet Explorer\Main"+ "\""
+ #" /v DisableFirstRunCustomize /f",
"");
public static string LaunchProcessAndWaitForOutput(string commandline, string args, bool returnError, bool returnOutput, string workingDir)
{
ProcessStartInfo info = new ProcessStartInfo(commandline, args);
if (workingDir != null)
{
info.WorkingDirectory = workingDir;
}
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.CreateNoWindow = true;
Process p = Process.Start(info);
string outStr = "";
string errStr = "";
p.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
{
outStr += e.Data + "\r\n";
});
p.ErrorDataReceived += new DataReceivedEventHandler((sender, e) =>
{
errStr += e.Data + "\r\n";
});
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
p.Close();
return "" + (returnOutput ? outStr : "") + (returnError ? errStr : "");
}
}
Related
I'm using Mplayer to extrac audio from video via command line. This is the command i use:
mplayer -ao pcm:fast:file=aaa.wav aaa.avi
I copied Mplayer.exe and aaa.avi both on windows drive (C:) and on the root directory of an external hard drive (in my case X).
When i execute from C the dumping start at normal speed (i see the video on real time) and aaa.wav is not created by Mplayer.
When i execute form X the dumping start at fast speed (as requested by the -ao pcm:fast audio driver) and the aaa.wav is correctly created.
I have the same issue in my app, here the code i use to do it:
public static string DumpWav_ConsoleOutput = "";
public static int DumpWav_ProcessID = 0;
Process DumpWav_Process = null;
private void DumpWav(string SourceFileName, string DestinationFileName, bool NeedToCut, TimeSpan Start, TimeSpan End)
{
//cancelliamo le variabili
DumpWav_ConsoleOutput = "";
//Handle della finestra di Media Player
Variables.MediaPlayerHandle = 0;
Variables.MediaPlayerHandle = (int)MediaPlayer.Handle;
Thread thread = new Thread(() => _DumpWav(SourceFileName, DestinationFileName, NeedToCut,Start, End)); //il thread principale di Dump Wav
thread.Start();
while (thread.IsAlive) //aspettiamo il suo completamento
{
Application.DoEvents();
}
var myForm = new Output();
myForm.SetOutputText = Variables.ConsoleOutputMP;
myForm.Show();
Variables.MediaPlayerExit = true;
// ok il processo è terminato
}
private void _DumpWav(string SourceFileName, string DestinationFileName, bool NeedToCut, TimeSpan Start, TimeSpan End)
{
string Output;
Output = RunDumpWav((output) => { }, SourceFileName, DestinationFileName, NeedToCut, Start, End);
}
// Media Player avviato da questa funzione
public string RunDumpWav(Action<string> output, string SourceFileName, string DestinationFileName, bool NeedToCut, TimeSpan Start, TimeSpan End)
{
if (output == null)
throw new ArgumentNullException("output");
string args;
ProcessStartInfo ps = new ProcessStartInfo();
ps.FileName = FindMediaPlayerPath("mplayer.exe");
ps.UseShellExecute = false;
ps.RedirectStandardInput = true;
ps.RedirectStandardError = true;
ps.RedirectStandardOutput = true;
ps.CreateNoWindow = true;
ps.WorkingDirectory = #"x:\";
args = "-wid ";
args += Variables.MediaPlayerHandle;
args += " -ao pcm:fast:file=";
args += DestinationFileName;
if (NeedToCut == true)
{
args += " -ss " + Start + " -endpos " + End;
}
//args += " -vo null -vc null -quiet ";
//-wid will tell MPlayer to show output inisde our panel
args += " " + SourceFileName;
ps.Arguments = args;
using (DumpWav_Process = Process.Start(ps))
using (ManualResetEvent mreOut = new ManualResetEvent(false),
mreErr = new ManualResetEvent(false))
{
DumpWav_Process.OutputDataReceived += (o, e) => { if (e.Data == null) mreOut.Set(); else output(e.Data); };
DumpWav_Process.BeginOutputReadLine();
DumpWav_Process.ErrorDataReceived += (o, e) => { if (e.Data == null) mreErr.Set(); else output(e.Data); }; ;
DumpWav_Process.BeginErrorReadLine();
output = s => DumpWav_ElaborateOutput(s);
DumpWav_ProcessID = DumpWav_Process.Id;
//processMP.StandardInput.Close();
DumpWav_Process.WaitForExit();
mreOut.WaitOne();
mreErr.WaitOne();
//stringa di ritorno (tutto il contenuto della console)
return DumpWav_ConsoleOutput;
}
}
//controlliamo l'output della console
private void DumpWav_ElaborateOutput(string output)
{
Variables.ConsoleOutputMP = Variables.ConsoleOutputMP + output + Environment.NewLine;
if (output.IndexOf("A:") != -1)
{
//some check here
}
}
I recently added this:
ps.WorkingDirectory = #"x:\";
But the result not change, the video speed is not fast and the wav file is not created by Mplayer.
In my app, like the C test, i receive some errors:
[AO PCM] Failed to open aaa.wav for writing!
Failed to initialize audio driver 'pcm:fast:file=aaa.wav'
One more question, when i use mPlayer to encapsulate videos inside my app the process start about one minute after i launched it... maybe concatenate with dumping issue?
Please, any suggestion?
Edit:
I discovered just now: If i start the command prompt with admin rights then also in C Drive Mplayer do the job in the right way...
My app unfortunately don't. I edited the manifest to grant admin rights but it's the same. Somewhere here at stackoverflow i read something about to useshellexecute to true but unfortunately by this way (i need to test anyway) i lose the ability to redirect input/output/error.
I need to find a way to start the process (then the mplayer.exe) from within my app, with admin rights, without use shellexecute...
Edit 2°
I created a simple button with this code:
string args;
//Handle della finestra di Media Player
Variables.MediaPlayerHandle = 0;
Variables.MediaPlayerHandle = (int)MediaPlayer.Handle;
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = FindMediaPlayerPath("mplayer.exe");
//psi.FileName = #"x:\mplayer.exe";
psi.UseShellExecute = true;
psi.CreateNoWindow = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.WorkingDirectory = Environment.CurrentDirectory; ;
psi.Verb = "runas";
args = "-wid ";
args += Variables.MediaPlayerHandle;
args += " -ao pcm:fast:file=";
args += #"x:\aaa.wav";
args += #" x:\aaa.avi";
psi.Arguments = args;
Process.Start(psi);
:-( same result, Mplayer is not able to open audio driver and to save file..
Fail, again.. 3° edit:
I tried using CMD:
private void button2_Click(object sender, EventArgs e)
{
ProcessStartInfo processInfo;
Process process;
Variables.MediaPlayerHandle = 0;
Variables.MediaPlayerHandle = (int)MediaPlayer.Handle;
string args = "";
args = #"x:\mplayer.exe -wid " + Variables.MediaPlayerHandle + #" -ao pcm:fast:file=x:\aaa.wav x:\aaa.avi";
MessageBox.Show(args);
processInfo = new ProcessStartInfo("cmd.exe", "/c " + args);
processInfo.CreateNoWindow = true;
processInfo.UseShellExecute = true;
processInfo.Verb = "runas";
process = Process.Start(processInfo);
process.WaitForExit();
MessageBox.Show("terminato");
process.Close();
}
Now i see the first frame of the video and Mplayer freeze...
I'm losing my hope to use mplayer :-(
Finally i solved...
This is the code:
if (output == null)
throw new ArgumentNullException("output");
string args;
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = FindMediaPlayerPath("mplayer.exe");
//psi.FileName = #"x:\mplayer.exe";
psi.UseShellExecute = false;
psi.RedirectStandardInput = true;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
psi.WorkingDirectory = Path.GetDirectoryName(DestinationFileName);
psi.Verb = "runas";
args = "-wid ";
args += Variables.MediaPlayerHandle;
args += " -ao pcm:fast:file=";
args += Path.GetFileName(DestinationFileName);
if (NeedToCut == true)
{
args += " -ss " + Start + " -endpos " + End;
}
//args += " -vo null -vc null -quiet ";
//-wid will tell MPlayer to show output inisde our panel
args += " " + SourceFileName;
psi.Arguments = args;
As i understand i need to move the Process.WorkingDirectory to the same folder as the destination file (in my case the wav).
Now it rocks :-)
NO need for UAC
NO need for useshellexecute = true
Thanks stanley for your help!
Running a c# console application compiled in visual studio 2013 on a Raspberry Pi(Linux) with Mono installed, the following code...
System.Diagnostics.Process syncProc = new System.Diagnostics.Process();
syncProc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
syncProc.StartInfo.UseShellExecute = false;
syncProc.StartInfo.FileName = "bash";
syncProc.StartInfo.Arguments = "-c sync --help";
syncProc.StartInfo.RedirectStandardError = true;
syncProc.StartInfo.RedirectStandardOutput = true;
syncProc.Start();
String stdOutput = syncProc.StandardOutput.ReadToEnd();
String errorOutput = syncProc.StandardError.ReadToEnd();
syncProc.WaitForExit();
if (syncProc.ExitCode == 0)
{
Console.WriteLine("SOUTPUT: " + stdOutput);
}
else
{
Console.WriteLine("EOUTPUT: " + errorOutput);
throw new Exception("Failed to sync with exit code: " + syncProc.ExitCode);
}
...outputs "SOUTPUT: "
Why is stdOutput always empty?
You could try redirecting the whole output asynchronously like this:
syncProc.ErrorDataReceived += (s, e) => Console.WriteLine("EOUTPUT:{0}", e.Data);
syncProc.OutputDataReceived += (s, e) => Console.WriteLine("SOUTPUT:{0}", e.Data);
syncProc.Start();
syncProc.BeginErrorReadLine();
syncProc.BeginOutputReadLine();
Why is stdOutput always empty?
The arguments are passed wrongly. The -c option's commands must be contained in a single argument command_string:
syncProc.StartInfo.Arguments = "-c 'sync --help'";
I am trying to read the CGMiner output in a C# program I am writing. I successfully read/write the standard thread input/output. But for some reason CGMiner does not write to the standard cmd window output, and I can't read it in C#. Any ideas?
This is my process start:
public void start() {
proc = new Process();
proc.StartInfo.FileName = "CMD.exe";
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.OutputDataReceived += (s, e) => updateConsoleOutput(e);
proc.Start();
proc.BeginOutputReadLine();
}
This is the function I use to write to the console:
public void RunCommand(string cmd = "") {
if (cmd.Length > 0) {
ConsoleInput = cmd;
}
StreamWriter myStreamWriter = proc.StandardInput;
myStreamWriter.WriteLine(ConsoleInput);
myStreamWriter.Flush();
ConsoleInput = String.Empty;
}
These are the functions I use to read from the console:
public delegate void consoleOutputCallback(string message);
private void updateConsoleOutput(DataReceivedEventArgs outLine) {
if (!String.IsNullOrEmpty(outLine.Data)) {
this.Dispatcher.Invoke(
new consoleOutputCallback(updateConsoleText),
new object[] { outLine.Data }
);
}
}
public void updateConsoleText(string message) {
this.OutputBlock.Text += message + "\n";
}
HINT: Don't know if it helps, but CGMiner will overwrite the entire console window, and cursor always stay at top left and does not move. All command before running CGMiner is overwritten.
Forgot to add, this is console command I use:
cd C:\cgminer\
del *.bin
cgminer.exe -o stratum+tcp://global.wemineltc.com:3335 -O yongke.1:x -g 2
You need to set the --per-device-stats flag in order for GPU stats to be written into stream
And don't forget to add this to the code in question
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardError = true;
proc.ErrorDataReceived += (s, e) => updateConsoleOutput(e);
....
proc.Start();
proc.BeginErrorReadLine();
Most of miners use standart Error stream instead of standart Output stream (to write both output data and errors) for some reason..
the only thing that made it work for me was
-T
here is my working code
Task StartGPUMiner(object set)
{
MinerParams m = new MinerParams();
m = (MinerParams)set;
var tcs = new TaskCompletionSource<object>();
Process p = new Process();
ProcessStartInfo start = new System.Diagnostics.ProcessStartInfo();
start.FileName = m.ApplicationPath + "\\cgminer\\cgminer.exe";
start.Arguments = " -I " + m.GpuIntisity + " -T --scrypt -o " + m.sProtocol + m.ServerName + ":" + m.ServerPort + " -u " + m.UserName + "." + m.WorkerName + " -p " + m.ThePassword + " " + m.GpuParams;
start.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
start.RedirectStandardOutput = true;
start.UseShellExecute = false;
start.CreateNoWindow = true;
var proc = Process.Start(start);
proc.OutputDataReceived += (s, e) =>
{
try
{
this.Invoke((Action)delegate
{
txtLog.Text += (e.Data + Environment.NewLine);
});
}
catch { }
};
try
{
proc.Exited += (s, e) => tcs.SetResult(null);
proc.EnableRaisingEvents = true;
proc.BeginOutputReadLine();
}
catch { }
return tcs.Task;
}
I am open WireShark using command line and start capture the packets, when i do it using CMD windows i can see the number of the incoming packets and this number i want to show in my application form (win form), currently this is my code but my application crash with error
static void Main(string[] args)
{
try
{
string _pcapPath = #"C:\test.pcap";
Process _tsharkProcess = new Process();
_tsharkProcess.StartInfo.FileName = #"C:\Program Files\Wireshark\tshark.exe";
_tsharkProcess.StartInfo.Arguments = string.Format(" -i " + 2 + " -c " + int.MaxValue + " -w " + _pcapPath);
_tsharkProcess.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
_tsharkProcess.StartInfo.RedirectStandardOutput = true;
_tsharkProcess.StartInfo.UseShellExecute = false;
//_tsharkProcess.StartInfo.CreateNoWindow = true;
//_tsharkProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
_tsharkProcess.Start();
StreamReader myStreamReader = _tsharkProcess.StandardOutput;
string myString = myStreamReader.ReadLine(); //read the standard output of the spawned process.
Console.WriteLine(myString);
_tsharkProcess.WaitForExit();
}
catch (Exception)
{
}
}
private static void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
string srt = e.Data; //arg.Data contains the output data from the process...
}
You can try with this code
Nota : Set these lines before start
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
Code:
Process process = new Process();
process.StartInfo.FileName = #"C:\Program Files\Wireshark\tshark.exe";
process.StartInfo.Arguments = string.Format(" -i " + _interfaceNumber + " -c " + int.MaxValue + " -w " + _pcapPath);
process.OutputDataReceived += new DataReceivedEventHandler(process_OutputDataReceived);
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
StreamReader myStreamReader = process.StandardOutput;
// Read the standard output of the spawned process.
string myString = myStreamReader.ReadLine();
Console.WriteLine(myString);
process.WaitForExit();
process.Close();
}
I use this method to compile C++ file in VS. But even i provide the correct file it returns false. Can any one help me...
This is class called CL
class CL
{
private const string clexe = #"cl.exe";
private const string exe = "Test.exe", file = "test.cpp";
private string args;
public CL(String[] args)
{
this.args = String.Join(" ", args);
this.args += (args.Length > 0 ? " " : "") + "/Fe" + exe + " " + file;
}
public Boolean Compile(String content, ref string errors)
{
if (File.Exists(exe))
File.Delete(exe);
if (File.Exists(file))
File.Delete(file);
File.WriteAllText(file, content);
Process proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = clexe;
proc.StartInfo.Arguments = this.args;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
//errors += proc.StandardError.ReadToEnd();
errors += proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
bool success = File.Exists(exe);
return success;
}
}
This is my button click event
private void button1_Click(object sender, EventArgs e)
{
string content = "#include <stdio.h>\nmain(){\nprintf(\"Hello world\");\n}\n";
string errors = "";
CL k = new CL(new string[] { });
if (k.Compile(content, ref errors))
Console.WriteLine("Success!");
else
MessageBox.Show("Errors are : ", errors);
}
In your Visual Studio installation folder there should be the following path:
VC\bin\x86_amd64\1033\1033
There should be a clui.dll in this path. Copy it to the parent folder (VC\bin\x86_amd64\1033). This should solve your problem.
I took the solution from http://connect.microsoft.com/VisualStudio/feedback/details/108528/command-line-issue-when-building-for-64bit-in-32bit-with-cl-exe:
Maybe it is not relevant, but I think you miss a space in your command line...
this.args += (args.Length > 0 ? " " : "") + "/Fe" + exe + " " + file;
right after the "/Fe"