I have a WindowsForm that has a DataGridView that shows output of my app. The class with the button is DriveRecursion_Results.cs. I want it so that once the button is pushed by the user, my method FileCleanUp() in my SanitizeFileNames class is called. I'm not quite sure how to do this though.
Here is the code for both classes:
public partial class DriveRecursion_Results : Form
{
public DriveRecursion_Results()
{
InitializeComponent();
}
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
}
public void DriveRecursion(string retPath)
{
//recurse through files. Let user press 'ok' to move onto next step
// string[] files = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
string pattern = " *[\\~#%&*{}/<>?|\"-]+ *";
//string replacement = "";
Regex regEx = new Regex(pattern);
string[] fileDrive = Directory.GetFiles(retPath, "*.*", SearchOption.AllDirectories);
List<string> filePath = new List<string>();
dataGridView1.Rows.Clear();
try
{
foreach (string fileNames in fileDrive)
{
if (regEx.IsMatch(fileNames))
{
string fileNameOnly = Path.GetFileName(fileNames);
string pathOnly = Path.GetDirectoryName(fileNames);
DataGridViewRow dgr = new DataGridViewRow();
filePath.Add(fileNames);
dgr.CreateCells(dataGridView1);
dgr.Cells[0].Value = pathOnly;
dgr.Cells[1].Value = fileNameOnly;
dataGridView1.Rows.Add(dgr);
filePath.Add(fileNames);
}
else
{
DataGridViewRow dgr2 = new DataGridViewRow();
dgr2.Cells[0].Value = "No Files To Clean Up";
dgr2.Cells[1].Value = "";
}
}
}
catch (Exception e)
{
StreamWriter sw = new StreamWriter(retPath + "ErrorLog.txt");
sw.Write(e);
}
}
private void button1_Click(object sender, EventArgs e)
{
//i want to call SanitizeFileName's method FileCleanup here.
}
}
Here is SanitizeFileNames:
public class SanitizeFileNames
{
public void FileCleanup(List<string>filePath)
{
string regPattern = "*[\\~#%&*{}/<>?|\"-]+*";
string replacement = "";
Regex regExPattern = new Regex(regPattern);
foreach (string files2 in filePath)
{
try
{
string filenameOnly = Path.GetFileName(files2);
string pathOnly = Path.GetDirectoryName(files2);
string sanitizedFileName = regExPattern.Replace(filenameOnly, replacement);
string sanitized = Path.Combine(pathOnly, sanitizedFileName);
//write to streamwriter
System.IO.File.Move(files2, sanitized);
}
catch (Exception ex)
{
//write to streamwriter
}
}
}
}
private void button1_Click(object sender, EventArgs e)
{
List<string> paths = new List<string>()
// initialize paths to whatever is neccessary
//....
new SanitizeFileNames().FileCleanUp(paths)
}
Just create an instance of the class, and call the method.
However, the method itself does not use the state of the class, so it can be changed to a static method
public static void FileCleanup(List<string>filePath)
and you'll be able to call it without creating an instance, directly from the class, like this:
SanitizeFileNames.FileCleanUp(paths)
Related
I am new to c# and I am trying to write simple code for listing all .ini files in directories. And now I need each line to be green or red depending on the context of .ini files. My code seems like just go through all files in listbox and color all lines depending on value of the last .ini.
Thanks
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string rootdir = #"C:\Users\isaced1\Desktop\test";
string[] files = Directory.GetFiles(rootdir, "*.ini", SearchOption.AllDirectories);
Projects.Items.AddRange(files);
//var items = Projects.SelectedItems;
foreach (var item in files)
{
try
{
string fileName = Projects.GetItemText(item);
string fileContents = System.IO.File.ReadAllText(fileName);
const string PATTERN = #"OTPM = true";
Match match = Regex.Match(fileContents, PATTERN, RegexOptions.IgnoreCase);
if (match.Success)
{
Projects.ForeColor = Color.Green;
}
else
{
Projects.ForeColor = Color.Red;
}
}
catch
{
MessageBox.Show("No");
}
}
}
}
I am practicing an OCR program using C#, I am not much of a coder so I am trying to find my way around.
1- I OCR some pdf files.
2- I see the output of the OCR.
3- I use UI buttons to browse and then click convert.
4- I have a progress bar on the UI but it does not visually upgrade, while when I log the progressBar.Value I see its numbers are updating.
So I searched around and I found that the issue is I should like stop the thread and create a new one for the Ui to visually update, but I really do not understand that, or even do not know how to do it.
Can someone please help me ? like baby steps.
Also I know I have copied and pasted like alot of code for you to see.
The case is the following:
1- class fmMain: Form has a progressBarIncrementation function, responsible for taking the increment value from a function in processFunctions class.
2- progressBarIncrementation function has progressBar.Value to be updated, I see its value updated.
3- But visually nothing is updated. I tried some threading code, but i do not understand it so.....
class processFunctions
{
Thread newThread = Thread.CurrentThread;
private string invoiceNameIndex = "";
private string invoiceIBANIndex = "";
private string invoiceNumberIndex = "";
private string invoiceDateIndex = "";
private string invoiceSubtotalIndex = "";
private string invoiceVATIndex = "";
private string invoiceTotalIndex = "";
private string[] filePath;
private string[] fileNamePDF;
private int totalNumberOfFiles;
private string InformationNeeded(string wholeRead, string ix)
{
string[] lines = wholeRead.Split(new[] { "\r\n", "\r", "\n", " " }, StringSplitOptions.None);
if(ix.Contains(","))
{
string[] variableIndex = ix.Split(',');
string name = "";
for(int i =0; i < variableIndex.Length; i++)
{
name += lines[Convert.ToInt32(variableIndex[i])];
}
return name;
}
return lines[Convert.ToInt32(ix)];
}
public void ocrFunction(string filePathOnly)
{
var Ocr = new AutoOcr();
var Results = Ocr.ReadPdf(filePathOnly);
var Barcodes = Results.Barcodes;
var Text = Results.Text;
string[] numbers = { invoiceNameIndex, invoiceIBANIndex, invoiceNumberIndex,
invoiceDateIndex, invoiceSubtotalIndex, invoiceVATIndex, invoiceTotalIndex};
string[] results = new string[numbers.Count()];
for (int i = 0; i < numbers.Length; i++)
{
results[i] = InformationNeeded(Text, numbers[i]);
Console.WriteLine(results[i]);
}
Results = null;
Ocr = null;
Barcodes = null;
Text = null;
}
public int browseFile()
{
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
OpenFileDialog ofd = new OpenFileDialog();
int numberOfFilesToBeProcessed = 0;
ofd.Filter = "PDF|*.pdf";
ofd.Multiselect = true;
string[] name = new string[2];
if (ofd.ShowDialog() == DialogResult.OK)
{
numberOfFilesToBeProcessed = ofd.FileNames.Length;
filePath = ofd.FileNames;
fileNamePDF = ofd.SafeFileNames;
}
this.totalNumberOfFiles = ofd.FileNames.Length;
return numberOfFilesToBeProcessed;
}
public void databaseReader()
{
string connectionString;
SqlConnection connection;
connectionString = ConfigurationManager.ConnectionStrings["OCR_App.Properties.Settings.LibraryConnectionString"].ConnectionString;
for (int i = 0; i < fileNamePDF.Length; i++)
{
string fileNameFiltered = fileNamePDF[i].Replace(".pdf", "");
using (connection = new SqlConnection(connectionString))
using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT * FROM invoicesTable WHERE invoiceRef = '" + fileNameFiltered + "'", connection))
{
DataTable invoicesTable = new DataTable();
adapter.Fill(invoicesTable);
DataRow index = invoicesTable.Rows[0];
invoiceNameIndex = (index[1].ToString());
invoiceIBANIndex = (index[2].ToString());
invoiceNumberIndex = (index[3].ToString());
invoiceDateIndex = (index[4].ToString());
invoiceSubtotalIndex = (index[5].ToString());
invoiceVATIndex = (index[6].ToString());
invoiceTotalIndex = (index[7].ToString());
ocrFunction(filePath[i]);
//newThread.Start();
fmMain formFunctions = new fmMain();
//Thread.Yield();
//Thread thread = new Thread(() => formFunctions.ProgressBarIncrementation(progressBarIncrement()));
formFunctions.ProgressBarIncrementation(progressBarIncrement());
}
}
}
public int progressBarIncrement()
{
int incrementValue = 0;
incrementValue = incrementValue + 100 / totalNumberOfFiles;
//Console.WriteLine(incrementValue);
return incrementValue;
}
///////////////////////////////////////////////////////////////////
public partial class fmMain : Form
{
processFunctions processingMain = new processFunctions();
ProgressBar NewprogressBar = new ProgressBar();
private static int incrementbar = 0;
public fmMain()
{
InitializeComponent();
}
[STAThread]
private void BtnBrowse_Click(object sender, EventArgs e)
//Browse the file needed to scan.
{
int number = processingMain.browseFile();
txtBoxFilePath.Text = number.ToString();
}
public void BtnConvert_Click(object sender, EventArgs e)
{
processingMain.databaseReader();
}
private void fmMain_Load(object sender, EventArgs e)
{
}
private void txtBoxFilePath_TextChanged(object sender, EventArgs e)
{
}
private void NumberOfFilesToBeProcessed_Click(object sender,
EventArgs e)
{
}
public void progressBar_Click(object sender, EventArgs e)
{
progressBar.Maximum = 100;
NewprogressBar.Value = progressBar.Value;
}
public void ProgressBarIncrementation(int incrementValue)
{
//Thread.Yield();
//Thread newThread = Thread.CurrentThread;
incrementbar = incrementbar + incrementValue;
progressBar.Visible = true;
progressBar.Value += incrementbar;
Thread thread = new Thread(() => progressBar.Value += incrementbar);
Console.WriteLine(progressBar.Value);
//progressBar.Value += incrementbar;
}
}
If you are needing the progress bar, you might want to consider creating an event to help report progress to your calling application. And you'll want to mark your function browseFile as async and do the following:
public async Task<int> browseFileAsync()
{
await Task.Run(new Action(() => {
OpenFileDialog ofd = new OpenFileDialog();
int numberOfFilesToBeProcessed = 0;
ofd.Filter = "PDF|*.pdf";
ofd.Multiselect = true;
string[] name = new string[2];
if (ofd.ShowDialog() == DialogResult.OK)
{
numberOfFilesToBeProcessed = ofd.FileNames.Length;
filePath = ofd.FileNames;
fileNamePDF = ofd.SafeFileNames;
}
this.totalNumberOfFiles = ofd.FileNames.Length;
return numberOfFilesToBeProcessed;
}));
}
And then in your calling application do:
private async void BtnBrowse_Click(object sender, EventArgs e)
//Browse the file needed to scan.
{
int number = await processMain.browseFileAsync();
txtBoxFilePath.Text = number.ToString();
}
I would also consider not calling a folder browser dialog from your class as this couples your class to a specific implementation. Rather, I would browse for the file from the GUI and pass the selected file(s) to the class.
I have written a code for extracting number from a text file using a windows From. Problem is that, Output Occurs in a partial way. Either the First Line is Printing or the Last Line. I want all the line that is containing the number
(i.e) If the text file contains,
Auto 2017
Mech 2056
CSE 2016
I want only those 2017, 2056, 2016 to be printed.
Here is the code:
private void button1_Click(object sender, EventArgs e)
{
string infile = textBox1.Text;
StreamReader sr = new StreamReader(infile);
string allDetails = File.ReadAllText(infile);
string result = Regex.Match(allDetails, #"\d+").Value;
richTextBox1.Text = result.ToString();
}
You are try to grab numeric value. Regex.Matches Will help you to solve your problem.
Below is simplified code.
private void button1_Click(object sender, EventArgs e)
{
string filedetails = File.ReadAllText(textBox1.Text);
var regexCollection = Regex.Matches(filedetails, #"\d+");
foreach (Match rc in regexCollection)
richTextBox1.AppendText(rc.Value + ",");
}
You can do this way, if you want output 2017,2056,2016
private void button1_Click(object sender, EventArgs e)
{
string infile = textBox1.Text;
string[] lines = System.IO.File.ReadAllLines(infile);
string temp = "";
int i = 0;
foreach (string line in lines)
{
string result = Regex.Match(line, #"\d+").Value;
if (i == 0)
{
temp = result;
}
else
{
temp = temp + "," + result;
}
i++;
}
richTextBox1.Text = temp;
}
or if you want single value 2017 2056 2016 then
private void button1_Click(object sender, EventArgs e)
{
string infile = textBox1.Text;
string[] lines = System.IO.File.ReadAllLines(infile);
foreach (string line in lines)
{
string result = Regex.Match(line, #"\d+").Value;
richTextBox1.Text = result ;
}
}
You need to use the method. Regex.Matches. Matches method searches the specified input string for all occurrences of a regular expression.
Match method returns the first match only, Subsequent matches need to be retrieved.
private void button1_Click(object sender, EventArgs e)
{
string infile = textBox1.Text;
StreamReader sr = new StreamReader(infile);
string allDetails = File.ReadAllText(infile);
var regexMatchCollection = Regex.Matches(allDetails, #"\d+");
foreach(Match mc in regexMatchCollection)
{
richTextBox1.AppendText(mc.Value);
richTextBox1.AppendText(",");
}
}
test.txt has
Auto 2017
Mech 2056
CSE 2016
in the following program File.ReadAllLines will store every line in a string array separately.Then we will use foreach loop to read single line at a time and store the extracted numbers in list e.g 2017 and finally with string.Join we will join the array and separate each word with "," and save it in string
List<string> list = new List<string>();
var textfile = File.ReadAllLines(#"D:\test.txt");
foreach (var line in textfile)
{
string result = Regex.Match(line, #"\d+").Value;
list.Add(result);
}
string numbers = string.Join(",",list.ToArray());
the output value will be
2017,2056,2016
private void button1_Click(object sender, EventArgs e)
{
string infile = textBox1.Text;
StreamReader sr = new StreamReader(infile);
string allDetails = File.ReadAllText(infile);
string result = string.Empty;
foreach (var item in Regex.Matches(allDetails, #"\d+"))
{
result = result + item.ToString() + ",";
}
richTextBox1.Text = result.TrimEnd(',');
}
Without using Regex,below is the simplified code
private void button1_Click(object sender, EventArgs e)
{
StringBuilder numbers = new StringBuilder();
string allDetails = File.ReadAllText(textBox1.Text);
foreach(string word in allDetails.Split(' '))
{
int number;
if(int.TryParse(word, out number))
{
numbers.Append(number);
numbers.Append(",");
}
}
richTextBox1.Text = numbers.Trim(',');
}
static void Main(string[] args)
{
string[] lines = System.IO.File.ReadAllLines(#"C:\Users\admin\Desktop\ConsoleApplication1\ConsoleApplication1\txtFile.txt");
List<string> Codelst = new List<string>();
foreach (var item in lines)
{
var a= Regex.Match(item, #"\d+").Value;
Codelst .Add(a);
}
var r = Codelst;
}
Output is like this:
I have set up a program that so far can browse for the location of a file that possesses data in a text file holding the locations of other files which then shows me if they exist, are missing or are a duplicate inside listboxes. The next step is to enable the user to select files in the checked list boxes and being given the option to either move or copy. I have already made buttons which allow this but I want to be able to use them for the checked boxes I the list boxes.(p.s) please ignore any comments I have made in the code they are just previous attempts of doing other things in the code.
My code so far:
namespace File_existence
{
public partial class fileForm : Form
{
private string _filelistlocation;
public fileForm()
{
InitializeComponent();
}
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
public void fileForm_Load(object sender, System.EventArgs e)
{
_filelistlocation = textBox1.Text;
}
private void button1_Click(object sender, System.EventArgs e)
{
//GetDuplicates();
checkedListBox1.Items.Clear();
listBox2.Items.Clear();
ReadFromList();
}
private void GetDuplicates()
{
DirectoryInfo directoryToCheck = new DirectoryInfo(#"C:\\temp");
FileInfo[] files = directoryToCheck.GetFiles("*.*", SearchOption.AllDirectories);
var duplicates = files.GroupBy(x => x.Name)
.Where(group => group.Count() > 1)
.Select(group => group.Key);
if (duplicates.Count() > 0)
{
MessageBox.Show("The file exists");
FileStream s2 = new FileStream(_filelistlocation, FileMode.Open, FileAccess.Read, FileShare.Read);
// open _filelistlocation
// foreach line in _filelistlocation
// concatenate pat hand filename
//
}
}
public void ReadFromList()
{
int lineCounter = 0;
int badlineCounter = 0;
using (StreamReader sr = new StreamReader(_filelistlocation))
{
String line;
while ((line = sr.ReadLine()) != null)
{
string[] values = line.Split('\t');
if (values.Length == 2)
{
string fullpath = string.Concat(values[1], "\\", values[0]);
if (File.Exists(fullpath))
checkedListBox1.Items.Add(fullpath);
else
listBox2.Items.Add(fullpath);
++lineCounter;
}
else
++badlineCounter;
//Console.WriteLine(line);
}
}
}
//StreamReader files= new StreamReader(File)();
private void listBox1_SelectedIndexChanged(object sender, System.EventArgs e)
{
}
private void button2_Click(object sender, System.EventArgs e)
{
FolderBrowserDialog folderBrowserDlg = new FolderBrowserDialog();
folderBrowserDlg.ShowNewFolderButton = true;
DialogResult dlgResult = folderBrowserDlg.ShowDialog();
if (dlgResult.Equals(DialogResult.OK))
{
textBox1.Text = folderBrowserDlg.SelectedPath;
Environment.SpecialFolder rootFolder = folderBrowserDlg.RootFolder;
}
try
{
string fileName = "filetest1.txt";
string sourcePath = #"C:\Temp\Trade files\removed";
string targetPath = #"C:\Temp\Trade files\queued";
string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
string destFile = System.IO.Path.Combine(targetPath,fileName);
System.IO.File.Copy(sourceFile, destFile, true);
}
catch (IOException exc)
{
MessageBox.Show(exc.Message);
}
}
private void button3_Click(object sender, System.EventArgs e)
{
try
{
string sourceFile = #"C:\Temp\Trade Files\queued\filetest1.txt";
string destinationFile = #"C:\Temp\Trade Files\processed\filetest1.txt";
System.IO.File.Move(sourceFile, destinationFile);
}
catch(IOException ex){
MessageBox.Show(ex.Message);//"File not found"
}
}
private void button4_Click(object sender, System.EventArgs e)
{
OpenFileDialog fileBrowserDlg = new OpenFileDialog();
//folderBrowserDlg.ShowNewFolderButton = true;
//folderBrowserDlg.SelectedPath = _filelistlocation;
fileBrowserDlg.FileName = textBox1.Text;
DialogResult dlgResult = fileBrowserDlg.ShowDialog();
if (dlgResult.Equals(DialogResult.OK))
{
textBox1.Text = fileBrowserDlg.FileName;
File_existence.Properties.Settings.Default.Save();
// Environment.SpecialFolder rootFolder = folderBrowserDlg.RootFolder;
}
}
private void button5_Click(object sender, System.EventArgs e)
{
if (!textBox1.Text.Equals(String.Empty))
{
if (System.IO.Directory.GetFiles(textBox1.Text).Length > 0)
{
foreach (string file in System.IO.Directory.GetFiles(textBox1.Text))
{
checkedListBox1.Items.Add(file);
}
}
else
{
checkedListBox1.Items.Add(String.Format("No file found: {0}", textBox1.Text));
}
}
}
}
}
The task I need to do is that the files that appear in the checked list box need to usually be moved or copied to another directory. That is fine as I can already do that with what I have coded, but what it does is it will move or copy all of the files in the checked list box. What I want to do is enable the user to only be able to select which files they what to move or copy through checking the checked list box so that only those files will be moved or copied.
EDIT: Could it be checkedListBox.checked items?
I want to invoke timer in my c# code on button click.It works well in form load event but didn't work in button click.Please help me to fix it.Thank's in advance.
My code is Here:
public partial class Form1 : Form
{
public int TimeTaken;
public Form1()
{
InitializeComponent();
lblFilesCount.Text = lblFoldersCount.Text = "0";
}
private void btnFolderBrowse_Click(object sender, EventArgs e)
{
DialogResult result = fbdFoldersFiles.ShowDialog();
if (result == DialogResult.OK)
{
string[] files = Directory.GetFiles(fbdFoldersFiles.SelectedPath);
MessageBox.Show("Files found: " + files.Length.ToString(), "Message");
}
txtFolderPath.Text = fbdFoldersFiles.SelectedPath;
}
private void btnDeleteFiles_Click(object sender, EventArgs e)
{
timerDelete.Enabled= true;
string path = fbdFoldersFiles.SelectedPath;
DirectoryInfo dirFirst = new DirectoryInfo(path);
foreach (FileInfo file in dirFirst.GetFiles())
{
timerDelete.Enabled = true;
DateTime dt = File.GetLastWriteTime(file.FullName);
if (dt < dtpDate.Value)
{
DeleteFiles(file);
}
}
string[] dirArray = Directory.GetDirectories(path, "*", SearchOption.AllDirectories).ToArray();
Array.Reverse(dirArray);
foreach (var directory in dirArray)
{
if (Directory.GetFiles(directory).Length > 0 || Directory.GetDirectories(directory).Length>0)
{
DirectoryInfo dir = new DirectoryInfo(directory);
FileInfo[] files = dir.GetFiles().ToArray();
foreach (FileInfo file in files)
{
timerDelete.Enabled = true;
DateTime dt = File.GetLastWriteTime(file.FullName);
if (dt < dtpDate.Value)
{
DeleteFiles(file);
}
}
if (Directory.GetFiles(directory).Length == 0 )
{
dir.Delete(true);
lblFoldersCount.Text = (Convert.ToInt32(lblFoldersCount.Text) + 1).ToString();
}
}
}
timerDelete.Enabled = false;
}
protected void DeleteFiles(FileInfo DeleteFile)
{
dgvDisplayFilesInfo.Rows.Add();
int RowIndex = dgvDisplayFilesInfo.RowCount - 1;
DataGridViewRow r = dgvDisplayFilesInfo.Rows[RowIndex];
r.Cells["dgvColoumnSrNo"].Value = RowIndex+1;
r.Cells["dgvColumnFullName"].Value = DeleteFile.Name;
r.Cells["dgvColumnPath"].Value = DeleteFile.Directory;
DeleteFile.Delete();
lblFilesCount.Text = (Convert.ToInt32(lblFilesCount.Text)+1).ToString();
}
private void timerDelete_Tick(object sender, EventArgs e)
{
TimeTaken = TimeTaken++;
lblShowTimeTaken.Text = TimeTaken.ToString();
}
}
First of all you are setting the Enabled=True in the foreach which I don't think it's what you intended. 2nd of all, why don't you use Stopwatch component. It's much easier to use.
Stopwatch sw = new Stopwatch();
sw.Start();
....
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds.ToString())