I made myself a proof of concept to test this tool to manage audio files.My purpose is to change sample rate. My first example works fine!
public class Test
{
public void SoxMethod()
{
var startInfo = new ProcessStartInfo();
startInfo.FileName = "C:\\Program Files (x86)\\sox-14-4-2\\sox.exe";
startInfo.Arguments = "\"C:\\Program Files (x86)\\sox-14-4-2\\input.wav\" -r 16000 output.wav";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = false;
startInfo.WorkingDirectory= "C:\\Program Files (x86)\\sox-14-4-2";
using (Process soxProc = Process.Start(startInfo))
{
soxProc.WaitForExit();
}
}
}
But when I want to add this tool in my bin folder but I get the exception: The directory name is invalid
public void SoxMethod()
{
var startInfo = new ProcessStartInfo();
startInfo.FileName = "bin/sox-14-4-2/sox.exe";
startInfo.Arguments = "bin/sox-14-4-2/input.wav -r 16000 output.wav";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = false;
startInfo.WorkingDirectory= "bin/sox-14-4-2";
using (Process soxProc = Process.Start(startInfo))
{
soxProc.WaitForExit();
}
}
Maybe its very obvious but I dont know what I'm doing wrong
Your working directory is wrongly set. Use AppDomain.CurrentDomain.BaseDirectory instead. That will make the Process to start at bin folder. Then, replace your file and your arguments to work relative to the working directory (thus remove the bin part of your path).
public void SoxMethod()
{
var startInfo = new ProcessStartInfo();
startInfo.FileName = "sox-14-4-2/sox.exe";
startInfo.Arguments = "sox-14-4-2/input.wav -r 16000 output.wav";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = false;
startInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
using (Process soxProc = Process.Start(startInfo))
{
soxProc.WaitForExit();
}
}
Related
I've been trying to create a simple application to backup my Windows Server databases aswell as a whole server backup.
For this I want to use batch files which are being executed by my application.
I tried several approaches but for some reason it always fails so I'd be happy if you could help me out.
Batch file BACKUPSERVER:
wbadmin start backup -backupTarget:D: -include:C: -allCritical -quiet
I have to run the bat as administrator or it fails due to missing permissions.
C# code:
static Task<int> RunProcessAsync(string fileName)
{
............
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.Verb = "runas";
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C \"D:\\SQLBACKUP\\BACKUPSERVER.bat\"";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
}
Debugging says 'wbadmin wasnt found'. 'runas' activated or not doesn't make any difference.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = fileName;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = true;
startInfo.CreateNoWindow = false;
// startInfo.Verb = "runas";
var process = new Process
{
StartInfo = { FileName = fileName },
EnableRaisingEvents = true
};
process.StartInfo = startInfo;
process.Exited += (sender, args) =>
{
tcs.SetResult(process.ExitCode);
process.Dispose();
};
process.Start();
Also doesn't work.
Any ideas?
EDIT:
I'm able to run commands like shutdown but wbadmin doesn't work whatsoever...
This is how I solved the problem:
Make sure ure compiling for 64bit if u intend to use your application on 64bit system, otherwise it will redirect to different subfolders and wont find 'wbadmin.exe'.
Run wbadmin with ProcessStart or run a batch but without direct cmd input, so use this with filename = batch file or wbadmin with startInfo.Arguments:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = fileName;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = true;
startInfo.CreateNoWindow = false;
// startInfo.Verb = "runas";
var process = new Process
{
StartInfo = { FileName = fileName },
EnableRaisingEvents = true
};
process.StartInfo = startInfo;
process.Exited += (sender, args) =>
{
tcs.SetResult(process.ExitCode);
process.Dispose();
};
process.Start();
Make sure u request administrator rights
I am trying to execute a command by Process in c#, but problem is that that command ask a question (y/n) and process hang there. would you mind recommend me a solution?
public static OutputEventArgs execSync(string exe, string arguments)
{
OutputEventArgs oea = new OutputEventArgs();
try
{
using (Process myProcess = new Process())
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.FileName = exe;
startInfo.Arguments = arguments;
myProcess.StartInfo = startInfo;
myProcess.Start();
oea.Data = myProcess.StandardOutput.ReadToEnd();
myProcess.WaitForExit();
oea.exitCode = myProcess.ExitCode;
}
}catch(Exception e)
{
oea.Data = e.Message;
oea.ExceptionHappened();
}
return oea;
}
my command output is something like below:
C:\Users\abc>pcli Label -prI:\PVCS\DEVELOPMENT\
-idabcd:abcpass -v'test3' -f -z '/Project1/APPLICATION/ajax_fetchGetCustNew.php' Unknown os = Windows
NT (unknown) Serena PVCS Version Manager (PCLI) v8.4.0.0 (Build 668)
for Windows NT/80x86 Copyright 1985-2010 Serena Software. All rights
reserved. Version "test3" is already defined in archive
"I:\PVCS\DEVELOPMENT\archives\Project1\Application\ajax_fetchGetCustNew.php-arc".
Overwrite? (y/n)
using(var myProcess = new Process()) {
...
myProcess.Start();
myProcess.StandardInput.WriteLine("y"); // Write 'y' to the processes' console input
...
}
Note: This approach is not very reusable.
Using a command line option like /no-confirm (as John Wu suggested in the questions comments) is preferable, if it exists.
I'm running the below command from c#. There is a prompt that will be shown that I want to answer "yes" to how can I do this with the current code
If I run this as a batch script I can just do
echo y | pscp.exe -batch -pw password E:\\Certs\\client.conf me#<ip>:/home/user
which works - but unsure how I can replicate this using the below
string pscpPath="-batch -pw password E:\\Certs\\client.conf me#<ip>:/home/user";
ExecuteCopyCerts("pscp.exe", pscpPath);
Function:
public Boolean ExecuteCopyCerts(string fileName, string arguments)
{
txtLiveHubStatus.Text = "";
try
{
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo(fileName, arguments);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
string result = proc.StandardOutput.ReadToEnd();
return proc.ExitCode == 0;
}
}
Set RedirectStandardInput to true
procStartInfo.RedirectStandardInput = true
and then write to StandardInput
proc.StandardInput.WriteLine("yes");
To reiterate what Hesam said though the prompt is Y, not yes. This is the prompt for the cert, which only occurs on the first call to each new linux machine. I use this code today in one of our applications.
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "pscp";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = false;
psi.Arguments = $"-r -p -pw {passWord} \"{localFileNamePath}\" {userName}#{hostName}:{remotePath}";
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
using (Process process = new Process())
{
process.StartInfo = psi;
process.Start();
process.StandardInput.WriteLine("Y");
process.WaitForExit();
}
I have a problem, I start cygwin commands with c#, what is working fine. The Problem is to set the working directory.
pathANDcommand = C:\cygwin\bin\ls.exe";
arg = " -lisa";
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = pathANDcommand;
startInfo.Arguments = arg;
output.Enqueue(arg + "\n" + "\n");
startInfo.WorkingDirectory = #"\cygdrive\c\Users\jhb\Source\Repos\myprogramm";
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo = startInfo;
process.Start();
If I set startInfo.WorkingDirectory to a windows path the program will run, but the command does not run in the path I set.
The original location (strange behaviour on another process via Process.Start(startInfo)) doesn't allow me post test code properly. I have to start a new question here.
Our C#(V3.5) needs to call a C++ executable to process a raw data file and generate result files for us.
It worked before with the following code (without ReadToEnd() or ReadLine() call):
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
Now the input raw data file changed (bigger than before). Our call to that executable will hang forever. Based on advice, I added ReadToEnd() or ReadLine() but it will hang on those calls. So I have to either use startInfo.UseShellExecute = true; or set
startInfo.UseShellExecute = false;
// and with
startInfo.RedirectStandardError = false;
startInfo.RedirectStandardOutput = false;
Don't know why?
Following are cases I tested:
working case:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = false;
startInfo.RedirectStandardOutput = false;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
//startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
try
{
Process correctionProcess = Process.Start(startInfo);
correctionProcess.WaitForExit();
}
working case:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = true;
startInfo.RedirectStandardError = false;//can be commented out
startInfo.RedirectStandardOutput = false;//can be commented out
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
try
{
Process correctionProcess = Process.Start(startInfo);
correctionProcess.WaitForExit();
}
NOT working case (using ReadLine()):
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
//startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
try
{
Process correctionProcess = Process.Start(startInfo);
while (!correctionProcess.HasExited)
{
Log.logItem(LogType.Performance, "read errorMsg ####", "DPTM::correctData()", "");
string errorMsg = correctionProcess.StandardError.ReadLine(); // <-- Hangs here
Log.logItem(LogType.Performance, "read errorMsg", "DPTM::correctData()", "errorMsg=" + errorMsg);
string outputMsg = correctionProcess.StandardOutput.ReadLine();
Log.logItem(LogType.Performance, "read outputMsg", "DPTM::correctData()", "outputMsg=" + outputMsg);
Thread.Sleep(100);
}
}
NOT working case (using ReadToEnd()):
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
//startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
try
{
Process correctionProcess = Process.Start(startInfo);
while (!correctionProcess.HasExited)
{
Log.logItem(LogType.Performance, "read errorMsg ####", "DPTM::correctData()", "");
string errorMsg = correctionProcess.StandardError.ReadToEnd(); // <-- Hangs here!
Log.logItem(LogType.Performance, "read errorMsg", "DPTM::correctData()", "errorMsg=" + errorMsg);
string outputMsg = correctionProcess.StandardOutput.ReadToEnd();
Log.logItem(LogType.Performance, "read outputMsg", "DPTM::correctData()", "outputMsg=" + outputMsg);
Thread.Sleep(100);
}
}
NOT working case:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
//startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
try
{
Process correctionProcess = Process.Start(startInfo);
Log.logItem(LogType.Performance, "read errorMsg ####", "DPTM::correctData()", "");
string errorMsg = correctionProcess.StandardError.ReadToEnd(); // <-- Hangs here!
Log.logItem(LogType.Performance, "read errorMsg", "DPTM::correctData()", "errorMsg=" + errorMsg);
string outputMsg = correctionProcess.StandardOutput.ReadToEnd();
Log.logItem(LogType.Performance, "read outputMsg", "DPTM::correctData()", "outputMsg=" + outputMsg);
correctionProcess.WaitForExit();
}
you are deadlocked on the error/output buffer. Your second process is waiting for the buffer to free up while you are waiting for that process to finish. You need to asynchronously read output/error streams to prevent that.
Looking at your MSDN sample: wow that sample is really confusing... It would've been easier to follow if they just limited it to std out or std error.
You need to first set data handler
correctionProcess.OutputDataReceived += new DataReceivedEventHandler(OutputDataHandler);
and then call
p.BeginOutputReadLine();
Just like comment [confusingly] advises do no try to read output there. Use handler instead.
private void OutputDataHandler(object sendingProcess, DataReceivedEventArgs data)
{
if (data.Data != null)
{
// append data.Data to your internal buffer (StringBuilder?)
}
}