Printing listbox Items in order of occurence - c#

I have an application that I have built and is just sort of printing app.
First I populate ListBox and format it then goto c:\somefolder
in some folder are pdf files it looks on listbox and see if there is any file name that matches an item on the listbox and sends it to the default printer.Everything is working great ,but say I have JohnDoe.pdf,ShahRukh.pdf,Vijay.pdf
how can I make it to send the files in that order, for now it works great ,but I want to be able to print ==> JohnDoe.pdf first, then ShahRukh.pdf and so on and so forth.Please if you have any idea to spare is much welcome.
Thanks in advance. This what I have right now it works great but print all items that match but randomly .I want it to respond or print matches in order of occurrence from top to bottom.
public class Pdf
{
public static Boolean PrintPDFs(string pdfFileName)
{
try
{
ProcessStartInfo stackOverflowHelp = new ProcessStartInfo();
stackOverflowHelp.Verb = "print";
stackOverflowHelp.FileName = pdfFileName;
stackOverflowHelp.CreateNoWindow = true;
stackOverflowHelp.WindowStyle = ProcessWindowStyle.Hidden;
Process gamingBoy = new Process();
gamingBoy.StartInfo = stackOverflowHelp;
gamingBoy.Start();
gamingBoy.WaitForInputIdle();
if (gamingBoy.HasExited == false)
{
gamingBoy.WaitForExit(20000);
//return true;
}
// System.Threading.Thread.Sleep(1000);
gamingBoy.EnableRaisingEvents = true;
gamingBoy.Close();
// return true;
//proc.Close();
//KillAdobe("AcroRd32");
return true;
}
catch
{
return false;
}
}
private void button2_Click(object sender, EventArgs e)
{
string dir = #"C:\slim\slimyyyy";//
if (Directory.Exists(dir))//If a directory defined above exists then do the followings
{
string[] pdf_Files = Directory.GetFiles(dir);
if (pdf_Files.Length > 0)
{
foreach (string file in pdf_Files)
{
string fileName = Path.GetFileName(file);
foreach (object item in listBox1.Items)
{
if (fileName == line.ToString())
{
Pdf.PrintPDFs((file));
}
}
}
}
}
}

Just reverse the order of your foreach loops:
foreach (object item in listBox1.Items)
{
foreach (string file in pdf_Files)
{
string fileName = Path.GetFileName(f);
if (fileName == line.ToString())
{
Pdf.PrintPDFs((file));
}
}
}

The easy answer is to change the order of your loops. That is, change your loop to:
foreach (var item in listBox1.Items)
{
var fname = item.ToString();
if (pdf_files.Contains(fname))
{
Pdf.PrintPDFs(fname);
}
}

Related

How do I make it so catch stops looping and goes back to the beginning of the loop

When running this code once it catches an exception it will keep repeating "The file was not found". How do I make it so it goes back to the beginning of the loop instead?
private static List<Party> FindData(string exactpath)
{
bool validInput = false;
while(validInput==false)
{
try
{
// Store values in a list of string
List<string> file = File.ReadAllLines(exactpath).ToList();
List<Party> parties = new List<Party>();
foreach (string line in file.Skip(3))
{
string[] items = line.Split(',');
Party p = new Party(items[0], Convert.ToInt32(items[1]), items.Skip(2).ToArray());
parties.Add(p);
}
return parties;
}
catch (FileNotFoundException)
{
Console.WriteLine($"The file was not found");
}
}
return null;
}
Example when not finding the file:
Break; should do the trick. Is it what you are looking for?
private static List<Party> FindData(string exactpath)
{
bool validInput = false;
while(validInput==false)
{
try
{
// Store values in a list of string
List<string> file = File.ReadAllLines(exactpath).ToList();
List<Party> parties = new List<Party>();
foreach (string line in file.Skip(3))
{
string[] items = line.Split(',');
Party p = new Party(items[0], Convert.ToInt32(items[1]), items.Skip(2).ToArray());
parties.Add(p);
}
return parties;
}
catch (FileNotFoundException)
{
Console.WriteLine($"The file was not found");
break;
}
}
return null;
}

Read Line Having Track Revisions in Word

Is there any way I can find Line Having Track Changes [Inserted or Deleted] using Open XML SDK. I have tried with below code I am able to detect whether document body having Track Changes or Not and It Works correctly Now What I want is to find which Text line of body contains track changes
public static System.Type[] trackedRevisionsElements = new System.Type[] {
typeof(CellDeletion),
typeof(CellInsertion),
typeof(CellMerge),
typeof(CustomXmlDelRangeEnd),
typeof(CustomXmlDelRangeStart),
typeof(CustomXmlInsRangeEnd),
typeof(CustomXmlInsRangeStart),
typeof(Deleted),
typeof(DeletedFieldCode),
typeof(DeletedMathControl),
typeof(DeletedRun),
typeof(DeletedText),
typeof(Inserted),
typeof(InsertedMathControl),
typeof(InsertedMathControl),
typeof(InsertedRun),
typeof(MoveFrom),
typeof(MoveFromRangeEnd),
typeof(MoveFromRangeStart),
typeof(MoveTo),
typeof(MoveToRangeEnd),
typeof(MoveToRangeStart),
typeof(MoveToRun),
typeof(NumberingChange),
typeof(ParagraphMarkRunPropertiesChange),
typeof(ParagraphPropertiesChange),
typeof(RunPropertiesChange),
typeof(SectionPropertiesChange),
typeof(TableCellPropertiesChange),
typeof(TableGridChange),
typeof(TablePropertiesChange),
typeof(TablePropertyExceptionsChange),
typeof(TableRowPropertiesChange),
};
public static bool PartHasTrackedRevisions(OpenXmlPart part)
{
List<OpenXmlElement> insertions =
part.RootElement.Descendants<Inserted>()
.Cast<OpenXmlElement>().ToList();
//Body bdy = wordDoc.MainDocumentPart.Document.Body;
if (part.RootElement.Descendants()
.Any(e => trackedRevisionsElements.Contains(e.GetType())))
{
var initialTextDescendants = part.RootElement.Descendants<Text>();
string dummy = string.Empty;
foreach (Text t in initialTextDescendants)
{
MessageBox.Show(t.Text);
}
}
return part.RootElement.Descendants()
.Any(e => trackedRevisionsElements.Contains(e.GetType()));
}
public static bool HasTrackedRevisions(WordprocessingDocument doc)
{
if (PartHasTrackedRevisions(doc.MainDocumentPart))
return true;
foreach (var part in doc.MainDocumentPart.HeaderParts)
if (PartHasTrackedRevisions(part))
return true;
foreach (var part in doc.MainDocumentPart.FooterParts)
if (PartHasTrackedRevisions(part))
return true;
if (doc.MainDocumentPart.EndnotesPart != null)
if (PartHasTrackedRevisions(doc.MainDocumentPart.EndnotesPart))
return true;
if (doc.MainDocumentPart.FootnotesPart != null)
if (PartHasTrackedRevisions(doc.MainDocumentPart.FootnotesPart))
return true;
return false;
}
private void button2_Click(object sender, EventArgs e)
{
foreach (var documentName in Directory.GetFiles(".", "*.docx"))
{
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Open(documentName, false))
{
if (HasTrackedRevisions(wordDoc)) {
//Body bdy = wordDoc.MainDocumentPart.Document.Body;
//var initialTextDescendants = bdy.Descendants<Text>();
//string dummy = string.Empty;
//foreach (Text t in initialTextDescendants)
//{
// richTextBox1.Text = richTextBox1.Text + t.Text;
//}
Console.WriteLine("{0} contains tracked revisions", documentName);
}
else
Console.WriteLine("{0} does not contain tracked revisions", documentName);
}
}
}
What exactly do you mean with "Text line of body"? The line of text as it would appear on a laid out document (which is not easy) or the Open XML elements that were changed?
If this is about the line of text on a laid out document, as produced by Microsoft Word, this is hard, because you would require a layout algorithm to understand where the lines with those tracked changes would be rendered.
If this is about the OpenXmlElements, e.g., Text or Paragraph, you already have part of your solution as this is about querying the XML mark-up.

