FFMPEG C# Winforms Output to Textbox - c#

Trying to write a video compression app using Windows Forms, I can get the file to compress ok, but I'm looking to show the process to something like a textbox?
At the minute the program doesn't have a progress, so you don't know if its complete or not, is it possible to output with FFMPEG is doing to a textbox?
This is my code, when it runs nothing is shown in the textbox:
string ffmpeg = #"c:\test\ffmpeg.exe";
ProcessStartInfo psi = new ProcessStartInfo(ffmpeg);
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardOutput = true;
psi.Arguments = "-i c:\\test\\small.mp4 -s 480x272 c:\\test\\compressed.mp4";
var proc = Process.Start(psi);
string s = proc.StandardOutput.ReadToEnd();
textBox1.Text = s;
Do i need to pass something else into the ProcessStartInfo section?

You need to periodically check back with proc.StandardOutput to see if there is new text there. Right immediately after you've started the program, it's no surprise that it hasn't managed to write anything yet.
I'd advise using a Timer for that.

Related

Process.Start from .txt file to textbox

I'm trying to solve a problem i got. My job is to make little app, that will show text which is inside of .txt file in the app window, but for some reason they told me that i have to use # ShellExecute(use Process.Start).
Is there even a way to do it? Because when i use ShellExecute, that file opens in notepad after button press, which is, I guess, point of using Shell.
There is little code of what i tried to do, but without success.
Thanks in advice!
string filePath = #"C:\Folder\file.txt";
ProcessStartInfo psi = new ProcessStartInfo(filePath);
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.CreateNoWindow = true;
var proc = Process.Start(psi);
string s = proc.StandardOutput.ReadToEnd();
textBox1.Text = s;
Instead of using ProcessStartInfo, try StreamReader like this :
string filePath = #"C:\Folder\file.txt";
StreamReader sr = new StreamReader(filePath);
string s = sr.ReadToEndAsync().GetAwaiter().GetResult();
Console.WriteLine(s);
Use Async method to read all text without blocking.
If you absolutely need to do that, you can create a second application TxtToTextBox, which you can run from your first application using Process.Start (initialize ProcessStartInfo with the path to that application instead of the txt file).
Then you can give that process an argument pointing to the file using psi.Arguments = $"\"{filePath}\"; (this also adds quotation marks around your path, so spaces are escaped).
Then in your second application you can do the sane thing, and simply read the file with File.ReadAllLines(args[0]) and print that into your text box.
If possible, I would recommend talking to whoever told you to use Process.Start and asking them for more reasons as to why you should use is, as this is one of the most roundabout ways to do this I could think of.

C# How to start .bat File with the normal Behaviour of Windows

I created this simple .bat File:
mstsc C:\Temp\example.rdp
DEL C:\Temp\example.rdp
The normal behaviour of the .bat file is to open the rdp dialog and wait til I close the RDP connection. After that the .rdp file will be deleted.
This works perfect for me.
Now I want to open the .bat file from my C# WPF project with a click on a button.
Process p = new Process();
p.StartInfo.FileName = #"cmd.exe";
p.StartInfo.WorkingDirectory = #"C:\Temp";
p.StartInfo.Arguments = "/k " + "example.bat";
p.Start();
I tried all different arguments but the result is always the same the .bat file won't wait for the mstsc command to finish.
Do you have an idea to get this work?
Edit:
I want the .bat file because i want to delete the .rdp file although my program isn't running and i don't want to close all rdp connections when i close the program.
Why are you not directly running mstsc?
Process.Start("mstsc", "dir-to-blah.rdp").WaitForExit();
File.Delete("dir-to-blah.rdp");
try using the "start" command.
start is documented here: https://ss64.com/nt/start.html
you should be able to do something like
Process p = new Process();
p.StartInfo.FileName = #"cmd.exe";
p.StartInfo.WorkingDirectory = #"C:\Temp";
p.StartInfo.Arguments = "start /w" + "/k " + "example.bat";
p.Start();
(as usual, my code is completely untested - leaving the final solution up to the OP)

Print PDF hidden from user

I have a PDF printed from C# with this code:
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "printto";
info.FileName = segnToPrint;
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.Arguments = "\""+ stmp+ "\"";
Process p = new Process();
p.StartInfo = info;
p.Start();
p.EnableRaisingEvents = true;
p.WaitForInputIdle();
System.Threading.Thread.Sleep(1000);
// Close Acrobat regardless of version
if (p != null)
{
p.WaitForInputIdle();
p.CloseMainWindow();
}
stmp is the address of the printer. The print works fine and it's perfect but i see the windows of Acrobat Reader any time that i call this function and the page of Acrobat Reader remains open after the last file printed.
How can i hidden all the process to the user?
If you are looking to hide some window then you may try move its window left and top position outside the screen using SetWindowPos function (see C# code here).
But please be aware of user interactions as user could be confused by the program running in the taskbar but not available on desktop.
Unfortunately (as you have found) acrobat reader will always open a window. If you wish to silently print without ever seeing acrobat then the only approach would be to use something other than acrobat reader. Two possible options are to use another PDF reader like FoxIt or to try to send your PDF directly to the printer in raw form, getting round the need for 3rd party applications all-together.

Progress Bar for each process

I'm currently busy with a small C# application that reads a folder then dynamically lists all .rar files on a windows form with a dynamic progress bar next to each .rar file. So basically with the press of a button, the .rar files needs to be unzipped (winrar command line) showing the progress for each process.
Below is my process snippet
Process proc = new Process();
proc.StartInfo.FileName = #"unrar.exe";
proc.StartInfo.Arguments = FileName + "whatever attributes/switches";
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
Having trouble getting this right.
Help will be much appreciated.
If unrar.exe outputs the progress to the standard output, you could try and parse it to update the progressbar.
Instead of using unrar.exe to uncompress the archives from within your program, you could try using a library, like SevenZipLib http://sevenziplib.codeplex.com/.
The problem may be that UNRAR doesn't output a NewLine, and just keeps writing to the same line, so the event handler never gets called. It only gets called once a new line is written.
I would go with Simon's solution and try to use 7zip instead. It's more friendly has a great C# library and works with almost all formats.

Is there a way to have a batch file run within a windows form application in C#?

So anyways, I've been working on a batch IDE, and I was wondering if there was a good way to effectively embed the file into the form.
It would function sort of like a debug mode, where at any time, the user can click a button, and the batch file would load into the actual form.
Like the black cmd window would be embedded into the form...
Is there any way to do that?
ProcessStartInfo psi = new ProcessStartInfo();
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.FileName = "C:\\echo.cmd";
var p = Process.Start(psi);
Console.WriteLine(p.StandardOutput.ReadToEnd());
And in C:\echo.cmd I have just basic echo hello!. When this code is executed - you'll see hello! received from batch's output stream.
Note that if executed command will wait for some input - ReadToEnd() can't return. In this case you should use Process.OutputDataReceived event.
Look at the process object and the StandardInput, StandardOutput and StandardError streams.
That is essentially all the command window is showing with some special handling of control characters.

Categories