I'm trying to edit a image file where instead of path i should be able to provide ImageSource as parameter.
//EditCode:
Process proc = Process.Start(Path);
proc.EnableRaisingEvents = true;
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Verb = "edit";
proc.StartInfo = startInfo;
proc.Exited += new EventHandler((s, e) => myProcess_Exited(s, e, obj.ToString()));
The above code works well when i pass the Path of the image file as the parameter. But now i have only the ImageSource.
//ImageSourceCode:
private BitmapFrame LoadImage(string path)
{
BitmapDecoder decoder = null;
if (File.Exists(path) && (path != null))
{
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
return decoder.Frames.FirstOrDefault();
}
else
return null;
}
The above code gets the path and convert an image as a source(BitmapFrame) and returns it.
Now i need this BitmapFrame to be passed in some function and edit the particular image file in paint and save it.
I neeed somthing like this,
Process proc = Process.Start(`ImageSource`);// Instead of path i need to pass the Image Source.
proc.EnableRaisingEvents = true;
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Verb = "edit";
proc.StartInfo = startInfo;
How can i achieve this?
You can't.
ProcessStartInfo starts a new process that is outside the App Domain of your application. You can't pass it structures in memory within your app domain as a command line parameter.
Related
The problem is the following. I need to convert a video to a set of pictures using the ffmpeg process. I have successfully done this before with the following code:
public void VideoToImages1()
{
var inputFile = #"D:\testVideo.avi";
var outputFilesPattern = #"D:\image%03d.jpg";
using var process = new Process
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = false,
CreateNoWindow = true,
Arguments = $"-y -i {inputFile} {outputFilesPattern}",
FileName = "ffmpeg.exe"
},
EnableRaisingEvents = true
};
process.Start();
process.WaitForExit();
}
Now I need to stream video through the input Stream and receive data from the output Stream. For this I have the following code. It's fully working since I used it to convert video and successfully streamed input via Stream and received output via Stream and produced a valid file.
public void VideoToImages2()
{
var inputFile = #"D:\testVideo.avi";
var outputFile = #"D:\resultImages.png";
var process = new Process
{
StartInfo = new ProcessStartInfo
{
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
Arguments = "-y -i - -f image2 -",
FileName = _ffmpeg
},
EnableRaisingEvents = true
};
process.Start();
//Write input data to input stream
var inputTask = Task.Run(() =>
{
using (var input = new FileStream(inputFile, FileMode.Open))
{
input.CopyTo(process.StandardInput.BaseStream);
process.StandardInput.Close();
}
});
//Read multiple files from output stream
var outputTask = Task.Run(() =>
{
//Problem here
using (var output = new FileStream(outputFile, FileMode.Create))
process.StandardOutput.BaseStream.CopyTo(output);
});
Task.WaitAll(inputTask, outputTask);
process.WaitForExit();
}
The problem here is that instead of creating files in a directory according to the specified pattern, it returns these files in a stream. As a result, I do not know how to write all the files from the Stream and how to process this output, since it contains many files. At the moment I have only 1 image created.
Help me please.
I tried googling but didn't find anything useful
You will have to decode the stream on the fly using the signatures of the output files. Any file has a unique signature and by recognizing these signatures you can keep track of the number of bytes related to this file. For example jpeg file starts with signature 0xFF 0xD8 0xFF and ends with signature 0xF9 xF8 if I'm not mistaken. Matching bytes with these signatures will have to find the files contained in the stream.
I'm trying to learn how C# could read and parsing multiple line from text file using streamReader and afterward process each of line with PSExec
Inside cocomand.txt have multiple line example
c:/command1.cmd
c:/command2.bat
c:/command3.cmd
private static void calleachline()
{
string pathx = #"c:\cocomand.txt";
using (StreamReader reader = new StreamReader(new FileStream(pathx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.ASCII))
{
while ((!reader.EndOfStream))
{
System.Diagnostics.Process cmd = new System.Diagnostics.Process();
cmd.StartInfo.FileName = #"psexec.exe";
cmd.StartInfo.Arguments = #"\\localhost";
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.Start();
if (!cmd.WaitForExit(cmd2))
{
ExecutePSKill(cmd);
}
else
{
//
}
}
}
Trying to understand from few thread but with my lack knowledge seems this still doesn't work
I am starting a cmd.exe from my c# application and redirect its inputstream.This works fine for normal chars like "abc" But when i try to redirect chars like "äöüßáàâ" in the consolewindow appears "õ÷³óô".
Process myProcess = new Process();
myProcess.StartInfo.FileName = "cmd.exe";
myProcess.StartInfo.Arguments = "/K";
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.StartInfo.WorkingDirectory = #"c:\";
myProcess.Start();
StreamWriter myStreamWriter = myProcess.StandardInput;
myStreamWriter.WriteLine("äöüßáàâ");
myStreamWriter.Encoding says its encoding is codepage 1252 i tryed to convert my string into it but it didnt change the result.
How to convert my string that it is shown correct?
I took the code and ran the same.. When I didnt redirect the output, I saw the same as the OP. However
Process myProcess = new Process();
myProcess.StartInfo.FileName = "cmd.exe";
myProcess.StartInfo.Arguments = "/K";
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.RedirectStandardInput = true;
//myProcess.StartInfo.StandardOutputEncoding = Encoding.UTF32;
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.WorkingDirectory = #"c:\";
myProcess.Start();
StreamWriter myStreamWriter = myProcess.StandardInput;
StreamReader myStreamReader = myProcess.StandardOutput;
myStreamWriter.WriteLine("äöüßáàâ");
richTextBox1.Text = myStreamReader.ReadToEnd();
This produced c:\>äöüßáàâ as expected in the text box.. even though it didnt seem to show it as right in the console window that showed.
How can I open a constant byte stream that I can read while it's playing? I am able to get a single image with a resolution of 100:75, but when I bump up the resolution the process never finishes.
I need help improving the performance this method, I'm sure it's possible but I know very little about FFmpeg.
I'd like to be able to:
List item
Get a full res image
Read while the process is running
Constantly read byte output from a live stream
This is how I get the single image, it's running on a background thread.
string stream = "-i " + url + " -vf scale=100:75 -an -vframes 1 -r 1 -f image2pipe pipe:bmp";
var process = new Process();
process.StartInfo.FileName = ffmpeg.exe;
process.StartInfo.Arguments = stream;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForExit();
Stream outputReader = process.StandardOutput.BaseStream;
byte[] buffer = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = outputReader.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(ms.ToArray());
bitmapImage.EndInit();
bitmapImage.Freeze();
Image = bitmapImage;
}
When i am adding service to windows manually by typing in CMD something like this:
"C:\Program Files (x86)\Windows Resource Kits\Tools\instsrv.exe" "some-pl-char-ąźńćńół" "C:\Program Files (x86)\Windows Resource Kits\Tools\srvany.exe"
... everything is good with service name, but when i try do that in c#:
ProcessStartInfo startInfo = new ProcessStartInfo();
Process myprocess = new Process();
startInfo.FileName = "cmd";
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
myprocess.StartInfo = startInfo;
myprocess.Start();
StreamWriter sw = myprocess.StandardInput;
StreamReader sr = myprocess.StandardOutput;
Thread.Sleep(200);
string command = ...
^ "C:\Program Files (x86)\Windows Resource Kits\Tools\instsrv.exe" "some-pl-char-ąźńćńół" "C:\Program Files (x86)\Windows Resource Kits\Tools\srvany.exe"
sw.WriteLine(command);
sw.WriteLine("exit");
Thread.Sleep(200);
sw.Close();
sr.Close();
then name of created service is: some-pl-char-¦č˝Š˝ˇ-
Why there is problem with code page?
There is something like StandardInputEncoding for ProcessStartInfo?
My active code page in CMD (using chcp) is 852. (Polish)
Arguments belongs assigned to the Arguments property and backslashes needs to be escaped by another one. \ -> \\
Updated:
using (var process = new Process())
{
var encoding = Encoding.GetEncoding(852);
var psi = new ProcessStartInfo();
psi.FileName = "cmd";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.StandardOutputEncoding = encoding;
process.StartInfo = psi;
process.Start();
using (var sr = process.StandardOutput)
using (var sw = new StreamWriter(process.StandardInput.BaseStream, encoding))
{
var command = "....";
sw.WriteLine(command);
// etc..
}
}
I had a very similar issue. Although I was working with VB.net, it fixed my issue. I couldnt run the command unless this was set.
startInfo.FileName = "cmd.exe /c";
instead of
startInfo.FileName = "cmd";