public class CmdHelper
{
public static string StartCmd(string commandLine)
{
commandLine = commandLine.Trim().TrimStart('&') + "&exit";
string outputMsg = "";
Process pro = new Process();
pro.StartInfo.FileName = "cmd.exe";
pro.StartInfo.UseShellExecute = false;
pro.StartInfo.RedirectStandardError = true;
pro.StartInfo.RedirectStandardInput = true;
pro.StartInfo.RedirectStandardOutput = true;
pro.StartInfo.CreateNoWindow = false;
pro.Start();
pro.StandardInput.WriteLine(commandLine);
pro.StandardInput.AutoFlush = true;
pro.StartInfo.StandardErrorEncoding = Encoding.UTF8;
pro.StartInfo.StandardOutputEncoding = Encoding.UTF8;
outputMsg += pro.StandardOutput.ReadToEnd();
pro.WaitForExit();
pro.Close();
return outputMsg;
}
public static void CommitBundleToSvn()
{
string folderPath = EditorConst.BundlesPath + VEngine.Editor.Builds.Settings.GetPlatformName();
string command = "svn status " + folderPath;
string regaxPattern = ".*&exit";
string output = "";
string[] regexRes = {};
command = "svn st " + folderPath+ " | awk \"{if ($1 == \\\"?\\\") {print $2} }\"";
output = CmdHelper.StartCmd(command);
UnityEngine.Debug.LogError(command);
UnityEngine.Debug.LogError(output);
}
Execute command:
("svn st " + folderPath+ " | awk \"{if ($1 == \\\"?\\\") {print $2} }\"")
In windows cmd, cmd could get return message.
Now I call the CommitBundleToSvn(). but the cmd will not exit.
If the command is "svn status " + folderPath, it is expected.
Another option is to not use awk in this case, and do:
command = "svn st " + folderPath+ ";
output = CmdHelper.StartCmd(command);
output = string.Join("\r\n", output.Split("\r\n",StringSplitOptions.RemoveEmptyEntries)
.Where(x => x.Split(' ',StringSplitOptions.RemoveEmptyEntries)[0]
.Contains("?"))
.Select(s => s.Split(' ',StringSplitOptions.RemoveEmptyEntries)[1])
.ToList());
Related
My c# code
public static string RunRScript(string filePath, string rScriptExecutablePath, string args, int totalFiles,
int RowsInChunk, int TotalRows, string identity)
{
string rCodeFilePath = filePath; //RScriptPath.GetFilePath();
//string file = rCodeFilePath;
string result = string.Empty;
// IEnumerable<string> connections = _connections.GetConnections(identity)
try
{
var info = new ProcessStartInfo();
info.FileName = rScriptExecutablePath;
info.WorkingDirectory = Path.GetDirectoryName(rScriptExecutablePath);
info.Arguments = "\"" + rCodeFilePath + "\"" + " " + args;
info.RedirectStandardInput = false;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
info.CreateNoWindow = true;
string fileName = string.Empty;
DateTime startTime = DateTime.Now;
List<ProgressTracker> lstProgress = new List<ProgressTracker>();
ProgressTracker p;
using (var proc = new Process())
{
//proc.StartInfo.Verb = "runas";
for (int i = 1; i <= totalFiles; i++)
{
p = new ProgressTracker();
p.DT = DateTime.Now;
p.Progress = i;
lstProgress.Add(p);
info.Arguments = "\"" + rCodeFilePath + "\"" + " " + args + " " + i.ToString();
proc.StartInfo = info;
proc.Start();
proc.WaitForExit();
result = proc.StandardOutput.ReadToEnd();
p.TimeTaken = (DateTime.Now - p.DT).TotalSeconds;
Functions.SendProgress("Process in progress...", i, totalFiles, RowsInChunk, TotalRows, lstProgress, identity);
}
}
return FormatOutput(result);
}
catch (Exception ex)
{
throw new Exception("R Script failed: " + result, ex);
}
}
Now objects have values like
info.FileName = C:\Program Files\R\R-3.4.3\bin\Rscript.exe
info.WorkingDirectory = C:\Program Files\R\R-3.4.3\bin
info.Arguments = "C:\MANOJ R\Topic modelling v2\TM_Webapi\Honeywell.UOP.TopicModel.Api\Uploads\h481821\TopicSearch.R" h481821 1
But process is not creating and its not calling R script and even it doesn't throwing any exception
Even I tried running VS as admin but no luck!
I have changed the .exe file path from
C:\Program Files\R\R-3.4.3\bin\Rscript.exe
to
C:\Program Files\R\R-3.4.3\bin\x64\Rscript.exe
Since I am using 64 bit machine
Now the process is working
I'm having an issue where my cmd windows is just blank when executed from code. I've searched here and there for some solutions. And tried a few different things myself.
Running it with a normal .bat file works just fine.. But just not from my C# application.
Note: the ffmpeg is being run perfectly, but just not showing anything in the cmd window when executed from code.
image at the bottom.
I'll update this if I find a solution.. Unless you guys do it first ;)
Code:
private async void RunFfmpeg()
{
await Task.Run(() =>
{
String destFolder = null;
String sourceFolder = null;
int listCount = 0;
this.Dispatcher.Invoke(() =>
{
destFolder = textDest.Text;
sourceFolder = textSource.Text;
listCount = listFiles.Items.Count;
});
foreach (FileInfo fileC in listFiles.Items)
{
//Changing old extension to mp4
string oldFileName = fileC.ToString();
string newFileName = null;
string[] extension = oldFileName.Split('.');
newFileName = extension[0] + ".mp4";
string newDir = destFolder + "\\" + extension[0];
DirectoryInfo createDir = new DirectoryInfo(newDir);
if (!createDir.Exists)
{
createDir.Create();
}
//Gathering folders and all I need...
string output = "\"" + destFolder + "\\" + extension[0] + "\\" + newFileName + "\"";
string input = "\"" + sourceFolder + "\\" + oldFileName + "\"";
var startInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "cmd.exe",
//Arguments = $"-i {input} {output}",
Arguments = $"/c ffmpeg -i {input}" + " -c:a copy -c:v copy " + $"{output}",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = false,
WorkingDirectory = Directory.GetCurrentDirectory()
};
Process p = new Process();
p.StartInfo = startInfo;
p.OutputDataReceived += P_OutputDataReceived;
p.Start();
p.WaitForExit();
}
});
}
Here is where I read the output:
private void P_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
this.Dispatcher.Invoke(() =>
{
//string cmdBox = cmdOutput.Text;
//cmdOutput.AppendText(cmdBox);
//cmdOutput.Clear();
cmdOutput.AppendText(e.Data);
});
}
I need to write a small utility to rebuild solution. I am using below code to do the same.
string solutionFile = #"E:\Projects\TFS\Code\WebSite.sln";
string cmd1 = #"""C:\Program Files\Microsoft Visual Studio 11.0\VC\vcvarsall.bat"" x86" + " &devenv " + "\"" + solutionFile + "\"" + " /rebuild release";
cmd1 = "\"" + cmd1 + "\"";
String command = String.Format("{0} {1}", #"/k ", cmd1);
ProcessStartInfo cmdsi = new ProcessStartInfo("cmd.exe")
{
UseShellExecute = false,
RedirectStandardOutput = true
};
cmdsi.Arguments = command;
using (Process cmd = Process.Start(cmdsi))
{
using (StreamReader reader = cmd.StandardOutput)
{
string result = reader.ReadToEnd();
listBox1.Items.Add(result);
}
}
If you will observe in command prompt then you can see executions output but same thing is not getting reflected in list box.
Please help to solve this issue.
Thank you in advance.
You can redirect the output to a temporary file and then can read the file like-
string cmd1 = "help > e:/temp.txt"; //e:/temp.txt is temporary file where the output is redirected.
String command = String.Format("{0} {1}", #"/k ", cmd1);
ProcessStartInfo cmdsi = new ProcessStartInfo("cmd.exe")
{
//You don't need to read console outputstream
//UseShellExecute = false,
//RedirectStandardOutput = true
};
cmdsi.Arguments = command;
using (Process cmd = Process.Start(cmdsi))
{
//Check if file exist or you can wait till the solution builds completely. you can apply your logic to wait here.
if (File.Exists("E:/temp.txt"))
{
//Read the files here
string[] lines = File.ReadAllLines("E:/temp.txt");
//Do your work here
}
}
You can do it async:
string solutionFile = #"E:\Projects\TFS\Code\WebSite.sln";
string batFile = #"C:\Program Files\Microsoft Visual Studio 11.0\VC\vcvarsall.bat";
string args = "x86" + " &devenv " + "\"" + solutionFile + "\"" + " /rebuild release";
ProcessStartInfo cmdsi = new ProcessStartInfo(batFile)
{
Arguments = args,
UseShellExecute = false,
RedirectStandardOutput = true
};
using (Process cmd = new Process())
{
cmd.StartInfo = cmdsi;
cmd.OutputDataReceived += (sender, args) => listBox1.Items.Add(string.IsNullOrEmpty(args.Data) ? string.Empty : args.Data);
cmd.Start();
}
I am creating java compiler in c# .it is working perfect if there is no input.but it ask forstrong text input it give me error (Exception in thread "main" java.util.NoSuchElementException: No line found)
public void executeit()
{
adresss = "";
string dir = textBox1.Text;
adresss = dir;
ProcessStartInfo info = new ProcessStartInfo("cmd.exe");
info.CreateNoWindow = true;
string[] s = new string[30];
s = Directory.GetDirectories(#"C:\Program Files\Java\", "jdk1*");
info.WorkingDirectory = s[0] + #"\bin\";
info.Arguments = "/c javac " + "\"" + dir + "\"";
Process p = new Process();
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
label1.Text = "";
p.StartInfo = info;
p.Start();
StreamReader sw = p.StandardError;
string err = sw.ReadToEnd();
label1.Text = err;
if (label1.Text == "")
{
label1.Text = "Compiled without Errors";
}
}
and it is java file:
import java.util.Scanner;
public class inputtry {
public static void main (String args[]){
Scanner reader = new Scanner(System.in);
System.out.println("Enter the first number");
//get user input for a
String a=reader.nextLine();
System.out.print("number is:");
System.out.print(a);
}
}
I have a problem to execute uninstallString using process, it won't work in all cases.
I need a generic procedure that will run in any case.
one of my ideas was to parse uninstall string
Code:
int indexOfExe = uninstallString.ToLower().IndexOf(".exe") + 4;
string exeFile = uninstallString.Substring(0, indexOfExe).Trim();
string args = uninstallString.Substring(indexOfExe, uninstallString.Length - indexOfExe).Trim();
if (args.Length > 0)
{
procStartInfo.FileName = exeFile;
procStartInfo.Arguments = args;
}
else
{
procStartInfo.FileName = exeFile;
procStartInfo.Arguments = "";
}
procStartInfo.Verb = "runas";
procStartInfo.CreateNoWindow = true;
procStartInfo.UseShellExecute = false ;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
my second idea was:
Code:
if (uninstallString.Contains("msiexec"))
{
uninstallString = uninstallString.Replace("\"", "");
uninstallString = RegistryHandler.getCommandInCommaAndArgumentsOutside(uninstallString);
}
else
{
procStartInfo.FileName = "cmd";
string[] words = uninstallString.Split("/".ToCharArray());
if (uninstallString.StartsWith(#"""") && words.Count() == 1)
{
procStartInfo.FileName = uninstallString;
procStartInfo.Arguments = "";
}
else
{
//procStartInfo.Arguments = "/c " + "\"" + uninstallString + "\"";
if ((uninstallString.StartsWith(#"""") && words.Count() > 1))
{
procStartInfo.Arguments = "/c " + uninstallString;
}
else
{
procStartInfo.Arguments = "/c " + RegistryHandler.getCommandInCommaAndArgumentsOutsideByExe(uninstallString);
}
}
}
but still it won't cover all cases.
What is the generic solution for all cases?
Your second idea should, technically, work (for all programs using Windows Installer). However, you need to get the proper uninstall string. I suspect the problem is your Uninstall String is incorrect.
You should be able to query the registry for the Uninstall String by looking at:
HKLM\Software\Microsoft\Windows\Currentversion\Uninstall\{NameOfApplication}\UninstallString
The section above marked {NameOfApplication} should have an entry for all programs which can be uninstalled. For details, see the Uninstall Registry Key.
//i wrote this code, which is working in most of the cases :
//----------------------------------------------------------------------------------------------
if (uninstallString.Contains("msiexec"))
{
uninstallString = uninstallString.Replace("\"", "");
uninstallString = RegistryHandler.getCommandInCommaAndArgumentsOutside(uninstallString);
}
else
{
if (uninstallString.StartsWith(#""""))
{
int indexOfLastComma = uninstallString.IndexOf("\"", 1) + 1;
procStartInfo.FileName = uninstallString.Substring(0, indexOfLastComma);
procStartInfo.Arguments = uninstallString.Substrin(indexOfLastComma,uninstallString.Length - indexOfLastComma));
}
else
{
procStartInfo.FileName = "cmd.exe";
procStartInfo.Arguments = "/c " + RegistryHandler.getCommandInCommaAndArgumentsOutsideByExe(uninstallString);
}
}
//----------------------------------------------------------------------------------------------
public static string getCommandInCommaAndArgumentsOutsideByExe(string command)
{
int ind = 0;
string[] prms = command.Split(' ');
ind = prms[0].Length; //command.IndexOf(".exe") + 4;
int exeLocationIndex = command.IndexOf(".exe") + 4;
string cmd = command.Substring(0, exeLocationIndex);
string arguments = command.Substring(command.IndexOf(".exe") + 4, command.Length - exeLocationIndex);
return "\"" + cmd + "\"" + arguments;
}
Here is my code, using the same way as Roy did,perhaps a litter simpler:
private string SwitchCondition(string uninstallstring)
{
if (uninstallstring.Substring(0, 1).Equals("\"") |
uninstallstring.ToLower().Contains("msiexec") |
uninstallstring.Contains("~"))
{
Debug.WriteLine(uninstallstring);
}
else if (uninstallstring.ToLower().IndexOf(".exe") > 0)
{
uninstallstring = "\"" + uninstallstring.Insert(uninstallstring.ToLower().IndexOf(".exe") + 4, "\"");
Debug.WriteLine("Contains .exe" + uninstallstring);
}
else
{
uninstallstring = "\"" + uninstallstring + "\"";
Debug.WriteLine("Case end " + uninstallstring);
}
return uninstallstring;
}