I am developing an windows application in that application i use winrar command line utility to make rar files.
Code
public static string RarFiles(string rarPackagePath,
Dictionary<int, string> accFiles)
{
string error = "";
try
{
string[] files = new string[accFiles.Count];
int i = 0;
foreach (var fList_item in accFiles)
{
files[i] = "\"" + fList_item.Value;
i++;
}
string fileList = string.Join("\" ", files);
fileList += "\"";
System.Diagnostics.ProcessStartInfo sdp = new System.Diagnostics.ProcessStartInfo();
string cmdArgs = string.Format("A {0} {1} -ep1 -r",
String.Format("\"{0}\"", rarPackagePath),
fileList);
sdp.ErrorDialog = true;
sdp.UseShellExecute = true;
sdp.Arguments = cmdArgs;
sdp.FileName = winrarPath;//Winrar.exe path
sdp.CreateNoWindow = false;
sdp.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
System.Diagnostics.Process process = System.Diagnostics.Process.Start(sdp);
process.WaitForExit();
//string s = process.StandardOutput.ReadToEnd();
error = "OK";
}
catch (Exception ex)
{
error = ex.Message;
}
return error;
}
Can any one tell me how can i handle winrar diagnostic messages.
i think u missed some parts :
try adding these :
sdp.StartInfo.RedirectStandardOutput = true;
after Start, add a string to get the output. After that, call WaitForExit()
sdp.Start();
string output = stillc.StandardOutput.ReadToEnd();
sdp.WaitForExit();
*Note : This works only if an output is shown in the console window.
Hope it helps :)
Related
I am trying to run a batch file using C#
The batch file for the test purposes contains
msg * Test
It works if I run it manually.
Then I use the following code to run this .bat file
filePath = full path to batch file
var startInfo = new ProcessStartInfo
{
Arguments = "/C \"" + filePath + "\"",
FileName = "cmd.exe",
UseShellExecute = true
};
Process p = Process.Start(startInfo);
and it does not work ->
cannot find msg
What I am doing wrong?
P.S. the batch file should not be changed.
Try this way:
batchfile:
set "msg=%SystemRoot%\System32\msg.exe"
if not exist "%msg%" set "msg=%SystemRoot%\Sysnative\msg.exe"
"%msg%" * Hello
code:
string sFile = <full path to batch file>;
Process.Start("cmd.exe", "/c " + sFile);
Probably need some authorization, you may try the following code:
static void ExecuteCommand(string command)
{
int exitCode;
ProcessStartInfo processInfo;
Process process;
processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
processInfo.CreateNoWindow = true;
processInfo.Domain = "domain"; // Your own domain
processInfo.UserName = "userName"; // Your own user name
System.Security.SecureString s = new System.Security.SecureString();
s.AppendChar('p'); // Your own password
s.AppendChar('a');
s.AppendChar('s');
s.AppendChar('s');
s.AppendChar('w');
s.AppendChar('o');
s.AppendChar('r');
s.AppendChar('d');
processInfo.Password = s;
processInfo.UseShellExecute = false;
// *** Redirect the output ***
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
process = Process.Start(processInfo);
process.WaitForExit();
// *** Read the streams ***
// Warning: This approach can lead to deadlocks, see Edit #2
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
exitCode = process.ExitCode;
Console.WriteLine("output>>" + (String.IsNullOrEmpty(output) ? "(none)" :
output));
Console.WriteLine("error>>" + (String.IsNullOrEmpty(error) ? "(none)" :
error));
Console.WriteLine("ExitCode: " + exitCode.ToString(), "ExecuteCommand");
process.Close();
}
static void Main()
{
ExecuteCommand(#"C:\displayMsg.bat");
}
You may check your domain in Control Panel >> User Account >> Manage User Accounts
Source of reference: source
The problem is the location of the file (msg.exe) in the different OS versions (32bit/64bit)
I suppose it helps How can I execute msg.exe by C# in windows?
Edited:
It works fine -
class Program
{
static void Main(string[] args)
{
int ExitCode;
try
{
var returnedMsgPath = string.Empty;
if (LocateMsgExe(out returnedMsgPath))
{
var startInfo = new ProcessStartInfo()
{
FileName = returnedMsgPath,
Arguments = #"* /v Hello",
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true
};
var p = Process.Start(startInfo);
p.WaitForExit();
// *** Read the streams ***
string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
ExitCode = p.ExitCode;
MessageBox.Show("output >>" + (String.IsNullOrEmpty(output) ? "(none)" : output));
MessageBox.Show("error>>" + (String.IsNullOrEmpty(error) ? "(none)" : error));
MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
p.Close();
}
else
{
MessageBox.Show("Not found");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public static bool LocateMsgExe(out string returnedMsgPath)
{
returnedMsgPath = null;
string[] msgPaths = new string[] { Environment.ExpandEnvironmentVariables(#"%windir%\system32\msg.exe"),
Environment.ExpandEnvironmentVariables(#"%windir%\sysnative\msg.exe") };
foreach (string msgPath in msgPaths)
{
if (File.Exists(msgPath))
{
returnedMsgPath = msgPath;
return true;
}
}
return false;
}
}
I'm trying to open a place on my harddisk to store some licensing files.
So far I have tried diskpart. It looks easy to use but I could not format the unallocated partition with diskpart. I have found a way to create the unallocated space but I have to format it to use(correct me if I am wrong here. I'm really new on disk partition stuff)
This is my method to select the right volume. I've take it from here and it's working good. Link : C# and diskpart: how to select by disk label and not by a number? and the code I am using is this :
public int GetIndexOfDrive(string drive)
{
drive = drive.Replace(":", "").Replace(#"\", "");
// execute DiskPart programatically
Process process = new Process();
process.StartInfo.FileName = "diskpart.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.StandardInput.WriteLine("list volume");
process.StandardInput.WriteLine("exit");
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
// extract information from output
string table = output.Split(new string[] { "DISKPART>" }, StringSplitOptions.None)[1];
var rows = table.Split(new string[] { "\n" }, StringSplitOptions.None);
for (int i = 3; i < rows.Length; i++)
{
if (rows[i].Contains("Volume"))
{
int index = Int32.Parse(rows[i].Split(new string[] { " " }, StringSplitOptions.None)[3]);
string label = rows[i].Split(new string[] { " " }, StringSplitOptions.None)[8];
if (label.Equals(drive))
{
return index;
}
}
}
return -1;
}
once I get the index I run my own code to shrink that selected volume with this code :
Process DiskPartProc = new Process();
DiskPartProc.StartInfo.CreateNoWindow = true;
DiskPartProc.StartInfo.UseShellExecute = false;
DiskPartProc.StartInfo.RedirectStandardOutput = true;
DiskPartProc.StartInfo.FileName = #"C:\Windows\System32\diskpart.exe";
DiskPartProc.StartInfo.RedirectStandardInput = true;
DiskPartProc.Start();
DiskPartProc.StandardInput.WriteLine("select volume "+index);
DiskPartProc.StandardInput.WriteLine("shrink desired=16 minimum=16");
DiskPartProc.StandardInput.WriteLine("exit");
string output = DiskPartProc.StandardOutput.ReadToEnd();
DiskPartProc.WaitForExit();
Once I do this the result is like this :
http://prntscr.com/mjwg0t (Picture of an unallocated partition only)
I can right click on it and create new simple volume from that unallocated partition but I have to do this with diskpart commands.
Can someone tell me which diskpart commands do I have to use to achieve this?
And how can I get detailed information about this volume?
I have solve my problem. This is my final code:
int index = GetIndexOfDrive(Path.GetPathRoot(#"E:\"));
Process DiskPartProc = new Process();
DiskPartProc.StartInfo.CreateNoWindow = true;
DiskPartProc.StartInfo.UseShellExecute = false;
DiskPartProc.StartInfo.RedirectStandardOutput = true;
DiskPartProc.StartInfo.FileName = #"C:\Windows\System32\diskpart.exe";
DiskPartProc.StartInfo.RedirectStandardInput = true;
DiskPartProc.Start();
DiskPartProc.StandardInput.WriteLine("select volume " + index);
DiskPartProc.StandardInput.WriteLine("shrink desired=16 minimum=16");
DiskPartProc.StandardInput.WriteLine("create partition primary size=16");
DiskPartProc.StandardInput.WriteLine("format fs=ntfs label=\"MyPlace\" quick");
DiskPartProc.StandardInput.WriteLine("exit");
string output = DiskPartProc.StandardOutput.ReadToEnd();
DiskPartProc.WaitForExit();
The problem was something about my own disk. I have put another spare one and did all my test on it and it work perfectly, now I can create a disk volume inside a disk and format it and then I can access it with its volume ID. I still have to find a way to do it in C#. I can do the last part from windows not from C# yet. I need a way to access that volume now. I tried Directory.Exist but it did not worked out.
EDIT : I found a way to check. Since I put only 1 file and nothing else in my volume I use this code :
Process MountProc = new Process();
MountProc.StartInfo.CreateNoWindow = true;
MountProc.StartInfo.UseShellExecute = false;
MountProc.StartInfo.RedirectStandardOutput = true;
MountProc.StartInfo.FileName = "mountvol";
MountProc.StartInfo.RedirectStandardInput = true;
MountProc.Start();
MountProc.StandardInput.WriteLine("mountvol");
MountProc.StandardInput.WriteLine("exit");
string MountOutput = MountProc.StandardOutput.ReadToEnd();
MountProc.WaitForExit();
string VolumeGUID = string.Empty;
List<string> VolList = MountOutput.Split(new string[] { "Possible values for VolumeName along with current mount points are:" }, StringSplitOptions.None)[1].Split('\n').Where(x => x != "\r").Where(x => x != "").ToList();
List<string> ClearList = VolList.Select(s => s.Trim().Replace("\r", "")).ToList();
for (int i = 0; i < ClearList.Count; i++)
{
if (ClearList[i].StartsWith(#"\\?\Volume") && ClearList[i + 1].StartsWith("***"))
{
string tmpPath = ClearList[i].Replace(#"\\?\", #"\\.\");
if (Directory.Exists(tmpPath))
{
string[] DirectoryList = Directory.GetDirectories(tmpPath, "*.*", SearchOption.TopDirectoryOnly);
string[] FileList = Directory.GetFiles(tmpPath, "*.*", SearchOption.TopDirectoryOnly);
if(DirectoryList.Length==0 && FileList.Length==1)
{
if (Path.GetExtension(FileList[0]) == ".license")
{
Console.WriteLine("\n\n\n\t\rLicense file found in : " + FileList[0]);
File.Copy(FileList[0], "LIC.license", true);
Console.WriteLine("\n\t\rContent of license file : " + File.ReadAllText("LIC.license"));
File.Delete("LIC.license");
}
}
}
}
}
Console.ReadKey();
The reason why I copied the file to another location and open it there is I can't open it with File class if it's accessed with it's ID(e.g. \.\Volume{UNIQUE_ID}\)
I was trying to automate server patch installation for my product and I came to know about Wix Toolset.
I was hoping to get the JBoss Version in my installer. The command to get the same is standalone.bat --version from cmd.
So from my installer I created one CustomAction where I tried to run it and get the output.
public static string runRunnableBatch(string path){
Process exploitVersionService = new Process();
string runnableBinPath = path;
exploitVersionService.StartInfo.WorkingDirectory = path + "bin";
exploitVersionService.StartInfo.FileName = path + "bin\\standalone.bat";
exploitVersionService.StartInfo.CreateNoWindow = false;
exploitVersionService.StartInfo.Arguments = string.Format("--version");
exploitVersionService.StartInfo.UseShellExecute = false;
exploitVersionService.StartInfo.RedirectStandardOutput = true;
exploitVersionService.StartInfo.RedirectStandardInput = false;
exploitVersionService.Start();
exploitVersionService.WaitForExit();
// /*
string opt = "";
while (!exploitVersionService.StandardOutput.EndOfStream){
opt += exploitVersionService.StandardOutput.ReadLine();
}
// */
//using (StreamWriter writer = new StreamWriter("D:\\_log.txt"))
//using (StreamReader reader = exploitVersionService.StandardOutput){
// writer.AutoFlush = true;
// for (; ; ){
// string textLine = reader.ReadLine();
// if (textLine == null)
// break;
// writer.WriteLine(textLine);
// }
//}
//StreamReader exploitVersionFeed = exploitVersionService.StandardOutput;
//string output = exploitVersionFeed.ReadToEnd();
return opt;
}
When I was doing that, all I got as output was the first line of the whole output string.
I needed the whole string in my code so that from regular expression I could extract the version.
Also tried with
public static string runRunnableBatch(string path){
string executableBinPath = path + "bin";
string executableBinPath_BatchCmd = "cd " + "\"" + executableBinPath + "\"";
string outputFileName = "TempVerInfoHolder.txt";
string outputFilePath = executableBinPath+#"\TempVerInfoHolder1.txt";
string versionRetriever_BatchCmd = #"standalone.bat --version > " + "\""+outputFilePath+"\"";
string partitionName_BatchCmd = #Strings.Utils.getPartitionFromPath(path);
// Creating command sequence
SortedList<int, string> commandSequence = new SortedList<int, string>();
// ~ d:
commandSequence.Add(1, partitionName_BatchCmd);
// ~ cd %path%
commandSequence.Add(2, executableBinPath_BatchCmd);
// ~ standalone.bat --version > %filename%
commandSequence.Add(3, versionRetriever_BatchCmd);
runCommandFromSequence(commandSequence);
// Run together
return "";
}
private static void runCommandFromSequence(SortedList<int, string> commandSequence){
Process seqCmdExecHost = new Process();
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = false;
seqCmdExecHost.StartInfo = psi;
seqCmdExecHost.Start();
using (StreamWriter writer = seqCmdExecHost.StandardInput) {
if (writer.BaseStream.CanWrite) {
foreach (int item in commandSequence.Keys){
MessageBox.Show(seqCmdExecHost.Id.ToString());
MessageBox.Show(commandSequence[item]);
writer.WriteLine(commandSequence[item]);
}
}
string opt = "";
while (!seqCmdExecHost.StandardOutput.EndOfStream){
opt += seqCmdExecHost.StandardOutput.ReadLine();
}
MessageBox.Show("Exited? " + seqCmdExecHost.HasExited);
MessageBox.Show("O/P? " + opt);
}
}
I have tried some other way as well. Switching the commented code of the above function was one of them.
Output getting while doing it from code level
Calling "D:\Servers\VA\XYZ\JBoss-7.1.1-Final\bin\standalone.conf.bat
Output while running the same command manually from cmd
Calling D:\Servers\VA\XYZ\JBoss-7.1.1-Final\bin\standalone.conf.bat
======================================================================
JBoss Bootstrap Environment
JBOSS_HOME: D:\Servers\VA\XYZ\JBoss-7.1.1-Final
JAVA: C:\Program Files\Java\jdk1.7.0_67\bin\java
JAVA_OPTS
======================================================================
Listening for transport dt_socket at address: 8787
19:08:08,333 INFO [org.jboss.modules] JBoss Modules version 1.1.1.GA
JBoss AS 7.1.1.Final "Brontes"
Press any key to continue . . .
My observation is, the stream is getting closed once the nested standalone.conf.bat is getting called from standalone.bat.
If any workaround available to get the full output in string/buffer/stream, would be appreciated.
Thanks
What you could do is call the Command line Application instead of calling the batch file
exploitVersionService.StartInfo.WorkingDirectory = path + "bin";
exploitVersionService.StartInfo.FileName = "cmd.exe";
exploitVersionService.StartInfo.CreateNoWindow = false;
exploitVersionService.StartInfo.Arguments = string.Format(" /c \"{0}\" --version",path + "bin\\standalone.bat");
I found one work around to do achieve this.
I created the batch file programmatically and ran it with cmd.
public static void createBatchToGetVersion(string path)
{
CustomLogger.getInstance().debug("Started creating batch file");
BatchOps.executableBinPath = path + "bin";
CustomLogger.getInstance().debug("Ëxecutable bin path: " + BatchOps.executableBinPath);
BatchOps.tempBatchFileName = "JBossVerCmd.bat";
BatchOps.holderFileName = #"JBossVerHolder.txt";
BatchOps.absoluteHolderPath = Strings.Utils.normalize(executableBinPath) + holderFileName;
CustomLogger.getInstance().debug("Normalized absoluteHolderPath: " + BatchOps.absoluteHolderPath);
CustomLogger.getInstance().debug("Checking if JBOSS_HOME entered by user actuallty points to JBOSS");
if (!File.Exists(Strings.Utils.normalize(executableBinPath) + "standalone.bat"))
{
CustomLogger.getInstance().error("standalone.bat not found. JBOSS_HOME Dir is not correctly entered");
throw new CustomExceptions.DirectoryNotAcceptableException("Bad directory is assigned to JBOSS_HOME or JBOSS_HOME structure corrupted");
}
/*
* Batch file formation.
* Contains:
* Start file
* D:
* cd D:\Fusion Server\jboss 7.1.1\bin
* #echo | call standalone.bat --version > sample.txt
* #echo Done
* End file
* #echo is required here because it exits the cmd when completed whithout having the user pressing any key
*/
string changePartition_cmd = Strings.Utils.getPartitionFromPath(path);
string changeDirectory_cmd = #"cd " + BatchOps.executableBinPath;
string getVersion_cmd = #"#echo | call standalone.bat --version > " + holderFileName;
string exitCmd = #"#echo Done";
CustomLogger.getInstance().debug("Command to be written on batch file");
CustomLogger.getInstance().debug("\r\n" + changePartition_cmd + "\r\n" + changeDirectory_cmd + "\r\n" + getVersion_cmd + "\r\n" + exitCmd);
SortedList<int, string> commandSequence = new SortedList<int, string>();
CustomLogger.getInstance().debug("Initializing command sequence.");
commandSequence.Add(1, changePartition_cmd);
commandSequence.Add(2, changeDirectory_cmd);
commandSequence.Add(3, getVersion_cmd);
commandSequence.Add(4, exitCmd);
// Will create one if file never existed and open one delete the content and set the pointer to the begnning
// if already existed
StreamWriter batchFileWriter = null;
try
{
CustomLogger.getInstance().debug("Establishing stream to and from temp batch file");
batchFileWriter = new StreamWriter(tempBatchFileName);
CustomLogger.getInstance().debug("Command sequence ready to be written on temp batch file.");
Perform.writeToStreamFromSequence(batchFileWriter, commandSequence);
CustomLogger.getInstance().debug("Command sequence successfully written");
}
catch (IOException ex)
{
CustomLogger.getInstance().error("Error while writing command sequence.\n" + ex.ToString());
// throw exception to CustomAction
throw new IOException("Error while writing commandSequence");
}
finally
{
// Not required. Stream already closed in writeToStreamFromSequence
}
}
public static void runTempBatchFile()
{
Process seqCmdExecHost = new Process();
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", #"/c " + BatchOps.tempBatchFileName);
procStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
seqCmdExecHost.StartInfo = procStartInfo;
seqCmdExecHost.Start();
seqCmdExecHost.WaitForExit();
seqCmdExecHost.Close();
}
I found the moment i was doing
procStartInfo.UseShellExecute=true;
procStartInfo.RedirectStandardOutput=true
It was giving the first line of output. Dont know why?. If anyone has any idea about it please explain.
Thanks
I want to get the video file duration in string using C#. I searched the internet and all i get is:
ffmpeg -i inputfile.avi
And every1 say that parse the output for duration.
Here is my code which is
string filargs = "-y -i " + inputavi + " -ar 22050 " + outputflv;
Process proc;
proc = new Process();
proc.StartInfo.FileName = spath;
proc.StartInfo.Arguments = filargs;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.RedirectStandardOutput = false;
try
{
proc.Start();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
try
{
proc.WaitForExit(50 * 1000);
}
catch (Exception ex)
{ }
finally
{
proc.Close();
}
Now please tell me how can i save the output string and parse it for the video duration.
Thanks and regards,
There is another Option to get Video Length ,by using Media Info DLL
Using Ffmpeg :
proc.StartInfo.RedirectErrorOutput = true;
string message = proc.ErrorOutput.ReadToEnd();
Filtering shouldn't be an issue ,so do it you're self.
PS : using ffmpeg you should not read the StandardOutput but ErrorOutput i dont know why ,but it work's only like that.
FFmpeg is a little bit of an adventure to parse. But in any case, here's what you need to know.
First, FFmpeg doesn't play well with RedirectOutput options
What you'll need to do is instead of launching ffmpeg directly, launch cmd.exe, passing in ffmpeg as an argument, and redirecting the output to a "monitor file" through a command line output like so... note that in the while (!proc.HasExited) loop you can read this file for real-time FFmpeg status, or just read it at the end if this is a quick operation.
FileInfo monitorFile = new FileInfo(Path.Combine(ffMpegExe.Directory.FullName, "FFMpegMonitor_" + Guid.NewGuid().ToString() + ".txt"));
string ffmpegpath = Environment.SystemDirectory + "\\cmd.exe";
string ffmpegargs = "/C " + ffMpegExe.FullName + " " + encodeArgs + " 2>" + monitorFile.FullName;
string fullTestCmd = ffmpegpath + " " + ffmpegargs;
ProcessStartInfo psi = new ProcessStartInfo(ffmpegpath, ffmpegargs);
psi.WorkingDirectory = ffMpegExe.Directory.FullName;
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
psi.Verb = "runas";
var proc = Process.Start(psi);
while (!proc.HasExited)
{
System.Threading.Thread.Sleep(1000);
}
string encodeLog = System.IO.File.ReadAllText(monitorFile.FullName);
Great, now you've got the log of what FFmpeg just spit out. Now to get the duration. The duration line will look something like this:
Duration: 00:10:53.79, start: 0.000000, bitrate: 9963 kb/s
Clean up the results into a List<string>:
var encodingLines = encodeLog.Split(System.Environment.NewLine[0]).Where(line => string.IsNullOrWhiteSpace(line) == false && string.IsNullOrEmpty(line.Trim()) == false).Select(s => s.Trim()).ToList();
... then loop through them looking for Duration.
foreach (var line in encodingLines)
{
// Duration: 00:10:53.79, start: 0.000000, bitrate: 9963 kb/s
if (line.StartsWith("Duration"))
{
var duration = ParseDurationLine(line);
}
}
Here's some code that can do the parse for you:
private TimeSpan ParseDurationLine(string line)
{
var itemsOfData = line.Split(" "[0], "="[0]).Where(s => string.IsNullOrEmpty(s) == false).Select(s => s.Trim().Replace("=", string.Empty).Replace(",", string.Empty)).ToList();
string duration = GetValueFromItemData(itemsOfData, "Duration:");
return TimeSpan.Parse(duration);
}
private string GetValueFromItemData(List<string> items, string targetKey)
{
var key = items.FirstOrDefault(i => i.ToUpper() == targetKey.ToUpper());
if (key == null) { return null; }
var idx = items.IndexOf(key);
var valueIdx = idx + 1;
if (valueIdx >= items.Count)
{
return null;
}
return items[valueIdx];
}
Just check it out::
//Create varriables
string ffMPEG = System.IO.Path.Combine(Application.StartupPath, "ffMPEG.exe");
system.Diagnostics.Process mProcess = null;
System.IO.StreamReader SROutput = null;
string outPut = "";
string filepath = "D:\\source.mp4";
string param = string.Format("-i \"{0}\"", filepath);
System.Diagnostics.ProcessStartInfo oInfo = null;
System.Text.RegularExpressions.Regex re = null;
System.Text.RegularExpressions.Match m = null;
TimeSpan Duration = null;
//Get ready with ProcessStartInfo
oInfo = new System.Diagnostics.ProcessStartInfo(ffMPEG, param);
oInfo.CreateNoWindow = true;
//ffMPEG uses StandardError for its output.
oInfo.RedirectStandardError = true;
oInfo.WindowStyle = ProcessWindowStyle.Hidden;
oInfo.UseShellExecute = false;
// Lets start the process
mProcess = System.Diagnostics.Process.Start(oInfo);
// Divert output
SROutput = mProcess.StandardError;
// Read all
outPut = SROutput.ReadToEnd();
// Please donot forget to call WaitForExit() after calling SROutput.ReadToEnd
mProcess.WaitForExit();
mProcess.Close();
mProcess.Dispose();
SROutput.Close();
SROutput.Dispose();
//get duration
re = new System.Text.RegularExpressions.Regex("[D|d]uration:.((\\d|:|\\.)*)");
m = re.Match(outPut);
if (m.Success) {
//Means the output has cantained the string "Duration"
string temp = m.Groups(1).Value;
string[] timepieces = temp.Split(new char[] {':', '.'});
if (timepieces.Length == 4) {
// Store duration
Duration = new TimeSpan(0, Convert.ToInt16(timepieces[0]), Convert.ToInt16(timepieces[1]), Convert.ToInt16(timepieces[2]), Convert.ToInt16(timepieces[3]));
}
}
With thanks,
Gouranga Das.
I tried using the Process class as always but that didn't work. All I am doing is trying to run a Python file like someone double clicked it.
Is it possible?
EDIT:
Sample code:
string pythonScript = #"C:\callme.py";
string workDir = System.IO.Path.GetDirectoryName ( pythonScript );
Process proc = new Process ( );
proc.StartInfo.WorkingDirectory = workDir;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.FileName = pythonScript;
proc.StartInfo.Arguments = "1, 2, 3";
I don't get any error, but the script isn't run. When I run the script manually, I see the result.
Here's my code for executing a python script from C#, with a redirected standard input and output ( I pass info in via the standard input), copied from an example on the web somewhere. Python location is hard coded as you can see, can refactor.
private static string CallPython(string script, string pyArgs, string workingDirectory, string[] standardInput)
{
ProcessStartInfo startInfo;
Process process;
string ret = "";
try
{
startInfo = new ProcessStartInfo(#"c:\python25\python.exe");
startInfo.WorkingDirectory = workingDirectory;
if (pyArgs.Length != 0)
startInfo.Arguments = script + " " + pyArgs;
else
startInfo.Arguments = script;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
process = new Process();
process.StartInfo = startInfo;
process.Start();
// write to standard input
foreach (string si in standardInput)
{
process.StandardInput.WriteLine(si);
}
string s;
while ((s = process.StandardError.ReadLine()) != null)
{
ret += s;
throw new System.Exception(ret);
}
while ((s = process.StandardOutput.ReadLine()) != null)
{
ret += s;
}
return ret;
}
catch (System.Exception ex)
{
string problem = ex.Message;
return problem;
}
}
Process.Start should work. if it doesn't, would you post your code and the error you are getting?
You forgot proc.Start() at the end. The code you have should work if you call Start().