How to Backup/Restore PostgreSQL using code? - c#

i have tried this method but it doesn't working anyone can correct it or share some tutorial for Backup/Restore PostgreSQL using VB.NET
and these methods are using to backup/restore
here commandType = pg_dump and commandSentence = -i -h localhost -p 5432 -U postgres -F c -b -v -f C:\Documents and Settings\GDS\Desktop\backup\RStar.backup RStar
but returns nothing in the folder where i am trying to place the backup file
private void executeCommand(string commandType,string commandSentence )
{
try
{
System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo();
info.FileName = "C:\\Program Files\\PostgreSQL\\9.2\\bin\\" + commandType + ".exe ";
info.Arguments = commandSentence;
info.CreateNoWindow = true ;
info.UseShellExecute = false;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = info;
proc.Start();
proc.WaitForExit();
if (commandType == "pg_dump")
toolStripStatusLabel1.Text = "Backup successfuly created";
else if (commandType == "pg_restore")
toolStripStatusLabel1.Text = "Restore successfuly executed";
else if(commandType=="shp2pgsql")
toolStripStatusLabel1.Text = "Your selected shape file successfuly transfered to PostGIS";
else if (commandType == "pgsql2shp")
toolStripStatusLabel1.Text = "Your selected layer from PostGIS successfuly converted to shape file";
}
catch (Exception ex)
{
toolStripStatusLabel1.Text = ex.ToString();
}
}

Just to enhance byte response and Working with Net Core 3.1 Linux and Windows System
You could use PGPASSWORD instead PGPASSFILE, so you can omit create a intermediate file for credentials.
For linux you need to consider how to run sh script in linux with Process:
Shell Script File(.sh) does not run from c# core on linux
To set a variable in linux you should use export instead set.
Here my example for Restore database in linux and windows OS system (Net Core 3.1):
string Set = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "set " : "export ";
public async Task PostgreSqlRestore(
string inputFile,
string host,
string port,
string database,
string user,
string password)
{
string dumpCommand = $"{Set}PGPASSWORD={password}\n" +
$"psql -h {host} -p {port} -U {user} -d {database} -c \"select pg_terminate_backend(pid) from pg_stat_activity where datname = '{database}'\"\n" +
$"dropdb -h " + host + " -p " + port + " -U " + user + $" {database}\n" +
$"createdb -h " + host + " -p " + port + " -U " + user + $" {database}\n" +
"pg_restore -h " + host + " -p " + port + " -d " + database + " -U " + user + "";
//psql command disconnect database
//dropdb and createdb remove database and create.
//pg_restore restore database with file create with pg_dump command
dumpCommand = $"{dumpCommand} {inputFile}";
await Execute(dumpCommand);
}
Execute Method
private Task Execute(string dumpCommand)
{
return Task.Run(() =>
{
string batFilePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}." + (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "bat" : "sh"));
try
{
string batchContent = "";
batchContent += $"{dumpCommand}";
File.WriteAllText(batFilePath, batchContent, Encoding.ASCII);
ProcessStartInfo info = ProcessInfoByOS(batFilePath);
using System.Diagnostics.Process proc = System.Diagnostics.Process.Start(info);
proc.WaitForExit();
var exit = proc.ExitCode;
... ommit error handler code ...
proc.Close();
}
catch (Exception e)
{
// Your exception handler here.
}
finally
{
if (File.Exists(batFilePath)) File.Delete(batFilePath);
}
});
}
ProcessInfoByOS Method
private static ProcessStartInfo ProcessInfoByOS(string batFilePath)
{
ProcessStartInfo info;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
info = new ProcessStartInfo(batFilePath)
{
};
}
else
{
info = new ProcessStartInfo("sh")
{
Arguments = $"{batFilePath}"
};
}
info.CreateNoWindow = true;
info.UseShellExecute = false;
info.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
info.RedirectStandardError = true;
return info;
}
And here the Dump Method
public async Task PostgreSqlDump(
string outFile,
string host,
string port,
string database,
string user,
string password)
{
string dumpCommand =
$"{Set}PGPASSWORD={password}\n" +
$"pg_dump" + " -Fc" + " -h " + host + " -p " + port + " -d " + database + " -U " + user + "";
string batchContent = "" + dumpCommand + " > " + "\"" + outFile + "\"" + "\n";
if (File.Exists(outFile)) File.Delete(outFile);
await Execute(batchContent);
}

