C# - Executing external exectutable with arguments - c#

I have been trying to convert my python code to c# code. For some reason, the c# code gets to the DirectoryInfo declaration and says the path is not found. If someone can tell me why, it would be appreciated.
This is the original python code:
def encode(path, dest):
for root_dir, dirs, files in os.walk(path, topdown=False):
for name in files:
(base, ext)=os.path.splitext(name)
input_file = os.path.join(root_dir,name)
output_file = os.path.join(dest_dir, base+".mkv")
if (os.path.exists(output_file)):
print ("skipped")
else:
subprocess.call( ["HandBrakeCLI.exe", "-i", input_file, "-o", output_file, "-e", "x264", "--aencoder", "ac3", "-s", "1", "--subtitle-default", "1" ])
This is my current c# code:
string qpath = Path.GetFullPath((Environment.CurrentDirectory + "\\Queue\\"));
if (Directory.Exists(Path.GetFullPath(qpath)))
{
var DirMKV = (Directory.GetFiles(qpath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".mkv") || s.EndsWith(".mp4")).ToArray());
foreach (string file in DirMKV)
{
DirectoryInfo dirinfo = new DirectoryInfo(file);
if (dirinfo.Parent.Parent.ToString().Contains("S"))
{
string ipath = Environment.CurrentDirectory;
string dpath = ipath + #"\Queue\" + dirinfo.Parent.Parent.ToString() + #"\" + Path.GetFileName(file);
string opath = ipath + #"\Finished\" + dirinfo.Parent.Parent.ToString() + #"\" + Path.GetFileName(file);
string arg = "-i " +dpath + " -o " +opath +" -e x264 "+ " --aencoder ac3 "+ "-s 1 "+ "--subtitle-default 1";
if (!File.Exists(opath))
{
Process.Start(ipath + #"\handbrakeCLI.exe", arg);
}
}
}
}

