I am trying to retrieve a specific attachment in Outlook to save to my folder.
Everything works great but it seems to save all the attachments in the "Inbox" Folder instead of the specific one I am looking for.
This is what I have at the moment:
static void EnumerateFoldersInDefaultStore()
{
Outlook.Application Application = new Outlook.Application();
Outlook.Folder root = Application.Session.DefaultStore.GetRootFolder() as Outlook.Folder;
EnumerateFolders(root);
}
static void EnumerateFolders(Outlook.Folder folder)
{
Outlook.Folders childFolders = folder.Folders;
if (childFolders.Count > 0)
{
foreach (Outlook.Folder childFolder in childFolders)
{
if (childFolder.FolderPath.Contains("Inbox"))
{
Console.WriteLine(childFolder.FolderPath);
EnumerateFolders(childFolder);
}
}
}
Console.WriteLine("Checking in " + folder.FolderPath);
IterateMessages(folder);
}
static void IterateMessages(Outlook.Folder folder)
{
string fileName = "Reports.pdf";
var fi = folder.Items;
if (fi != null)
{
try
{
foreach (Object item in fi)
{
Outlook.MailItem mi = (Outlook.MailItem)item;
var attachments = mi.Attachments;
if (attachments.Count != 0)
{
if (!Directory.Exists(basePath + folder.FolderPath))
{
Directory.CreateDirectory(basePath + folder.FolderPath);
}
for (int i = 1; i <= mi.Attachments.Count; i++)
{
if (fileName != null)
{
if (!Directory.Exists(basePath))
{
Directory.CreateDirectory(basePath);
}
totalfilesize = totalfilesize + mi.Attachments[i].Size;
if (!File.Exists(basePath + mi.Attachments[i].FileName))
{
Console.WriteLine("Saving " + mi.Attachments[i].FileName);
mi.Attachments[i].SaveAsFile(basePath + mi.Attachments[i].FileName);
}
else
{
Console.WriteLine("Already saved " + mi.Attachments[i].FileName);
}
}
}
}
}
}
catch (Exception e)
{
Console.WriteLine("An error occurred: '{0}'", e);
}
}
}
So it basically searches the entire "Inbox" and saves all the attachments but like I said not the one I want only - "Reports.pdf"
What am I doing wrong here?
In static void IterateMessages(Outlook.Folder folder) you currently only check for if (fileName != null) (which should never happen as fileName is always assigned at the beginning of the method).
You need to add a condition to check if the attached file meets your fileName-Criteria, e.g.:
if (mi.Attachments[i].FileName == fileName) {
//Save your attachment
} else {
// naming-critera not met, skip...
}
Related
From the following code I am trying to save listView items in a text file. But it doesn't save the items of listView in text file even not generating any error. My listView has a single column. Please identify What I am missing in this code.
private void saveAttemptsStatus()
{
var sw = new System.IO.StreamWriter("D:\\AlphaNumDataSum_" + txt_LUsername.Text);
foreach (ListViewItem item in list_Count.Items)
{
sw.Write(item + "\r\n");
}
sw.Close();
}
private void CountAttemps()
{
int numberOfItems = list_Count.Items.Count;
if (numberOfItems != 10)
{
if (username == txt_LUsername.Text && password == txt_LPassword.Text)
{
list_Count.Items.Add("correct");
txt_LUsername.Text = string.Empty;
txt_LPassword.Text = string.Empty;
}
else
{
list_Count.Items.Add("inCorrect");
txt_LUsername.Text = string.Empty;
txt_LPassword.Text = string.Empty;
}
}
else
{
saveAttemptsStatus();
MessageBox.Show("Thank You!");
}
}
Try changing your code to the following version and see if this works:
private void saveAttemptsStatus()
{
var filePath = "D:\\AlphaNumDataSum_" + txt_LUsername.Text;
using(sw = new System.IO.StreamWriter(filePath)){
foreach (ListViewItem item in list_Count.Items)
{
sw.WriteLine(item.Text);
}
}
}
I have sorted it out by creating a new file.
private void saveAttemptsStatus()
{
try
{
var sw = new System.IO.StreamWriter("D:\\AlphaNumDataSum_" + txt_LUsername.Text + "_Attempts");
foreach (ListViewItem item in list_Count.Items)
{
sw.Write(item + "\r\n");
}
sw.Close();
}
catch (System.IO.FileNotFoundException ex)
{
System.IO.File.Create("D:\\AlphaNumDataSum_" + txt_LUsername.Text + "_Attempts");
var sw = new System.IO.StreamWriter("D:\\AlphaNumDataSum_" + txt_LUsername.Text + "_Attempts");
foreach (ListViewItem item in list_Count.Items)
{
sw.Write(item + "\r\n");
}
sw.Close();
}
}
public void AccessOutlook()
{
Application oOutlook;
NameSpace oNs;
MAPIFolder oFldr;
try
{
oOutlook = new Application();
oNs = oOutlook.GetNamespace("MAPI");
oFldr = oNs.GetDefaultFolder(OlDefaultFolders.olFolderInbox);
string str = "Total Mail(s) in Inbox:" + oFldr.Items.Count;
string str2 = "Total Unread items = " + oFldr.UnReadItemCount;
foreach (var oMessage in oFldr.Items)
{
MailItem mitem = null;
try
{
if (oMessage != null)
{
mitem = (MailItem)oMessage;
String savepath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + #"\" + "Sridhar.html";
mitem.BodyFormat = OlBodyFormat.olFormatHTML;
mitem.SaveAs(savepath, OlSaveAsType.olHTML);
}
}
catch (System.Exception ex)
{
}
if (mitem != null)
{
string str3 = mitem.Subject;
}
}
}
catch (System.Exception ex)
{
}
finally
{
GC.Collect();
oFldr = null;
oNs = null;
oOutlook = null;
}
}
Here I want to convert mail item into PDF, hence in first step I'm trying to get mail item based on subject line and saving it in any outlook supported file formats. But I'm not able to do. Can anyone help with this?
Thanks in advance
In constructor. filePathList is List
filePathList = SearchAccessibleFilesNoDistinct(rootDirectory, null).ToList();
And the SearchAccessibleFilesNoDistinct method
IEnumerable<string> SearchAccessibleFilesNoDistinct(string root, List<string> files)
{
if (files == null)
files = new List<string>();
if (Directory.Exists(root))
{
foreach (var file in Directory.EnumerateFiles(root))
{
string ext = Path.GetExtension(file);
if (!files.Contains(file) && ext == textBox2.Text)
{
files.Add(file);
}
}
foreach (var subDir in Directory.EnumerateDirectories(root))
{
try
{
SearchAccessibleFilesNoDistinct(subDir, files);
files.Add(subDir);
}
catch (UnauthorizedAccessException ex)
{
// ...
}
}
}
return files;
}
Then i make loop over the List filePathList
foreach (string file in filePathList)
{
try
{
_busy.WaitOne();
if (worker.CancellationPending == true)
{
e.Cancel = true;
return;
}
bool reportedFile = false;
for (int i = 0; i < textToSearch.Length; i++)
{
if (File.ReadAllText(file).IndexOf(textToSearch[i], StringComparison.InvariantCultureIgnoreCase) >= 0)
{
resultsoftextfound.Add(file + " " + textToSearch[i]);
if (!reportedFile)
{
numberoffiles++;
MyProgress myp = new MyProgress();
myp.Report1 = file;
myp.Report2 = numberoffiles.ToString();
myp.Report3 = textToSearch[i];
backgroundWorker1.ReportProgress(0, myp);
reportedFile = true;
}
}
}
numberofdirs++;
label1.Invoke((MethodInvoker)delegate
{
label1.Text = numberofdirs.ToString();
label1.Visible = true;
});
}
catch (Exception)
{
restrictedFiles.Add(file);
numberofrestrictedFiles ++;
label11.Invoke((MethodInvoker)delegate
{
label11.Text = numberofrestrictedFiles.ToString();
label11.Visible = true;
});
continue;
}
The problem is that in the catch part the restrictedFiles is just directories not files. Since filePathList contain files and directories and when it's trying to search in a directory it's getting to the catch. It's not a restricted file it's just directory and not file at all.
That's why i think the method SearchAccessibleFilesNoDistinct should return only files without directories as items.
For example in filePathList i see in index 0:
c:\temp
And in index 1
c:\temp\help.txt
The first item in index 0 will go to the catch as restricted file and the second item will not.
You have this loop to search search the subdirectories:
foreach (var subDir in Directory.EnumerateDirectories(root))
{
try
{
SearchAccessibleFilesNoDistinct(subDir, files);
files.Add(subDir); <--- remove this line
}
catch (UnauthorizedAccessException ex)
{
// ...
}
}
Remove the line that adds the subdirectory to the list of files. I've marked it in the code above.
Is it you looking for:
Directory.GetFiles(rootDir,"*.*", SearchOption.AllDirectories);
? Change . to mask form textbox only.
Im trying to backup a computer with Windows 7 installed.
In older systems I created a backup that found and copyied specific images and office files.
Now when trying in Windows 7, I face some problems regarding some folders that arent available for me like they used to be in older systems.
How can I tweek this problem. I really like this way of backing the system up prior to upgrading etc.
Thanks in advance.
Feel free to ask and comment.
using System;
using System.Collections.Generic;
using System.IO;
//using System.IO.Directory.CreateDirectory;
static class Program
{
static void Main(string[] args)
{
ShowAllFoldersUnder(#"c:\",0);
}
private static void ShowAllFoldersUnder(string path,int indent)
{
int idx = 0;
string sourcePath = #"c:\";
string destinPath = #"h:\20160714\";
string fldr = #"C:\";
string[] fileTypes = new string[2];
fileTypes[idx] = ".docx"; idx++;
fileTypes[idx] = ".xlsx"; idx++;
try
{
if ((File.GetAttributes(path) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint)
{
foreach (string folder in Directory.GetDirectories( path ) )
{
//Console.WriteLine(folder);
//if (#folder.IndexOf(fldr) != -1) // COMMENT
//{
Console.WriteLine( folder );
foreach ( string file in Directory.GetFiles( folder ) )
{
string e = Path.GetExtension( file );
//Console.WriteLine(e);
for (int i =0;i<=fileTypes.GetUpperBound(0);i++)
{
string[] filesToCopy = Directory.GetFiles(folder, "*" + Convert.ToString(fileTypes[i]));
foreach (string name in filesToCopy)
{
if (Convert.ToString(fileTypes[i]).ToLower() == Path.GetExtension(file).ToLower())
{
Console.WriteLine("From: {0}",name);
Console.WriteLine("To: {0}", name.Replace(sourcePath, destinPath) );
try
{
DirectoryInfo di = Directory.CreateDirectory( Path.GetDirectoryName( name.Replace(sourcePath, destinPath) ) );
Console.WriteLine("Copying.");
File.Copy(name, name.Replace(sourcePath, destinPath), true);
}
catch (Exception ex)
{
Console.WriteLine("The process failed: {0}", ex.ToString());
}
finally {}
}
}
}
}
// break;
//}
ShowAllFoldersUnder(folder, indent);
}
}
}
catch (UnauthorizedAccessException)
{ }
}
}
I'm trying to move files from a to b, but I get an IOException with the Information: Access denied.
I'm pretty sure it's because the file is still open. My question is - how can I check if the file is in use or not, and if it is wait until it's closed.
The exception is thrown at the MoveTo() call in the example below.
public void CreateCheckedStructure() {
List<string> checkedDirNew = RemoveTempFolders(GetAllFromDir(Settings.Default.NewFolder));
List<string> checkedDirCurrent = RemoveTempFolders(GetAllFromDir(Settings.Default.CurrentFolder));
if (checkedDirNew.Count != 0 && checkedDirCurrent.Count != 0) {
MyLog.WriteToLog("Moving Checked Files", MyLog.Messages.Info);
foreach (string checkedNew in checkedDirNew) {
DirectoryInfo dirInfoNew = new DirectoryInfo(checkedNew);
foreach (string checkedCurrent in checkedDirCurrent) {
DirectoryInfo dirInfoCurrent = new DirectoryInfo(checkedCurrent);
if (dirInfoNew.Name.Equals(dirInfoCurrent.Name)) {
string checkedFoldersPath = Settings.Default.CheckedTables + "\\" + dirInfoCurrent.Name + "_" + DateTime.Now.ToString("hh-mm-ss");
Directory.CreateDirectory(checkedFoldersPath);
Directory.CreateDirectory(checkedFoldersPath + "\\New");
Directory.CreateDirectory(checkedFoldersPath + "\\Current");
dirInfoCurrent.MoveTo(checkedFoldersPath + "\\Current\\" + dirInfoNew.Name);
dirInfoNew.MoveTo(checkedFoldersPath + "\\New\\" + dirInfoCurrent.Name);
break;
}
}
}
MyLog.WriteToLog("All Checked Files have been moved", MyLog.Messages.Info);
} else { MyLog.WriteToLog("No Temporary Folder for Zips found",MyLog.Messages.Warning); }
}
you can try this extension method which I wrote to solve similar type of problem
public static async Task<bool> TryToAsync( Action action, int timeoutInSeconds )
{
var timeout = DateTime.Now.AddSeconds( timeoutInSeconds );
while ( DateTime.Now < timeout )
{
try
{
action();
return true;
}
catch ( Exception )
{
await Task.Delay( 200 );
}
}
return false;
}