Method for dump (where pgDumpPath is path to pg_dump.exe and outFile is output file path):
public void PostgreSqlDump(
string pgDumpPath,
string outFile,
string host,
string port,
string database,
string user,
string password)
{
String dumpCommand = "\"" + pgDumpPath + "\"" + " -Fc" + " -h " + host + " -p " + port + " -d " + database + " -U " + user + "";
String passFileContent = "" + host + ":" + port + ":" + database + ":" + user + ":" + password + "";
String batFilePath = Path.Combine(
Path.GetTempPath(),
Guid.NewGuid().ToString() + ".bat");
String passFilePath = Path.Combine(
Path.GetTempPath(),
Guid.NewGuid().ToString() + ".conf");
try
{
String batchContent = "";
batchContent += "#" + "set PGPASSFILE=" + passFilePath + "\n";
batchContent += "#" + dumpCommand + " > " + "\"" + outFile + "\"" + "\n";
File.WriteAllText(
batFilePath,
batchContent,
Encoding.ASCII);
File.WriteAllText(
passFilePath,
passFileContent,
Encoding.ASCII);
if (File.Exists(outFile))
File.Delete(outFile);
ProcessStartInfo oInfo = new ProcessStartInfo(batFilePath);
oInfo.UseShellExecute = false;
oInfo.CreateNoWindow = true;
using (Process proc = System.Diagnostics.Process.Start(oInfo))
{
proc.WaitForExit();
proc.Close();
}
}
finally
{
if (File.Exists(batFilePath))
File.Delete(batFilePath);
if (File.Exists(passFilePath))
File.Delete(passFilePath);
}
}