Access Denied on accessing the system folder of any drive like system volume information

I have the following recursion code to get all the folders and files of a selected directory. But when I select a drive, for example E:\\ .., I am getting an error message of
"Access denied in accessing E:\system volume information"
Is it possible to bypass the system volume information folder?
This is the code I am using:
private static ArrayList GenerateFileList(string Dir)
{
ArrayList fils = new ArrayList();
bool Empty = true;
foreach (string file in Directory.GetFiles(Dir)) // add each file in directory
{
fils.Add(file);
Empty = false;
}
if (Empty)
{
if (Directory.GetDirectories(Dir).Length == 0)
// if directory is completely empty, add it
{
fils.Add(Dir + #"/");
}
}
foreach (string dirs in Directory.GetDirectories(Dir)) // recursive
{
foreach (object obj in GenerateFileList(dirs))
{
fils.Add(obj);
}
}
return fils; // return file list
}
private static ArrayList GenerateFileList(string Dir)
{
ArrayList fils = new ArrayList();
bool Empty = true;
try
{
foreach (string file in Directory.GetFiles(Dir)) // add each file in directory
{
fils.Add(file);
Empty = false;
}
}
catch(UnauthorizedAccessException e)
{
// I believe that's the right exception to catch - compare with what you get
return new ArrayList();
}
if (Empty)
{
if (Directory.GetDirectories(Dir).Length == 0)
// if directory is completely empty, add it
{
fils.Add(Dir + #"/");
}
}
foreach (string dirs in Directory.GetDirectories(Dir)) // recursive
{
foreach (object obj in GenerateFileList(dirs))
{
fils.Add(obj);
}

Refresing the C# DataGrid from a background thread

I'm using a DataGrid bound to an ObservableCollection source to display two columns, a file name and a number that I get from analysing the file.
ObservableCollection<SearchFile> fileso;
//...
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
/* Get all the files to check. */
int dirCount = searchFoldersListView.Items.Count;
List<string> allFiles = new List<string>();
for(int i = 0; i < dirCount; i++)
{
try
{
allFiles.AddRange(Directory.GetFiles(searchFoldersListView.Items[i].ToString(), "*.txt").ToList());
allFiles.AddRange(Directory.GetFiles(searchFoldersListView.Items[i].ToString(), "*.pdf").ToList());
}
catch
{ /* stuff */ }
}
/* Clear the collection and populate it with unchecked files again, refreshing the grid. */
this.Dispatcher.Invoke(new Action(delegate
{
fileso.Clear();
foreach(var file in allFiles)
{
SearchFile sf = new SearchFile() { path=file, occurrences=0 };
fileso.Add(sf);
}
}));
/* Check the files. */
foreach(var file in allFiles)
{
this.Dispatcher.Invoke(new Action(delegate
{
int occurences;
bool result = FileSearcher.searchFile(file, searchTermTextBox.Text, out occurences);
fileso.AddOccurrences(file, occurences); // This is an extension method that alters the collection by finding the relevant item and changing it.
}));
}
}
//...
public static void AddOccurrences(this ObservableCollection<SearchFile> collection, string path, int occurrences)
{
for(int i = 0; i < collection.Count; i++)
{
if(collection[i].path == path)
{
collection[i].occurrences = occurrences;
break;
}
}
}
//...
public static bool searchTxtFile(string path, string term, out int occurences)
{
string contents = File.ReadAllText(path);
occurences = Regex.Matches(contents, term, RegexOptions.IgnoreCase).Count;
if(occurences>0)
return true;
return false;
}
public static bool searchDocxFile(string path, string term, out int occurences)
{
occurences = 0;
string tempPath = Path.GetTempPath();
string rawName = Path.GetFileNameWithoutExtension(path);
string destFile = System.IO.Path.Combine(tempPath, rawName + ".zip");
System.IO.File.Copy(path, destFile, true);
using(ZipFile zf = new ZipFile(destFile))
{
ZipEntry ze = zf.GetEntry("word/document.xml");
if(ze != null)
{
using(Stream zipstream = zf.GetInputStream(ze))
{
using(StreamReader sr = new StreamReader(zipstream))
{
string docContents = sr.ReadToEnd();
string rawText = Extensions.StripTagsRegexCompiled(docContents);
occurences = Regex.Matches(rawText, term, RegexOptions.IgnoreCase).Count;
if(occurences>0)
return true;
return false;
}
}
}
}
return false;
}
public static bool searchFile(string path, string term, out int occurences)
{
occurences = 0;
string ext = System.IO.Path.GetExtension(path);
switch(ext)
{
case ".txt":
return searchTxtFile(path, term, out occurences);
//case ".doc":
// return searchDocFile(path, term, out occurences);
case ".docx":
return searchDocxFile(path, term, out occurences);
}
return false;
}
But the problem is that sometimes, when I hit the update button (which starts the worker with the the do_work method above), some of the time, I'm getting random zeroes in the number column instead of the correct number. Why is that? I'm assuming it's because there's some problem with updating the number column twice, with sometimes the first zeroing getting applied after the actual update, but I'm not sure about the details.
I think this is a case of an access to a modified closure
/* Check the files. */
foreach(var file in allFiles)
{
var fileTmp = file; // avoid access to modified closure
this.Dispatcher.Invoke(new Action(delegate
{
int occurences;
bool result = FileSearcher.searchFile(fileTmp, searchTermTextBox.Text, out occurences);
fileso.AddOccurrences(fileTmp, occurences); // This is an extension method that alters the collection by finding the relevant item and changing it.
}));
}
Basically what's happening is that you are passing the file variable to a lambda expression, but file will be modified by the foreach loop before the action is actually invoked, using a temp variable to hold file should solve this.

How to avoid using foreach loop to get the filelist for different reason

Here what am trying to do:
I have a remote server (e.g:svr01,svr02,svr03). Using GetFileList to read the directory get all the files and match with the file name I have then copy to my local drive.
If any files matched then am adding them to an XML file also.
I was trying to do like below
class Program
{
static void Main(string[] args)
{
var getfiles = new fileshare.Program();
string realname = "*main*";
string Location = "SVR01";
bool anymatch = false;
foreach (var file in getfiles.GetFileList(realname,Location))
{anymatch=true;}
if (anymatch == true)
{ baseMeta(); }
foreach (var file in getfiles.GetFileList(realname,Location))
{getfiles.copytolocal(file.FullName); }
}
private FileInfo[] GetFileList(string pattern,string Location)
{
try
{
switch (Location)
{
case "SVR01":
{
var di = new DirectoryInfo(#"\\SVR01\Dev");
return di.GetFiles(pattern);
}
case "SVR02":
{
var di = new DirectoryInfo(#"\\SVR02\Dev");
return di.GetFiles(pattern);
}
case "SVR03":
{
var di = new DirectoryInfo(#"\\SVR03\Prod");
return di.GetFiles(pattern);
}
default: throw new ArgumentOutOfRangeException();
}
}
catch(Exception ex)
{ Console.Write(ex.ToString());
return null;
}
}
private void copytolocal(string filename)
{
string nameonly = Path.GetFileName(filename);
File.Copy(filename,Path.Combine(#"c:\",nameonly),true);
}
private void baseMeta()
{
XmlWriter xmlWrite = XmlWriter.Create(#"c:\basexml");
xmlWrite.WriteStartElement("job");
xmlWrite.WriteElementString("Name", "test");
xmlWrite.WriteElementString("time", DateTime);
xmlWrite.Close();
}
}
but this piece of code worries me because am doing the same process two times, any one please guide me how to avoid this.
foreach (var file in getfiles.GetFileList(realname,Location))
{
anymatch=true;}
if (anymatch == true)
{
baseMeta();
}
foreach (var file in getfiles.GetFileList(realname,Location))
{
getfiles.copytolocal(file.FullName);
}
}
Even am trying to find out if it match anyfile then i quit the first foreach loop generate the basemeta() then goes to next foreach loop to do the rest of the process.
Using LINQ you should be able to easily change your posted code into:
var getfiles = new fileshare.Program();
string realname = "*main*";
string Location = "SVR01";
var fileList = getFiles.GetFileList(realname, Location);
var anymatch = fileList.Any();
if (anymatch) // Or possibly `if (fileList.Any())` if anymatch isn't
// really used anywhere else
baseMeta();
foreach (var file in getfiles.GetFileList(realname,Location))
getfiles.copytolocal(file.FullName);
You'll get the greatest benefit by replacing your GetFileList method with:
private IEnumerable<FileInfo> GetFileList(string pattern,string Location)
{
string directory = string.Empty;
switch (Location)
{
case "SVR01":
directory = #"\\SVR01\Dev";
break;
case "SVR02":
directory = #"\\SVR02\Dev";
break;
case "SVR03":
directory = #"\\SVR03\Prod");
break;
default:
throw new ArgumentOutOfRangeException();
}
DirectoryInfo di = null;
try
{
di = new DirectoryInfo(directory);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
yield break;
}
foreach(var fi in di.EnumerateFiles(pattern))
yield return fi;
}
Use this
var files = getfiles.GetFileList(realname, Location);
if (files.Length > 0)
{
baseMeta();
foreach(var file in files)
{
getfiles.copytolocal(file.FullName);
}
}
Try this:
Create method to check the file existence and do all in single loop.
your statement is not much clear that when you will copy or not.. use
your condition on which you want to copy or create xml entry..
What is your AnyMatch?? If you want to check that Is there any file then use
var fileList = getfiles.GetFileList(realname,Location);
if( fileList.Count() > 0)
{
baseMeta();
}
foreach (var file in fileList)
{
// copy the file if match does not exist..
getfiles.copytolocal(file.FullName);
}
But Foreach loop through collection if it have any item. so you need not to care about the count of the files..
If you want to do entry on every copy as per your code then why you need to check anyMatch etc. It will create entry on every file copy.
foreach (var file in getfiles.GetFileList(realname,Location))
{
baseMeta();
// copy the file
getfiles.copytolocal(file.FullName);
}

Categories

Resources