I don't understand Python, but from what I see, your c# code and python code definitely do different things. There are bunch of things that are not clear. I have commented your code with my advice. Hopefully that will solve your issues
Commented code below
string qpath = Path.GetFullPath((Environment.CurrentDirectory + "\\Queue\\"));
if (Directory.Exists(Path.GetFullPath(qpath))) // No need to do Path.GetFullPath again
{
var DirMKV = (Directory.GetFiles(qpath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".mkv") || s.EndsWith(".mp4")).ToArray()); // no need to do ToArray. List all files in Queue folder
foreach (string file in DirMKV)
{
DirectoryInfo dirinfo = new DirectoryInfo(file); // I don't get any Path not found exception here
if (dirinfo.Parent.Parent.ToString().Contains("S")) // Check if GrandParent directory name contains the letter S. Don't see any such thing in python code
{
string ipath = Environment.CurrentDirectory;
string dpath = ipath + #"\\Queue\\" + dirinfo.Parent.Parent.ToString() + #"\" + Path.GetFileName(file); // Set input file to something like Queue\*S*\File.mkv. Does this file exist??? It should use single backslash instead of double backslash
string opath = ipath + #"\\Finished\\" + dirinfo.Parent.Parent.ToString() + #"\" + Path.GetFileName(file); // Set output file to something like Finished\*S*\File.mkv. It should use single backslash instead of double backslash
string arg = "-i " +dpath + " -o " +opath +" -e x264 "+ " --aencoder ac3 "+ "-s 1 "+ "--subtitle-default 1";
if (!File.Exists(opath))
{
Process.Start(ipath + #"\handbrakeCLI.exe", arg); // does the handbrakeCLI.exe exist in the current directory????
}
}
}
}
Below code is based on my guess about what you want
/*
* Expects a directory structure like below
* S
* |-> bin
* |-> Queue
* |-> test1.mp4
* |-> test2.mkv
* |-> Finished
* |-> test3.mkv
* |-> executable (this code)
* |-> handbrakeCLI.exe
*
*/
DirectoryInfo qpath = new DirectoryInfo("Queue");
if (qpath.Exists) {
var mkvFiles = qpath.GetFiles("*.*", SearchOption.AllDirectories).Where(s => s.Extension == ".mkv" || s.Extension == ".mp4");
foreach (var mkvFile in mkvFiles) {
var gParent = mkvFile.Directory.Parent.ToString();
if (gParent.Contains("S")) {
string opath = Path.Combine(mkvFile.Directory.Parent.FullName, "Finished", mkvFile.Name);
string arg = "-i " + mkvFile.FullName + " -o " + opath + " -e x264 " + " --aencoder ac3 " + "-s 1 " + "--subtitle-default 1";
if (!File.Exists(opath))
Process.Start(Environment.CurrentDirectory+ #"\handbrakeCLI.exe", arg);
}
}
}

Related

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.

GetFiles of certain extension and write to spreadsheet C#

I'm writing a application that reads Ia directory contents and writes that to a csv file. I'm trying to get a list of certain file extensions from and upload path which contains a csv file and write a list of the filtered extensions to a new csv file.
I cant figure out how to get the filtered csv file written.....
Here's my method.
StringBuilder CreateUserFileUploadList(SLDocument document, StringBuilder destroyWorksheet)
{
document.SelectWorksheet("User Folder");
var stats = document.GetWorksheetStatistics();
var rowcount = stats.EndRowIndex + 1;
List unwantedExtensions = cblExtensions.Items.Cast().Where(li => li.Selected).Select(li => li.Text).ToList();
if (!String.IsNullOrEmpty(tbOtherExtensions.Text))
{
unwantedExtensions.AddRange(tbOtherExtensions.Text.ToUpper().Split(new char[] { ',', ' ', '.' }, StringSplitOptions.RemoveEmptyEntries));
}
unwantedExtensions.AddRange("EXE,COM,BAT,JS,VBS,PIF,CMD,DLL,OCX,PWL".Split(new char[] { ',', ' ', '.' }, StringSplitOptions.RemoveEmptyEntries));
// new CSV file
var workSheet = new StringBuilder();
workSheet.AppendLine("FILEPATH,Client,Matter,LAST MODIFIED DATE,CREATED DATE,CREATED BY,LAST MODIFIED BY,FOLDER,DOCUMENT NAME,Author,Practice Area,Document Type,ACCESS,Keywords - Comments");
// loop through the directories
for (int i = 2; i 100 chars, or including TAB / \ : * ? " |
// Folder has folders>500 or has files>1000
//TODO: this loops through leaf folders; we need to check intermediate folders to ensure they don't have too many files or folders or a bad name
//Took out #"\",
bool invalidFolderName = new string[] { "/", ":", "*", "?", "" }.Any(s => directoryName.Contains(s));
if (invalidFolderName || directoryName.Length > 200 || files.Count() > 1000)
{
System.Diagnostics.Debug.WriteLine("INVALID folder: " + directoryName);
lblError.Text = lblError.Text + "\r\n" + "INVALID folder: " + directoryName;
//TODO: This should cause the WHOLE upload to fail
}
// build the target folder path
string folder;
string[] stringSeparators = new string[] { tbAuthor.Text };
var path = directoryName.Split(stringSeparators, StringSplitOptions.None);
folder = path.Last();
if (path.Count() > 1)
{
folder = ConfigurationManager.AppSettings["NetDocumentsFolderPath"].ToString() + tbAuthor.Text + #"\User Folder" + folder;
if (folder.Substring(folder.Length - 1, 1) == #"\")
{
folder = folder.Substring(0, folder.Length - 1);
}
}
// Get the files
foreach (var file in files)
{
// Remove unwanted extensions
if (!unwantedExtensions.Contains(file.Extension.Replace(".", "").ToUpper()))
{
var access = file.GetAccessControl();
string user = access.GetOwner(typeof(System.Security.Principal.NTAccount)).ToString();
//TODO: FWIW, fileName (on netdocs) does NOT need to match the name in the original location...
string fullName = file.FullName;
string fileName = file.Name;
// Wrap in quotes if there are any invalid characters
if (fullName.IndexOfAny(csvTokens) >= 0)
{
fullName = "\"" + fullName.Replace("\"", "\"\"") + "\"";
}
if (fileName.IndexOfAny(csvTokens) >= 0)
{
fileName = "\"" + fileName.Replace("\"", "\"\"") + "\"";
}
if (!document.GetCellValueAsString(i, 2).ToUpper().Contains("DESTROY"))
{
String practiceArea = GetPracticeAreaForClientMatter(document.GetCellValueAsString(i, 2), document.GetCellValueAsString(i, 3));
String documentType = ConfigurationManager.AppSettings["FileDocumentType"].ToString();
// Validate file
// Invalid file names (>200 chars, or TAB / \ : * ? " |
// Invalid file size (>200 MB)
bool invalidFileName = new string[] { "/", #"\", ":", "*", "?", "" }.Any(s => file.Name.Contains(s));
if (invalidFileName || file.Length > 200000000 || file.Name.Length > 200)
{
System.Diagnostics.Debug.WriteLine("INVALID file: " + file.Name);
lblError.Text = lblError.Text + "\r\n" + "INVALID file: " + file.Name;
//TODO: This should cause the WHOLE upload to fail
}
else
{
workSheet.AppendLine(
fullName + "," +
document.GetCellValueAsString(i, 2) + "," +
document.GetCellValueAsString(i, 3) + "," +
file.LastWriteTime + "," +
file.CreationTime + "," +
tbAuthor.Text + "," +
tbAuthor.Text + "," +
folder + "," +
fileName + "," +
tbAuthor.Text + "," +
practiceArea + "," +
documentType + "," +
practiceArea + "|V," +
"Imported from Departed Attorney on: " + DateTime.Now.ToString("G"));
}
}
else
{
destroyWorksheet.AppendLine(fullName);
}
}
}
}
bool invalidFileName = new string[] { "/", #"\", ":", "*", "?", "" }.Any(s => file.Name.Contains(s));
if (document.GetCellValueAsString(i, 2).ToUpper().Contains("DESTROY"))
{// Files in folders marked "destroy" are saved elsewhere
//destroyWorkSheet.Append(string.Format("{0}", "Directory" + fullName));
//destroyWorkSheet.Append(string.Format("{1}", "FileName" + fullName));
// destroyWorkSheet.AppendLine("Directory, FileName");
// destroyWorkSheet.Append(string.Format("{0},{1}", "Directory", "FileName") + fullName);
destroyWorksheet.AppendLine(fullName);
}
// Validate file for name (less than 200 chars, can't have TAB / \ : * ? " | ) and size ( less than 200 MB)
else if (invalidFileName || file.Length > 200000000 || file.Name.Length > 200)
{// This should cause the WHOLE upload to fail
System.Diagnostics.Debug.WriteLine("INVALID file: " + file.Name);
lblError.Text = lblError.Text + "\r\n" + "INVALID file: " + file.Name;
errorWorksheet.AppendLine("INVALID file: " + file.Name);
}
else if (unwantedExtensions.Contains(file.Extension.Replace(".", "").ToUpper()))
{// Files with unwanted extensions are filtered out
filterWorksheet.AppendLine(fullName);
}

Remove file present on Linux server

Trying to run sudo command with user who has all the priviledges, but something is wrong in my code .
I am trying to remove a file present on the remote server via C# code. It says : The name 'pass' does not exist in the current context.:
My Code :
SshExec sshExec = new SshExec("sj1slm612", "karansha");
sshExec.Password = "pass";
sshExec.Connect();
//Removing config files from sj1slm612 server
string remove_config_file_express = "echo " + "'" + pass + "'" + "| sudo -S -u wtsnqa rm " + "/apps/instances/express_13000/configuration/standalone-full.xml";
string output_express = sshExec.RunCommand(remove_config_file_express);
Console.WriteLine("All config files removed");
Console.ReadLine();
the compiler is indeed correct. you reference a variable called pass which you probably meant to be the string "pass"
string remove_config_file_express = "echo " + "'" + pass + "'" + "| sudo -S -u wtsnqa rm " + "/apps/instances/express_13000/configuration/standalone-full.xml";
Use tamir Library next code.
public static bool BorrarArchivo(string rutaRemota)
{
try
{
SshExec comando = new SshExec(Servidor, Usuario);
comando.Password = Password;
comando.Connect();
string paso = comando.RunCommand("rm " + rutaRemota);
comando.Close();
return true;
}
catch (Exception ex)
{
mErrorSFTP = ex.Message;
return false;
}
}

C# pass path in argument

I'm starting cmd as a process in C# and I want to pass a file path in the argument. How to do it?
Process CommandStart = new Process();
CommandStart.StartInfo.UseShellExecute = true;
CommandStart.StartInfo.RedirectStandardOutput = false;
CommandStart.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
CommandStart.StartInfo.FileName = "cmd";
CommandStart.StartInfo.Arguments = "(here i want to put a file path to a executable) -arg bla -anotherArg blabla < (and here I want to put another file path)";
CommandStart.Start();
CommandStart.WaitForExit();
CommandStart.Close();
EDIT:
Process MySQLDump = new Process();
MySQLDump.StartInfo.UseShellExecute = true;
MySQLDump.StartInfo.RedirectStandardOutput = false;
MySQLDump.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
MySQLDump.StartInfo.FileName = "cmd";
MySQLDump.StartInfo.Arguments = "/c \"\"" + MySQLDumpExecutablePath + "\" -u " + SQLActions.MySQLUser + " -p" + SQLActions.MySQLPassword + " -h " + SQLActions.MySQLServer + " --port=" + SQLActions.MySQLPort + " " + SQLActions.MySQLDatabase + " \" > " + SQLActions.MySQLDatabase + "_date_" + date + ".sql";
MySQLDump.Start();
MySQLDump.WaitForExit();
MySQLDump.Close();
You need to put the file path in double quotes and use a verbatim string literal (#) as SLaks mentioned.
CommandStart.StartInfo.Arguments = #"""C:\MyPath\file.exe"" -arg bla -anotherArg";
Example with an OpenFileDialog
using(OpenFileDialog ofd = new OpenFileDialog())
{
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string filePath = "\"" + ofd.FileName + "\"";
//..set up process..
CommandStart.StartInfo.Arguments = filePath + " -arg bla -anotherArg";
}
}
Update to comment
You can format your string using String.Format.
string finalPath = String.Format("\"{0}{1}_date_{2}.sql\"", AppDomain.CurrentDomain.BaseDirectory, SQLActions.MySQLDatabase, date);
Then pass finalPath into the arguments.

Upload any video and convert to .mp4 online in .net

I have a strange requirement. User can upload their video of any format (or a limited format). We have to store them and convert them to .mp4 format so we can play that in our site.
Same requirement also for audio files.
I have googled but I can't get any proper idea. Any help or suggestions....??
Thanks in advance
You can convert almost any video/audio user files to mp4/mp3 with FFMpeg command line utility. From .NET it can be called using wrapper library like Video Converter for .NET (this one is nice because everything is packed into one DLL):
(new NReco.VideoConverter.FFMpegConverter()).ConvertMedia(pathToVideoFile, pathToOutputMp4File, Formats.mp4)
Note that video conversion requires significant CPU resources; it's good idea to run it in background.
Your Answer
please Replace .flv to .mp4 you will get your answer
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 + "OriginalVideo";
//Path of the original file
outputPath = AppPath + "ConvertVideo";
//Path of the converted file
imgpath = AppPath + "Thumbs";
//Path of the preview file
string filepath = Server.MapPath("~/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("~/OriginalVideo/" + fileName);
}
try
{
this.fileuploadImageVideo.SaveAs(filepath);
}
catch
{
return false;
}
string outPutFile;
outPutFile = "~/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);
string imgargs = " -i \"" + outputPath + "\\" + fileName.Remove(fileName.IndexOf(".")) + ".flv" + "\" -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 "flvtool2.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)
{
}
}
protected void btn_Submit_Click(object sender, EventArgs e)
{
ReturnVideo(this.fileuploadImageVideo.FileName.ToString());
}
I know it's a bit old thread but if I get here other people see this too. You shoudn't use it process info to start ffmpeg. It is a lot to do with it. Xabe.FFmpeg you could do this by running just
await Conversion.Convert("inputfile.mkv", "file.mp4").Start()
This is one of easiest usage. This library provide fluent API to FFmpeg.

Categories