public void { BackupDatabase(server,port, user,password, dbname, "backupdir", dbname, "C:\\Program Files\\PostgreSQL\\11\\bin\\");
}
public static string BackupDatabase(
string server,
string port,
string user,
string password,
string dbname,
string backupdir,
string backupFileName,
string backupCommandDir)
{
try
{
Environment.SetEnvironmentVariable("PGPASSWORD", password);
string backupFile = backupdir + backupFileName + "_"+DateTime.Now.ToString("yyyy") + "_" + DateTime.Now.ToString("MM") + "_" + DateTime.Now.ToString("dd") + ".backup";
string BackupString = " -f \"" + backupFile + "\" -F c"+
" -h " + server + " -U " + user + " -p " + port + " -d " + dbname;
Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = backupCommandDir + "\\pg_dump.exe";
proc.StartInfo.Arguments = BackupString;
proc.StartInfo.RedirectStandardOutput = true;//for error checks BackupString
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;//use for not opening cmd screen
proc.StartInfo.CreateNoWindow = true;//use for not opening cmd screen
proc.Start();
proc.WaitForExit();
proc.Close();
return backupFile;
}
catch (Exception ex)
{
return null;
}
https://sagartajpara.blogspot.com/2017/03/postgres-database-backup-in-c.html

public void Backup()
{
try
{
DateTime Time = DateTime.Now;
int year = Time.Year;
int month = Time.Month;
int day = Time.Day;
int hour = Time.Hour;
int minute = Time.Minute;
int second = Time.Second;
int millisecond = Time.Millisecond;
//Save file to C:\ with the current date as a filename
string path;
path = "D:\\" + year + "-" + month + "-" + day + "-" + hour + "-" + minute + ".sql";
StreamWriter file = new StreamWriter(path);
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "mysqldump";
psi.RedirectStandardInput = false;
psi.RedirectStandardOutput = true;
psi.Arguments = string.Format(#"-u{0} -p{1} -h{2} {3}", uid, password, server, database);
psi.UseShellExecute = false;
Process process = Process.Start(path);
string output;
output = process.StandardOutput.ReadToEnd();
file.WriteLine(output);
process.WaitForExit();
file.Close();
process.Close();
}
catch (IOException ex)
{
MessageBox.Show("Error , unable to backup!");
}
}

Related

Mono: how to run a bash command on a new console/terminal window?

How can I run a bash command using Mono (System.Diagnostics.Process) in a new console/terminal window? It works fine on Windows, where a new console window is opened to run the command. On Linux and macOS, the command runs on the same terminal window which I've used to open the app. I've tried all CreateNoWindow/UseShellExecute combinations but none of them worked for me.
Edit: here's the code:
var startInfo = new ProcessStartInfo();
switch (ThermoCS.PlatformCheck.RunningPlatform())
{
case ThermoCS.PlatformCheck.Platform.Windows:
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.FileName = Environment.CurrentDirectory + "\\ThermoCS\\" + item.Key + ".exe";
if (item.Key.Contains("1"))
{
startInfo.Arguments = Model;
}
else
{
startInfo.Arguments = Model + " " + MixRule;
}
break;
case ThermoCS.PlatformCheck.Platform.Linux:
startInfo.WorkingDirectory = Environment.CurrentDirectory;
var ldc = "LD_LIBRARY_PATH=" + Environment.CurrentDirectory + "/ThermoCS/; export LD_LIBRARY_PATH";
//startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "/bin/bash";
if (item.Key.Contains("1"))
{
startInfo.Arguments = "-c \" " + ldc + " && chmod +x ThermoCS/" + item.Key + " && ./ThermoCS/" + item.Key + " " + Model + " \"";
}
else
{
startInfo.Arguments = "-c \" " + ldc + " && chmod +x ThermoCS/" + item.Key + " && ./ThermoCS/" + item.Key + " " + Model + " " + MixRule + " \"";
}
break;
case ThermoCS.PlatformCheck.Platform.Mac:
var basedir = Directory.GetParent(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).Parent.FullName;
var ldcosx = "export DYLD_LIBRARY_PATH=" + basedir + "/Contents/MonoBundle/ThermoCS/";
startInfo.WorkingDirectory = basedir;
//startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "/bin/bash";
if (item.Key.Contains("1"))
{
startInfo.Arguments = "-c \" " + ldcosx + " && chmod +x Contents/MonoBundle/ThermoCS/" + item.Key + " && ./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model + " \"";
}
else
{
startInfo.Arguments = "-c \" " + ldcosx + " && chmod +x Contents/MonoBundle/ThermoCS/" + item.Key + " && ./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model + " " + MixRule + " \"";
}
break;
}
Process proc = Process.Start(startInfo);
As I've described above, the command runs just fine. The problem is that on Linux and macOS it does on the same terminal window which owns the currently running app. I want it to run on a new terminal window.
Thanks in advance!
What I did was I wrote a simple bash script that I placed in my Debug/Release/Whatever folder (folder of the executable of C# program.) Lets call the bash script, first.sh
In this bash folder, I would call another bash from another directory, the bash I was looking to run initially. Lets call this bash script, second.sh
In my C# code I will call first.sh like this:
string command = string.Format("{0}", "./first.sh");
Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "gnome-terminal";
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.RedirectStandardInput = false;
proc.StartInfo.RedirectStandardOutput = false;
proc.StartInfo.Arguments = " -e \" " + command + " \"";
proc.Start();
My first.sh would change to the directory where my second.sh is:
#!/bin/sh
# This is a comment!
echo hello world # This is just a test to see if it is being called
cd ~
cd home/scripts
(exec "./second")
This whole process would physically open up a new terminal and execute commands within it from C# code.
Here is a good tutorial on how to write bash scripts: tutorial on bash scripting in linux
I've found the solution by myself. It involves saving the commands in a script file, making it executable and calling xterm on Linux or Terminal.app on macOS:
var startInfo = new ProcessStartInfo();
switch (ThermoCS.PlatformCheck.RunningPlatform())
{
case ThermoCS.PlatformCheck.Platform.Windows:
startInfo.WorkingDirectory = Environment.CurrentDirectory;
startInfo.FileName = Environment.CurrentDirectory + "\\ThermoCS\\" + item.Key + ".exe";
if (item.Key.Contains("1"))
{
startInfo.Arguments = Model;
}
else
{
startInfo.Arguments = Model + " " + MixRule;
}
break;
case ThermoCS.PlatformCheck.Platform.Linux:
startInfo.WorkingDirectory = Environment.CurrentDirectory;
var ldc = "LD_LIBRARY_PATH=" + Environment.CurrentDirectory + "/ThermoCS/; export LD_LIBRARY_PATH";
var scriptl = new StringBuilder();
scriptl.AppendLine("#!/bin/bash");
scriptl.AppendLine("cd '" + Environment.CurrentDirectory + "'");
scriptl.AppendLine(ldc);
scriptl.AppendLine("chmod +x ThermoCS/" + item.Key);
if (item.Key.Contains("1"))
{
scriptl.AppendLine("./ThermoCS/" + item.Key + " " + Model);
}
else
{
scriptl.AppendLine("./ThermoCS/" + item.Key + " " + Model + " " + MixRule);
}
var filepathl = Path.GetTempFileName();
File.WriteAllText(filepathl, scriptl.ToString());
Process.Start("/bin/bash", "-c \" chmod +x " + filepathl + " \"");
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "xterm";
startInfo.Arguments = "-e '" + filepathl + "'";
break;
case ThermoCS.PlatformCheck.Platform.Mac:
var basedir = Directory.GetParent(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)).Parent.FullName;
var ldcosx = "export DYLD_LIBRARY_PATH=" + basedir + "/Contents/MonoBundle/ThermoCS/";
var script = new StringBuilder();
script.AppendLine("#!/bin/bash");
script.AppendLine("cd '" + basedir + "'");
script.AppendLine(ldcosx);
script.AppendLine("chmod +x Contents/MonoBundle/ThermoCS/" + item.Key);
if (item.Key.Contains("1"))
{
script.AppendLine("./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model);
}
else
{
script.AppendLine("./Contents/MonoBundle/ThermoCS/" + item.Key + " " + Model + " " + MixRule);
}
var filepath = Path.GetTempFileName();
File.WriteAllText(filepath, script.ToString());
Process.Start("/bin/bash", "-c \" chmod +x " + filepath + " \"");
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "open";
startInfo.Arguments = "-a Terminal.app " + filepath;
break;
}
Process proc = Process.Start(startInfo);

process.BasePriority threw an Exception of Type 'System.InvalidOperationException'

When I am trying to start a process from web API locally its started successfully but when I am hosting it to IIS 7.5 and try to start that process there is no response I am getting. when I tried to debug attaching the process to visual studio and start a debug I seen this error Process's BaseProperty
process.BasePriority threw an Exception of Type 'System.InvalidOperationException'
I am starting a process to start a cmd.exe and here is the code:
public static void Start(long campaign_id, long contact_id, string startDate, string endDate, string user)
{
try
{
//WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.WorkingDirectory = #"C:\";
startInfo.Arguments = "/c sparkclr-submit --master " + ConfigurationManager.AppSettings["SparkMaster"] + " --driver-class-path " + AppDomain.CurrentDomain.BaseDirectory + "Engine\\mysql.jar " + "--exe CmAnalyticsEngine.exe " + AppDomain.CurrentDomain.BaseDirectory + "Engine " + campaign_id + " " + contact_id + " " + startDate + " " + endDate + " " + user;
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.LoadUserProfile = true;
//startInfo.Verb = "runas";
process.StartInfo = startInfo;
process.Start();
if (!process.HasExited)
{
Console.WriteLine("process is running");
}
else
{
Console.WriteLine("process is stopped");
}
}
catch (Exception e)
{
LogWritter.WriteErrorLog(e);
}
}
when I am running this locally it works properly but on IIS its printing msg Process is stopped.
do I need to give permission to cmd.exe to start from IIS? if yes then how to do it?
Any help will be most appreciated.
Thanks
This error means the process has exited.-or- The process has not started, so there is no process ID.
public static void Start(long campaign_id, long contact_id, string startDate, string endDate, string user)
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.WorkingDirectory = #"C:\";
startInfo.Arguments = "/c sparkclr-submit --master " + ConfigurationManager.AppSettings["SparkMaster"] + " --driver-class-path " + AppDomain.CurrentDomain.BaseDirectory + "Engine\\mysql.jar " + "--exe CmAnalyticsEngine.exe " + AppDomain.CurrentDomain.BaseDirectory + "Engine " + campaign_id + " " + contact_id + " " + startDate + " " + endDate + " " + user;
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.LoadUserProfile = true;
//startInfo.Verb = "runas";
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
if (!process.HasExited)
{
Console.WriteLine("process is running");
}
else
{
Console.WriteLine("process is stopped");
}
}
catch (Exception e)
{
LogWritter.WriteErrorLog(e);
}
}
Hope it helps.

windres: The filename, directory name, or volume label syntax is incorrect

I'm using windows 10.
I'm trying to compile a c++ file within c# using MinGW(the MinGW folder is in the projects directory), but it won't compile a resource script (using windres).
Whenever I use windres in cmd it says: "C:/Users/username/AppData/Local/Temp/my.rc:1: unrecognized escape sequence".
but still works.
But when I run the exact same command through c# (by creating a process) it doesn't work at all and says: "The filename, directory name, or volume label syntax is incorrect.".
My code:
String tempDir = Path.GetTempPath();
String file = tempDir + "my.rc";
using (StreamWriter writer = new StreamWriter(file, false, Encoding.ASCII))
{
if (!textIcon.Text.Equals(""))
await writer.WriteLineAsync("25 ICON \"" + textIcon.Text + "\"");
if (checkAdmin.Checked)
{
String manifest = tempDir + #"\manifest.xml";
createManifest(manifest);
await writer.WriteLineAsync("55 24 \"" + manifest + "\"");
}
}
String args2 = "/c \"" + Path.Combine(gccLocation, "windres.exe") + "\" -o \"" + Path.Combine(tempDir, "my.o").Replace("\\", "/") + "\" \"" + file.Replace("\\", "/") + "\"";
//Debug
//args2 = "/k echo " + args2;
ProcessStartInfo psi2 = new ProcessStartInfo();
psi2.FileName = "CMD.exe";
psi2.Arguments = args2;
psi2.UseShellExecute = false;
psi2.CreateNoWindow = true;
//Debug
//psi2.CreateNoWindow = false;
Process windres = Process.Start(psi2);
windres.WaitForExit();
if(windres.ExitCode != 0)
{
MessageBox.Show("Error: Could not create resource file (" + windres.ExitCode + ")");
}
Ended up using a batch file to run the command.
String args2 = "windres.exe -i \"" + Path.GetFullPath(file) + "\" -o \"" + Path.Combine(tempDir, "my.o") + "\"" ;
using (StreamWriter writer = new StreamWriter(tempDir + #"\my.bat", false, Encoding.ASCII))
{
await writer.WriteLineAsync("#echo off");
await writer.WriteLineAsync("cd " + Path.GetFullPath(gccLocation));
await writer.WriteLineAsync(args2);
}
//Debug
//args2 = "/k echo " + args2;
ProcessStartInfo psi2 = new ProcessStartInfo();
psi2.FileName = tempDir + #"\my.bat";
psi2.UseShellExecute = false;
psi2.CreateNoWindow = true;
//Debug
//psi2.CreateNoWindow = false;
Process windres = Process.Start(psi2);
windres.WaitForExit();

How to take mysql backup or Restore with 'SPACE' in the given path C#

When i'm trying to take a database Backup or Restore means it is not working properly. because the path which i given contains 'SPACE'
BackUp/RestoreFile Path: "C:\Documents and Settings\prabhu\Desktop\Backup.sql"
(Documents and Settings contains 'SPACE')
I'm Working in C#.
CODE:
string directoryName = D:\\Shop Plan\\ERP Project\\Main Source\\OutPut\\Debug\\DBBackup;
string filePath = "C:\Documents and Settings\prabhu\Desktop\Backup.sql";
TextWriter textWriter = new StreamWriter(filePath);
textWriter.WriteLine("CD " + directoryName);
if (type == "Backup")
{
textWriter.WriteLine("mysqldump -h " + "SERVERNAME"+ " -u " + "USERNAME" + " -p" + "PASSWORD" + " -P " + "PORT" + " --routines " + "DATABASE_NAME" + " -B> " + filePath);
}
else if (type == "Restore")
{
textWriter.WriteLine("mysql -h " + "SERVERNAME" + " -u " + "USERNAME" + " -p" + "PASSWORD" +" -P " + "PORT" + " <" + filePath);
}
textWriter.Close();
Process processes = new Process();
processes.StartInfo.WorkingDirectory = directoryName ;
processes.StartInfo.FileName = "Backup.BAT";
processes.StartInfo.CreateNoWindow = true;
processes.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
processes.Start();
processes.WaitForExit();
Lines:
string directoryName = D:\\Shop Plan\\ERP Project\\Main Source\\OutPut\\Debug\\DBBackup;
string filePath = "C:\Documents and Settings\prabhu\Desktop\Backup.sql";
change to:
string directoryName = "\"" + #"D:\Shop Plan\ERP Project\Main Source\OutPut\Debug\DBBackup" + "\"";
string filePath = "\"" + #"C:\Documents and Settings\prabhu\Desktop\Backup.sql" + "\"";
#"C:\Documents and Settings\prabhu\Desktop\Backup.sql"
Are you sure it is the spaces maybe you need the syntax #
http://www.dotnetperls.com/path

ffmpeg.exe freezes

I'm using Asp.Net C# Framework 4 and currently developing a video conversion application. I'm also using ffmpeg to convert from all uploaded formats to flv. I'm first converting uploaded file to mpg and after to flv due to problems I encountered while trying conversion directly to flv from mp4 sometimes. But ffmpeg freezes as soon as it's done with conversion process to mpg file. When I run task manager and check the processes list, it just stands there using no CPU resource. When I end the ffmpeg process directly from task manager, other process take place which converts from mpg to flv and preview file (jpg) and works smoothly. Due to freezing of first process, the second process cannot start when I try to upload from my web page's file upload form. I appreciate any response from now. Here is my code:
string duration = "00:00:00";
//converting video
Process ffmpeg;
ffmpeg = new Process();
// convert to mpg 1st
ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + videolink + "\" -f mpeg -b 300k -ac 2 -ab 128k -ar 44K \"" + Server.MapPath("static/user/vid/") + mpglink + "\"";
ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe");
ffmpeg.StartInfo.CreateNoWindow = true;
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.Start();
ffmpeg.WaitForExit();
ffmpeg.Close();
// mpg 2 flv
ffmpeg = new Process();
ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + mpglink + "\" -f flv -s 624x352 \"" + Server.MapPath("static/user/vid/") + flvlink + "\"";
ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe");
ffmpeg.StartInfo.CreateNoWindow = true;
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.Start();
ffmpeg.BeginOutputReadLine();
string error = ffmpeg.StandardError.ReadToEnd();
ffmpeg.WaitForExit();
try
{
duration = error.Substring(error.IndexOf("Duration: ") + 10, 8);
}
catch
{
}
if (ffmpeg.ExitCode != 0)
{
ltrUpload.Text = "<div class=\"resultbox-negative\" id=\"divResult\">Problem occured during upload process. Error code: " + error + "<br>" + "</div>";
return;
}
ffmpeg.Close();
// generate preview image
ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + flvlink + "\" -s 624x352 -ss 00:00:03 -an -vframes 1 -f image2 -vcodec mjpeg \"" + Server.MapPath("static/user/vid/") + flvlink.Replace(".flv", ".jpg") + "\"";
ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe");
ffmpeg.StartInfo.CreateNoWindow = true;
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.Start();
ffmpeg.WaitForExit();
ffmpeg.Close();
// deleting original file and mpg
FileInfo fi = new FileInfo(Server.MapPath("static/user/vid/") + videolink);
if (fi.Exists) fi.Delete();
fi = new FileInfo(Server.MapPath("static/user/vid/") + mpglink);
if (fi.Exists) fi.Delete();
I know this is a very old question, but if someone gets here because of a Google search, the answer is the following:
You would have to read the redirected error output of the first ffmpeg process, too, even if you do not need it. It will result in a deadlock if you do not read the redirected error output because your program will wait for the process to finish, but the process waits for the filled error output stream to be read. You can look it up here.
// convert to mpg 1st
ffmpeg.StartInfo.Arguments = " -i \"" + Server.MapPath("static/user/vid/") + videolink + "\" -f mpeg -b 300k -ac 2 -ab 128k -ar 44K \"" + Server.MapPath("static/user/vid/") + mpglink + "\"";
ffmpeg.StartInfo.FileName = Page.MapPath("bin/ffmpeg.exe");
ffmpeg.StartInfo.CreateNoWindow = true;
ffmpeg.StartInfo.UseShellExecute = false;
ffmpeg.StartInfo.RedirectStandardOutput = true;
ffmpeg.StartInfo.RedirectStandardError = true;
ffmpeg.Start();
// Use asynchronous read operations on at least one of the streams.
// Reading both streams synchronously would generate another deadlock.
ffmpeg.BeginOutputReadLine();
string tmpErrorOut = ffmpeg.StandardError.ReadToEnd();
ffmpeg.WaitForExit();
ffmpeg.Close();
So you would have to read the redirected error and output streams like you did with your second ffmpeg process.
The same goes for your generating image preview part!
private bool ReturnVideo(string fileName)
{
string html = string.Empty;
//rename if file already exists
int j = 0;
string AppPath;
string inputPath;
string outputPath;
string imgpath;
AppPath = Request.PhysicalApplicationPath;
//Get the application path
inputPath = AppPath + "Upload\\Videos\\OriginalVideo";
//Path of the original file
outputPath = AppPath + "Upload\\Videos\\ConvertVideo";
//Path of the converted file
imgpath = AppPath + "Upload\\Videos\\Thumbs";
//Path of the preview file
string filepath = Server.MapPath("../Upload/Videos/OriginalVideo/" + fileName);
while (File.Exists(filepath))
{
j = j + 1;
int dotPos = fileName.LastIndexOf(".");
string namewithoutext = fileName.Substring(0, dotPos);
string ext = fileName.Substring(dotPos + 1);
fileName = namewithoutext + j + "." + ext;
filepath = Server.MapPath("../Upload/Videos/OriginalVideo/" + fileName);
}
try
{
this.fileuploadImageVideo.SaveAs(filepath);
}
catch
{
return false;
}
string outPutFile;
outPutFile = "../Upload/Videos/OriginalVideo/" + fileName;
int i = this.fileuploadImageVideo.PostedFile.ContentLength;
System.IO.FileInfo a = new System.IO.FileInfo(Server.MapPath(outPutFile));
while (a.Exists == false)
{ }
long b = a.Length;
while (i != b)
{ }
string cmd = " -i \"" + inputPath + "\\" + fileName + "\" \"" + outputPath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".flv" + "\"";
ConvertNow(cmd);
ViewState["fileName"] = fileName.Remove(fileName.IndexOf(".")) + ".wmv";
string imgargs = " -i \"" + inputPath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".wmv" + "\" -f image2 -ss 1 -vframes 1 -s 280x200 -an \"" + imgpath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".jpg" + "\"";
ConvertNow(imgargs);
return true;
}
private void ConvertNow(string cmd)
{
string exepath;
string AppPath = Request.PhysicalApplicationPath;
//Get the application path
exepath = AppPath + "ffmpeg.exe";
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = exepath;
//Path of exe that will be executed, only for "filebuffer" it will be "wmvtool2.exe"
proc.StartInfo.Arguments = cmd;
//The command which will be executed
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = false;
proc.Start();
while (proc.HasExited == false)
{ }
}
if (fileuploadImageVideo.HasFile)
{
ReturnVideo(this.fileuploadImageVideo.FileName.ToString());
string filename = fileuploadImageVideo.PostedFile.FileName;
fileuploadImageVideo.SaveAs(Server.MapPath("../upload/Video/"+filename));
objfun.Video = filename ;
}

Categories

Resources