Pass more arguments to an already opened cmd prompt in C# - c#

I want to loop through all images in a folder, retrieve each image's name and pass an argument using the name. This is what I have:
foreach (string imageFile in Directory.EnumerateFiles(filePath))
{
//Get image name and save it as string
string args = "something"; //a line of argument with image name in it
Process.Start("cmd", #"/c cd C:\Tesseract-OCR && " + args);
}
The problem with above code is that, for each image file, it will open up a new command prompt. Instead, I want something like:
Process.Start("cmd", #"/k cd C:\Tesseract-OCR");
foreach (string imageFile in Directory.EnumerateFiles(filePath))
{
//For each imageFile I have, pass an argument to the opened cmd prompt
}

There are a few methods, but generally the simplest is to create a batch file with all of the commands you want to execute then pass that as a parameter to cmd.
Something like this:
string imageFolder = #"C:\Path\To\Images";
string batchFile = #"C:\Temp\cmds.cmd";
string outputFile = #"C:\Temp\cmds.log";
// substitute your own command here. "{0}" will be substituted for filename
string command = #"attrib ""{0}"" >> """ + outputFile + #"""";
// delete the batch file if it exists
if (File.Exists(batchFile))
File.Delete(batchFile);
// create batch file from content of image folder
using (var writer = File.CreateText(batchFile))
{
writer.WriteLine("#echo off");
foreach (var file in Directory.EnumerateFiles(imageFolder, "*.jpg"))
writer.WriteLine(command, file);
}
// Delete the output file if it exists
if (File.Exists(outputFile))
File.Delete(outputFile);
// Execute the batch
var p = Process.Start("cmd", #"/c """ + batchFile + #"""");
p.WaitForExit();
After that completes you can grab the content of the output file and parse it for results. If you need a break between the outputs, just echo something distinctive between each one. Maybe something like:
// create batch file from content of image folder
using (var writer = File.CreateText(batchFile))
{
writer.WriteLine("#echo off");
foreach (var file in Directory.EnumerateFiles(imageFolder, "*.jpg"))
{
writer.WriteLine(#"echo -----Start: {0}>>""{1}""", file, outputFile);
writer.WriteLine(command, file);
writer.WriteLine(#"echo -----End: {0}>>""{1}""", file, outputFile);
}
}
That way you get the filename in the output as well to help with parsing.
Another option is to use full stream redirection to streams that you can write commands to and read responses from. This would allow you to have a command prompt running somewhere in the background that you can issue commands to. Seems simple, but honestly it takes a lot of work to get just right. If you want to go this way I'd suggest redirecting all three standard streams.

Why not have the program create a batch file containing all the files/commands to be executed, then use Process.Start to execute the batch file?

You can use Directory.GetFiles() to get a string array of all the files in a directory. Then use String.Join() to merge the array into one long string of file names separated by space. I would also wrap each item in quotes if your path or files contain spaces.
const string QUOTE = "\"";
const string SPACE = " ";
const string SEPARATOR = QUOTE + SPACE + QUOTE;
string[] files = Directory.GetFiles(filePath, "*.png");
string allFiles = QUOTE + String.Join(SEPARATOR, files) + QUOTE;
Console.WriteLine(#"cmd.exe /c cd C:\Tesseract-OCR && " + allFiles);

Related

How can I detect if there is any file in a folder using SSIS?

I receive every day a file with a specific pattern and extension, which I want to run under certain process. I want to check if there is any file in my folder, because otherwise I will do another task. So far I found that you can use a Script Task and do a File.Exist. However, I'm doing something wrong because it doesn't take the * as a wildcard.
Devoluciones_source is "C:\Users\us1\Folder\"
FileToSearch is "return"
My files:
return_20200102.csv
return_20200203.csv
String Filepath = Dts.Variables["$Project::Devoluciones_source"].Value.ToString() + Dts.Variables["User::FileToSearch"].Value.ToString() + "*csv";
if (
File.Exists(Filepath))
{
Dts.Variables["User::IsFound"].Value = 1;
}
I don't think File.Exits() accepts wildcards, it checks the literal filepath and will return false because C:\Users\us1\Folder\*.csv is not found.
What you could do instead is get the files in the folder C:\Users\us1\Folder\ and checking those agains a searchPattern using Directory.GetFiles(path, searchPattern)
Like this:
string dirPath = Dts.Variables["$Project::Devoluciones_source"].Value.ToString();
string fileName = Dts.Variables["User::FileToSearch"].Value.ToString();
// if you want to make sure the directory exists:
if(Directory.Exists(dirPath) {
string[] files = Directory.GetFiles(dirPath, fileName + "*.csv");
if(files.lenght > 0) {
// you can now iterate over each file that is found in the users directory that matches your pattern and do your logic.
}
}
Some more info on the Directory.GetFiles method: Directory.GetFiles on docs.Microsoft.com
Some more info on the Files.Exists method: Directory.GetFiles on docs.Microsoft.com

rename file by adding an incrementing number to old file name c#

I'm writing my first Cocoa app in c#, its suppose to append/add numbers at the begging of a file name.
Users give only the path to the folder (for example with music), and for each file included in folder the program suppose to add incrementing numbers like
001_(old_fileName),
002_(old_fileName),
...,
092_(old_fileName)
etc,
Untill the end of files in given folder (by path).
There is no way to split a file name, cause file names are not known (may even include numbers itself). I've tried few possible options to solve this, but non of them works. Found few already asked question with changing names in c# but non of the results actually helped me.
The code under is the rest I've got at the moment, all non-working tries were firstly commented and later deleted. by NSAlert i see the path/name of each file in folder as a help. I would be more than happy to receive help
void RenameFunction()
{
string sPath = _Path_textBox.StringValue;
if (Directory.Exists(sPath))
{
var txtFiles = Directory.EnumerateFiles(sPath);
var txt2Files = Directory.GetFiles((sPath));
string fileNameOnly = Path.GetFileNameWithoutExtension(sPath);
string extension = Path.GetExtension(sPath);
string path = Path.GetDirectoryName(sPath);
string newFullPath = sPath;
int count = 1;
while (File.Exists(sPath))//newFullPath))
{
string tempFileName = string.Format(count + "_" + fileNameOnly + sPath);
//count++;
//string.Format("{0}{0}{0}{1}", fileNameOnly, count++);
newFullPath = Path.Combine(path, extension + tempFileName);
count++;
}
string[] fileEntities = Directory.GetFiles(newFullPath); //GetFileSystemEntries(sPath);//GetFiles(sPath);
//foreach (var _songName in fileEntities)
//{
// string tempFileName = count + "_" + fileNameOnly + sPath;
// //string.Format("{0}{0}{0}{1}", fileNameOnly, count++);
// newFullPath = Path.Combine(sPath ,extension + tempFileName);
// File.Move(sPath, newFullPath);
//}
foreach (var _songName in fileEntities)
{
AmountofFiles(_songName);
}
}
}
void AmountofFiles(string path)
{
var alert2 = new NSAlert();
alert2.MessageText = "mp3";
alert2.InformativeText = "AMOUNT OF MP3 FILES IS '{1}' : " + path;
alert2.RunModal();
}
Have you try use File.Move? Just move file to same path, but another name
File.Move("NameToBeRename.jpg","NewName.jpg");
There are multiple things which are not right with the code you share. The thing which want to achieve can be implemented using very simple approach.
All you need to do is retrieve all the files names with the full path from the directory and rename them one by one.
Follow the below code which demonstrates the above mentioned approach.
// Path of the directory.
var directroy = _Path_textBox.StringValue;
if (Directory.Exists(directroy))
{
//Get all the filenames with full path from the directory.
var filePaths = Directory.EnumerateFiles(directroy);
//Variable to append number in front of the file name.
var count = 1;
//Iterate thru all the file names
foreach (var filePath in filePaths)
{
//Get only file name from the full file path.
var fileName = Path.GetFileName(filePath);
//Create new path with the directory path and new file name.
var destLocation = Path.Combine(directory, count + fileName);
//User File.Move to move file to the same directory with new name.
File.Move(filePath, destLocation);
//Increment count.
count++;
}
}
I hope this helps you to resolve your issue.

C# Save a copy of a text file after replacing values with .Replace

I have a method that i am using to replace values in a txt file.
protected void SendFormData(NameValueCollection formData)
{
string fileName = Server.MapPath("/_TextTemplate/textTemplate.txt");
string emailBody = File.ReadAllText(fileName);
foreach (string val in formData.AllKeys)
{
emailBody = emailBody.Replace("##"+ val +"##", formData[val]);
}
}
I plan on saving a copy of this text file after i have replaced the values. How can give this file a logical name and save a copy of it in my directory?
I did some googleing and File.WriteAllLines keeps popping up.
File.WriteAllLines(#"/_TextTemplate/" + formData[0] + ".txt", formData[0]);
But VS is complaining about that.
File.WriteAllLines
Expects an IEnumerable<string> as an argument. You want
File.WriteAllText(#"/_TextTemplate/" + formData[0] + ".txt", formData[0])

c# create 7z archive, then Can not open file "name.7z" as an archive

I am trying to zip some folders. They have different paths, will not belong to the same directory.
I tested the command line arguments that I would give, and it works, but I can't get it to work from c#:
string destination = "some path\\name.7z";
string pathToZip = "path to zip\\7z.exe"; // or 7za.exe
ProcessStartInfo p = new ProcessStartInfo();
p.FileName = pathToZip;
p.Arguments = "a \"" + destination + "\" \"";
// room for the foreach - but even one directory doesn't work right now
p.Arguments += directoryPath + "\" \"";
p.Arguments += "\" -mx=9 -aoa";
Process x = Process.Start(p);
With 7z.exe i get a blink; With 7za.exe, I get the typical command-line zip sequence, with files zipping through, adding to archive, and an archive gets created.
Then I go to it and right-click, open or double-click... and I get that it is an invalid archive (Can not open file "name.7z" as an archive). Try command line, with 7za, to extract - same thing.
Edit: I found the solution:
My problem was the -aoa option (which I used for overwrite) - after removing it, it worked.
This code works for me, packs a directory with files within:
string destination = #"c:\my test.7z";
string pathToZip = #"C:\Program Files\7-Zip\7z.exe";
string directoryPath = #"c:\my test";
ProcessStartInfo p = new ProcessStartInfo();
p.FileName = pathToZip;
p.Arguments = string.Format("a -mx=9 \"{0}\" \"{1}\"", destination, directoryPath);
Process x = Process.Start(p);
7za.exe is the command line program, you should use it in this instance.
Why are you adding "" to your command line? That may be causing your problem.
Also, make sure you put your " around things, don't pad with two of them at the end, that just causes problems.
If the command line works, maybe just use a different start function; the one that takes the path to the exe, and the command line parameters in the second parameter.
Look here.
If the command line works, this may be the best way.

Path with white spaces can't create a file using File.CreateText(filePath) c#

I'm developing a console application that parse xml files and generate a txt file. I have created the file path to store the new file, but this is having white spaces, like this:
string filePath = "C:\\Program Files\\my path\\fileName.txt"
but I'm creating the path using:
string filePath = Path.Combine(temp, "fileName.txt");
while temp is the previous path. And when I call:
StreamWriter sw = File.CreateText(filePath);
Is giving this exception:
Could not find a part of the path: filePath
Can someone help me with this issue?? how can I create the file with this path?
there looks like a problem with you file path
try#"C:\Program Files\my path\fileName.txt"
Note: You've updated your question with the changes mentioned in the comments.
Your issue is probably that 'my path' doesn't exist as this console application works OK for me when run as an administrator. When not run I get an UnathorizedAccessException
class Program
{
static void Main(string[] args)
{
try
{
var temp = #"C:\\Program Files\\my path\\";
string filePath = Path.Combine(temp, "fileName.txt");
StreamWriter sw = File.CreateText(filePath);
Console.WriteLine("I got here");
}
catch (Exception)
{
Console.WriteLine("I didn't");
//
}
}
}
Use this:
string filePath = #"C:\Program Files\my path\fileName.txt"
You have single backslashes in the string. Make them double backslashes:
string filePath = "C:\\Program Files\\my path\\fileName.txt"

Categories

Resources