Ghost script command dosent wait for WaitForExit() - c#

Hi guys im trying to execute gs command by creating a process and i want it to wait until the process is completed. I used waitforexit() but its surpassing waitforexit().
public async void pdf2Png(string name, string pdf, int lastPage)
{
Stopwatch stopwatch = Stopwatch.StartNew();
Response.Write((stopwatch.ElapsedMilliseconds / 1000) + " pdf 2 png" + "<br>");
Process obj_process = null;
ProcessStartInfo obj_startinfo = null;
StreamWriter obj_writer = null;
string sOutputFile = Path.Combine(Path.GetDirectoryName(pdf), name + "%d.png"); ;
string inputFilePath = pdf;
int lP = lastPage;
Response.Write(sOutputFile + " : " + inputFilePath + "<br>");
string str_command = string.Format("gswin64 -dSAFER -dBATCH -dNOPAUSE -dFirstPage=1 -dLastPage=\"{0}\" -sDEVICE=png16m -r600 -sOutputFile=\"{1}\" \"{2}\"",
lP, sOutputFile, inputFilePath);
obj_startinfo = new ProcessStartInfo("cmd.exe");
obj_startinfo.UseShellExecute = false;
obj_startinfo.RedirectStandardInput = true;
obj_startinfo.RedirectStandardError = true;
obj_startinfo.RedirectStandardOutput = true;
obj_startinfo.CreateNoWindow = true;
obj_startinfo.ErrorDialog = false;
obj_startinfo.WindowStyle = ProcessWindowStyle.Hidden;
obj_process = Process.Start(obj_startinfo);
obj_writer = obj_process.StandardInput;
obj_writer.WriteLine(str_command);
obj_writer.Flush();
obj_writer.Close();
obj_writer.Dispose();
obj_writer = null;
obj_process.WaitForExit();
System.IO.File.WriteAllText(#"D:\shits not working.txt", str_command);
stopwatch.Stop();
Response.Write((stopwatch.ElapsedMilliseconds / 1000) + " pdf 2 png" + "<br>");
}
the line below "Waitforexit()" gets executed even before the png gets created and exits the process. what can i do?

Related

C# StreamWrite to Process not executing on flush

I'm executing a jar file from a c# process. This is how I start the process and redirect the Input & Output. Problem indicated at the bottom!
Process process = new Process();
process.EnableRaisingEvents = false;
if (isLinux)
{
process.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory() + "/Servers/" + server.ServerLocation + "/";
}
else
{
process.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory() + "\\Servers\\" + server.ServerLocation + "\\";
}
process.StartInfo.FileName = "java";
process.StartInfo.Arguments = "-Xms" + server.AllocatedRam + "M -Xmx" + server.AllocatedRam + "M -jar " + '"' + path + '"';
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
LogController.Notice("Server Starting", server.Name);
proc = process;
process.Start();
if (Write.ContainsKey(server.ID))
{
Write.Remove(server.ID);
Write.Add(server.ID, process.StandardInput);
}
else
{
Write.Add(server.ID, process.StandardInput);
}
if (Output.ContainsKey(server.ID))
{
Output.Remove(server.ID);
Output.Add(server.ID, process.StandardOutput);
}
else
{
Output.Add(server.ID, process.StandardOutput);
}
Dictionaries
public static Dictionary<string, StreamWriter> Write = new Dictionary<string, StreamWriter>();
public static Dictionary<string, StreamReader> Output = new Dictionary<string, StreamReader>();
Executing command without closing writer
StreamWriter w = ServerController.Write[ID];
w.Write(Command.command);
w.Flush();
^ Flushing this will not execute the write. If I dispose the writer then I cannot execute more than 1 command. The writer has to always be open for writes and be able to execute the write but flushing does not work.

StandardOutput.ReadToEnd() always NULL

I have a problem with this function. It is supposed to output an install command to a textbox but install.StandardOutput.ReadToEnd() is always null.
I get the error: Expression cannot be evaluated because there is a native frame at the top of the call stack
Can you help me out with this?
Process install = new Process();
install.StartInfo.FileName = "cmd.exe";
install.StartInfo.UseShellExecute = false;
install.StartInfo.Arguments = "/all";
install.StartInfo.CreateNoWindow = true;
install.StartInfo.RedirectStandardInput = true;
install.StartInfo.RedirectStandardOutput = true;
install.Start();
if (CB_MultiADB.Checked == true)
{
install.StandardInput.WriteLine("FOR /F \"skip=1\" %%x IN ('adb devices') DO start cmd.exe #cmd /k" + InstallOption + InstallPfad + "\"");
}
else
{
install.StandardInput.WriteLine("adb install" + InstallOption + InstallPfad + "\"");
InstallAusgabe = install.StandardOutput.ReadToEnd();
string Index = "adb install";
int Indexnr = InstallAusgabe.IndexOf(Index);
string SubInstall = InstallAusgabe.Substring(Indexnr, 100);
TB_Ausgabe.Text = SubInstall;
}

How to send and receive numeric list from C# to Python?

I'm new to Python and I have to send some lists of double type from C# to Python and receive a list in return.
Here is the C# code:
private List<double> func_C(List<double> sampleX, List<double> sampleY, List<double> DBx, List<double> DBy)
{
var python = "python.exe";
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(python);
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardInput = true;
myProcessStartInfo.RedirectStandardOutput = true;
myProcessStartInfo.RedirectStandardError = true;
FileInfo pfile = new FileInfo(python);
var filename = "mypython.py";
DirectoryInfo directory = new DirectoryInfo(filename);
var filepath = directory.FullName;
myProcessStartInfo.Arguments = filepath
+ " " + sampleX
+ " " + sampleY
+ " " + DBx
+ " " + DBy;
Process myProcess = new Process();
myProcess.StartInfo = myProcessStartInfo;
FileInfo fileinfor = new FileInfo(filename);
myProcess.Start();
StreamReader myStreamReader = myProcess.StandardOutput;
sampleY.Clear();
string readum= string.Empty;
while((readum = myStreamReader.ReadLine())!= null)
sampleY.Add(Double.Parse(readum));
Console.WriteLine("runpython 5" + myProcess.StandardError.ReadToEnd());
myProcess.WaitForExit();
Console.WriteLine("runpython 6" + myProcess.StandardOutput.ReadToEnd());
myProcess.Close();
myProcess.Refresh();
return sampleY;
}
This my python code:
import sys
import numpy as np
XY = np.array(sys.argv[1], sys.argv[2])
XY2 = np.array(sys.argv[3], sys.argv[4])
# Some operations done
print(XY[1])
I received this error
XY = np.array(sys.argv[1], sys.argv[2])
TypeError: data type System.Collections.Generic.List`1[System.Double]
not understood
How to send lists to Python from C#?

when i use the gsutil in c# (diagnostics.process, cmd), it's does not end

I want to automate using gsutil in c #.
I use the "gsutil cp" command . If the file is small , the copied successfully . However, the file size is more than 10MB, the command is not end . I 've waited a long time , the command does not end .
This is my code.
String currentUser = Environment.UserName;
if (File.Exists(#"C:\Users\" + currentUser + #"\" + botoFileName) == false)
{
log.Error("can't find the confileFileName (" + botoFileName + ")");
return false;
}
log.Info("==========================================================");
log.Info("fileKey = " + fileKey);
string resultPro = null;
string resultError = null;
System.Diagnostics.ProcessStartInfo proInfo = new System.Diagnostics.ProcessStartInfo();
System.Diagnostics.Process pro = new System.Diagnostics.Process();
proInfo.FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe");
proInfo.CreateNoWindow = true;
proInfo.UseShellExecute = false;
proInfo.RedirectStandardOutput = true;
proInfo.RedirectStandardInput = true;
proInfo.RedirectStandardError = true;
pro.StartInfo = proInfo;
pro.Start();
pro.StandardInput.Write("c:" + Environment.NewLine);
pro.StandardInput.Write(#"set BOTO_PATH=C:\Users\" + currentUser + #"\" + botoFileName + Environment.NewLine);
if (usingCloudSdk.Equals("true"))
{
//when using google sdk and python
pro.StandardInput.Write(#"gsutil cp " + fileKey + " " + gcsPath + Environment.NewLine);
}
else
{
//when using only gsutil and python
pro.StandardInput.Write(#"cd C:\gsutil\gsutil" + Environment.NewLine);
pro.StandardInput.Write(#"python gsutil -m cp " + fileKey + " " + gcsPath + Environment.NewLine);
}
pro.StandardInput.Close();
resultPro = pro.StandardOutput.ReadToEnd();
resultError = pro.StandardError.ReadToEnd();
pro.WaitForExit();
pro.Close();
log.Info(resultPro);
log.Info(resultError);
log.Info("==========================================================");
if (resultError.IndexOf("Exception") != -1 || resultError.IndexOf("Fail") != -1)
{
return false;
}
return true;
please help me.

Merge videos in c# asp.net using ffmpeg

Is it possible to merge the two videos by c# asp.net with the help of ffmpeg. In the ffmpeg documentation they gave us cat command. But it wont works in asp.net. I thought it only for linux.
cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg
asp.net execute this command but there is no output. Help me.
namespace demo
{
public partial class Default : System.Web.UI.Page
{
protected void Button2_Click(object sender, EventArgs e)
{
string strFile = "cars1.flv";
MergeFiles(strFile);
}
public void MergeFiles(string strFile)
{
string strParam;
string Path_FFMPEG = Server.MapPath("~/ffmpeg/bin/ffmpeg.exe");
//Converting a video into mp4 format
string strOrginal = Server.MapPath("~/Videos/");
strOrginal = strOrginal + strFile;
string strConvert = Server.MapPath("~/Videos/ConvertedFiles/");
string strExtn = Path.GetExtension(strOrginal);
if (strExtn != ".mp4")
{
strConvert = strConvert + strFile.Replace(strExtn, ".mp4");
strParam = "-i " + strOrginal + " " + strConvert;
//strParam = "-i " + strOrginal + " -same_quant " + strConvert;
process(Path_FFMPEG, strParam);
}
//Merging two videos
String video1 = Server.MapPath("~/Videos/Cars1.mp4");
String video2 = Server.MapPath("~/Videos/ConvertedFiles/Cars2.mp4");
String strResult = Server.MapPath("~/Videos/ConvertedFiles/Merge.mp4");
//strParam = "-loop_input -shortest -y -i " + video1 + " -i " + video2 + " -acodec copy -vcodec mjpeg " + strResult;
strParam = " -i " + video1 + " -i " + video2 + " -acodec copy -vcodec mjpeg " + strResult;
process(Path_FFMPEG, strParam);
}
public void process(string Path_FFMPEG, string strParam)
{
try
{
Process ffmpeg = new Process();
ProcessStartInfo ffmpeg_StartInfo = new ProcessStartInfo(Path_FFMPEG, strParam);
ffmpeg_StartInfo.UseShellExecute = false;
ffmpeg_StartInfo.RedirectStandardError = true;
ffmpeg_StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo = ffmpeg_StartInfo;
ffmpeg_StartInfo.CreateNoWindow = true;
ffmpeg.EnableRaisingEvents = true;
ffmpeg.Start();
ffmpeg.WaitForExit();
ffmpeg.Close();
ffmpeg.Dispose();
ffmpeg = null;
}
catch (Exception ex)
{
}
}
}
}
Finally i found the answer for my own question.
The following method resolves my problem.
public void MergeFiles(string strFile)
{
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = Server.MapPath("~/app.bat");
p.Start();
p.WaitForExit();
p.Dispose();
}
app.bat
The app.bat contains the following code.
copy e:\cars1.mpg /b + e:\cars2.mpg /b e:\output.mpg /b
NOTE: This is for windows only. That's why "cat" command doesn't works. Instead of "cat" command we use copy command.
Creating app. Bat file double the file size but it play as single. Still problem not resolved. You should try ffmpeg concat command approach in which you need to create a text file that contain files names and this file should be on same folder where mp4 file are. the below code will help you i was facing the same issue. My task was to merge two mp4 files and I merge successfully when I was doing it from Command prompt. But stuck when I was doiing it through asp. Net. My issue resolved by given correct path and remove ffmpeg from command. For E. G( ffmepg - f concat TO - f concat)
Dim _ffmpeg As String = "D:\Develop\Experiment\mergermp4Vb\mergermp4Vb\bin\ffmpeg.exe"
Dim params = "-f concat -i D:\Develop\Experiment\mergermp4Vb\mergermp4Vb\Videos\mylist2.txt -c copy D:\Develop\Experiment\mergermp4Vb\mergermp4Vb\Videos\0104.mp4"
Dim _FFmpegProcessPropertys As New ProcessStartInfo
_FFmpegProcessPropertys.FileName = _ffmpeg
_FFmpegProcessPropertys.Arguments = params
_FFmpegProcessPropertys.UseShellExecute = False
_FFmpegProcessPropertys.RedirectStandardOutput = True
_FFmpegProcessPropertys.RedirectStandardError = True
_FFmpegProcessPropertys.CreateNoWindow = True
Dim FFmpegProcess = Process.Start(_FFmpegProcessPropertys)

Categories