Hi have been reading about form regions for the last week.I finally managed to create a new interacting form using windows controls (i deprecated forms with vbscript).In the end though i have to associate the new seperate form with a specific calendar from c# code...
but let's get to code...This is how i did it using outlook-vbscript forms.(using ofts):
private bool CreateCustomCalendar(string registryname, string newCalendarName, string outlookformpathandfilename)
{
app = this.Application;
Outlook.MAPIFolder primaryCalendar = (Outlook.MAPIFolder)
this.Application.ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderCalendar);
bool needFolder = true;
if (debugmode) writer.WriteToLog("RootCalendar :" + primaryCalendar.Name + " found");
Outlook.MAPIFolder personalCalendar = primaryCalendar
.Folders.Add(newCalendarName,
Outlook.OlDefaultFolders.olFolderCalendar);
personalCalendar.Name = newCalendarName;
if (debugmode) writer.WriteToLog("Creating Calendar stage1 complete");
//Access new calendar by its name that has the habit to append this computer only
bool notfound1 = true; bool notfound2 = true;
try
{
string mName = primaryCalendar.Folders[newCalendarName].Name;
if (debugmode) writer.WriteToLog("calendar accesible by name:" + mName);
notfound1 = false;
}
catch (SystemException sex)
{
throw;
}
Outlook.MAPIFolder setcalendar = primaryCalendar.Folders[newCalendarName];
if (debugmode) writer.WriteToLog("calendar is set");
PublishFormToPersonalFormsLibrary(setcalendar, outlookformpathandfilename, registryname, registryname, registryname, registryname + "version 1.0.0.1", "1.0.0.1", Application);
if (debugmode) writer.WriteToLog("Creating Calendar stage2 complete");
SetFolderDefaultForm_forappointments(setcalendar, "IPM.Appointment." + registryname, newCalendarName);
if (debugmode) writer.WriteToLog("Creating Calendar stage3 complete");
return needFolder;
}
void SetFolderDefaultForm_forappointments(Outlook.MAPIFolder fld, string msgClass, string displayname)
{
Outlook.PropertyAccessor objPA = fld.PropertyAccessor;
string strBaseType;
string strMsg;
int intLoc;
bool blnBadForm;
int i;
string PR_DEF_POST_MSGCLASS =
"http://schemas.microsoft.com/mapi/proptag/0x36E5001E";
string PR_DEF_POST_DISPLAYNAME =
"http://schemas.microsoft.com/mapi/proptag/0x36E6001E";
string[] arrSchema = { PR_DEF_POST_MSGCLASS, PR_DEF_POST_DISPLAYNAME };
string[] arrValues = { msgClass, displayname };
string[] arrErrors;
if (debugmode) writer.WriteToLog("prepared for setting default item");
try
{
objPA = fld.PropertyAccessor;
objPA.SetProperty(PR_DEF_POST_MSGCLASS, msgClass);
objPA.SetProperty(PR_DEF_POST_DISPLAYNAME, displayname);
if (debugmode) writer.WriteToLog("default folder set");
// arrErrors = objPA.SetProperties(arrSchema, arrValues);
}
catch (SystemException sex)
{
Console.WriteLine("This is catch with system exception : {0}", sex.ToString());
}
}
public void PublishFormToPersonalFormsLibrary(Outlook.MAPIFolder calendarfolder, string oftFilePath, string messageClass, string name, string displayName, string description, string version, Outlook.Application application)
{
object missing = System.Reflection.Missing.Value;
string existingVersion = "";
// try to create an existing Instance of the Form to check the current installed Version
try
{
// create atemplatefolder object
Outlook.MAPIFolder templateFolder = application.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderDrafts);
if (debugmode) writer.WriteToLog("templateFolder is set");
// we add our new object here
object existingItem = templateFolder.Items.Add(messageClass);
if (debugmode) writer.WriteToLog("added form " + messageClass + " as templates");
// did we installed the form
if (existingItem != null)
{
// yes, we did it before
// get the formdescription with latebinding
Type existingItemType = existingItem.GetType();
Outlook.FormDescription existingFormDescription = (Outlook.FormDescription)existingItemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, existingItem, null);
if (debugmode) writer.WriteToLog("formdescription allocated to existingformdescription");
// get the installed version
existingVersion = existingFormDescription.Version;
// discard the temporary item
object[] args = { Outlook.OlInspectorClose.olDiscard };
existingItemType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, existingItem, args);
if (debugmode) writer.WriteToLog("GarbageCollection");
}
}
catch (System.Exception ex)
{
}
// if the existing Version is equal, no need for publishing the form
// if (version == existingVersion) return;
// check, if the templatefile exists
if (!System.IO.File.Exists(oftFilePath)) throw new System.IO.FileNotFoundException("Form template could not be found!", oftFilePath);
// create the item from TemplateFile
object item = application.CreateItemFromTemplate(oftFilePath, missing);
if (debugmode) writer.WriteToLog("created item from template");
// get the FormDescription Property using LateBinding
Type itemType = item.GetType();
Outlook.FormDescription formDescription = (Outlook.FormDescription)itemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, item, null);
// Apply some Parameters to the Formdescription
formDescription.Name = name;
formDescription.DisplayName = displayName;
formDescription.Category = "uncategorized";
formDescription.Comment = description;
formDescription.Version = version;
if (debugmode) writer.WriteToLog("Set custom form and its properties");
// Publish Form to Personal Froms Library
//formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olPersonalRegistry );
formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olFolderRegistry, calendarfolder);
if (debugmode) writer.WriteToLog("associating complete");
}
the question is how to do it with form-regions(using .ofs)
any solutions\documentation would be welcomed.
Many thnx to the creators of stack-overflow for this great resource and all developers that altruistically contribute to our problems
I finally did it!!! the replacement code for outlook.addin item goes like this:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Outlook.Folder taskList =Application.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderTasks)
as Outlook.Folder;
Outlook.TaskItem taskItem = taskList.Items.Add(
"IPM.Task.twoformMssges") as Outlook.TaskItem;
taskItem.Subject = "IPM.Task.twoformMssges Created On " +
System.DateTime.Now.ToLongDateString();
taskItem.Save();
Outlook.MAPIFolder primarytaskfolder = (Outlook.MAPIFolder)
this.Application.ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderTasks);
Outlook.MAPIFolder settaskfolder = primarytaskfolder.Folders["testassociation"];
Outlook.Application app = this.Application;
string formpropstring= "twotabs";
// PublishFormToPersonalFormsLibrary(taskItem,settaskfolder, "c:\\" , "IPM.Task.twoformMssges",registryname, registryname,registryname + "version 0.0.0.1", "0.0.0.1", Application);
object missing = System.Reflection.Missing.Value;
string existingVersion = "";
try
{
if (taskItem != null)
{
Type existingItemType = taskItem.GetType();
Outlook.FormDescription existingFormDescription = (Outlook.FormDescription)existingItemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, taskItem, null);
//if (debugmode) writer.WriteToLog("formdescription allocated to existingformdescription");
// get the installed version
existingVersion = existingFormDescription.Version;
// discard the temporary item
object[] args = { Outlook.OlInspectorClose.olDiscard };
existingItemType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, taskItem, args);
//if (debugmode) writer.WriteToLog("GarbageCollection");
}
}
catch (System.Exception ex)
{
}
Type itemType = taskItem.GetType();
Outlook.FormDescription formDescription = (Outlook.FormDescription)itemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, taskItem, null);
// Apply some Parameters to the Formdescription
formDescription.Name = formpropstring;
formDescription.DisplayName = formpropstring;
formDescription.Category = "uncategorized";
formDescription.Comment = formpropstring;
formDescription.Version = "0.0.0.1";
//formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olPersonalRegistry );
formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olFolderRegistry, settaskfolder);
//if (debugmode) writer.WriteToLog("associating complete");
Outlook.PropertyAccessor objPA = settaskfolder.PropertyAccessor;
string strBaseType;
string strMsg;
int intLoc;
bool blnBadForm;
int i;
string PR_DEF_POST_MSGCLASS =
"http://schemas.microsoft.com/mapi/proptag/0x36E5001E";
string PR_DEF_POST_DISPLAYNAME =
"http://schemas.microsoft.com/mapi/proptag/0x36E6001E";
\\string[] arrSchema = { PR_DEF_POST_MSGCLASS, PR_DEF_POST_DISPLAYNAME };
\\string[] arrValues = { "IPM.Task.twoformMssges" , "testassociation" };
\\string[] arrErrors;
try
{
objPA = settaskfolder.PropertyAccessor;
objPA.SetProperty(PR_DEF_POST_MSGCLASS, "IPM.Task.twoformMssges");
objPA.SetProperty(PR_DEF_POST_DISPLAYNAME, "testassociation");
// if (debugmode) writer.WriteToLog("default folder set");
// arrErrors = objPA.SetProperties(arrSchema, arrValues);
}
catch (SystemException sex)
{
Console.WriteLine("This is catch with system exception : {0}", sex.ToString());
}
}
also required a couple of attributes(code in brackets) needs to be added
[Microsoft.Office.Tools.Outlook.FormRegionMessageClass("IPM.Task.twoformMssges")]
[Microsoft.Office.Tools.Outlook.FormRegionName("FormInVsto20136.msgclassregion1")]
public partial class msgclassregion1Factory{ blah blah blah ...
...and that does the trick
(I now wonder how to differentiate between save and update)
Related
I have the following code in C# .NET Core Windows 10:
public string getBrowser()
{
string browserName = "iexplore.exe";
using (RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey(#"\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice"))
{
if (userChoiceKey != null)
{
object progIdValue = userChoiceKey.GetValue("Progid");
if (progIdValue != null)
{
if (progIdValue.ToString().ToLower().Contains("chrome"))
browserName = "chrome.exe";
else if (progIdValue.ToString().ToLower().Contains("firefox"))
browserName = "firefox.exe";
else if (progIdValue.ToString().ToLower().Contains("opera"))
browserName = "opera.exe";
}
}
}
return browserName;
}
The problem is that
userChoiceKey
is always null.
I practically copy paste the path from the registry Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice
And still not working.
Any help will be highly appreciated.
Thanks in advance!
Try this:
internal string GetSystemDefaultBrowser()
{
string name = string.Empty;
RegistryKey regKey = null;
try
{
var regDefault = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.htm\\UserChoice", false);
var stringDefault = regDefault.GetValue("ProgId");
regKey = Registry.ClassesRoot.OpenSubKey(stringDefault + "\\shell\\open\\command", false);
name = regKey.GetValue(null).ToString().ToLower().Replace("" + (char)34, "");
if (!name.EndsWith("exe"))
name = name.Substring(0, name.LastIndexOf(".exe") + 4);
}
catch (Exception ex)
{
name = string.Format("ERROR: An exception of type: {0} occurred in method: {1} in the following module: {2}", ex.GetType(), ex.TargetSite, this.GetType());
}
finally
{
if (regKey != null)
regKey.Close();
}
return name;
}
Referring to the answer mentioned in the post:
Reading Outlook Mail with C#
This code works well for a single account, but the issue with the current code is that it reads the email of the default id which was set as the first one in the outlook app.
For example, if "abcxyz#outlook.com" is set as the first account and "decxyz#outlook.com" is set as the second one, then it reads the inbox of only the first id, i.e., "abcxyz#outlook.com". I tried doing some modifications in the code but it did not work. Below is my code:
public static void OutLookMailStart(string EmailID, string password)
{
Microsoft.Office.Interop.Outlook.Application app = null;
Microsoft.Office.Interop.Outlook._NameSpace ns = null;
Microsoft.Office.Interop.Outlook.PostItem item = null;
Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;
Microsoft.Office.Interop.Outlook.MAPIFolder subFolder = null;
Microsoft.Office.Interop.Outlook.MailItem mailItem = null;
try
{
app = new Microsoft.Office.Interop.Outlook.Application();
ns = app.GetNamespace("MAPI");
ns.Logon(EmailID, password, false, true);
inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
foreach (Object mail in inboxFolder.Items)
{
if ((mail as MailItem) != null && (mail as MailItem).UnRead == true)
{
// Email Subject
string Subject = (mail as MailItem).Subject.ToString();
if (Subject.Contains(FileDomain))
{
// Email Body
var ReplyText = ExtractReply(((mail as MailItem).Body.ToString()), FromTrimName);
}
// (mail as MailItem).UnRead = false;
(mail as MailItem).Save();
}
}
}
catch (System.Exception ex)
{
throw ex;
}
finally
{
ns.Logoff();
inboxFolder = null;
subFolder = null;
mailItem = null;
app = null;
}}
Any sort of help will be appreciated.
public static void OutLookMailStart(string EmailID, string password)
{
Microsoft.Office.Interop.Outlook.Application app = null;
Microsoft.Office.Interop.Outlook._NameSpace ns = null;
Microsoft.Office.Interop.Outlook.PostItem item = null;
Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;
Microsoft.Office.Interop.Outlook.MAPIFolder subFolder = null;
Microsoft.Office.Interop.Outlook.MailItem mailItem = null;
try
{
app = new Microsoft.Office.Interop.Outlook.Application();
ns = app.GetNamespace("MAPI");
ns.Logon(EmailID, password, true, true);
inboxFolder = ns.Folders[EmailID].Folders[2];
foreach (Microsoft.Office.Interop.Outlook.MailItem mailItemm in inboxFolder.Items)
{
if (mailItemm.UnRead) // I only process the mail if unread
{
// Email Subject
Console.WriteLine("Subject : {0}", mailItemm.Subject);
string Subject = mailItemm.Subject;
if (!string.IsNullOrEmpty(Subject) && !string.IsNullOrWhiteSpace(Subject))
{
if (Subject.Contains(FileDomain))
{
var SenderName = mailItemm.Sender.Name;
//Email Body
Console.WriteLine("Accounts: {0}", mailItemm.Body);
// Read All Attachements
var attachments = (mailItemm as MailItem).Attachments;
if (attachments != null && attachments.Count > 0)
{
for (int i = 1; i <= attachments.Count; i++)
{
attachments[i].SaveAsFile(tempFolderPath + (mailItemm as MailItem).Attachments[i].FileName);
}
}
}
}
}
}
}
catch (System.Exception ex)
{
throw ex;
}
finally
{
ns.Logoff();
inboxFolder = null;
subFolder = null;
mailItem = null;
app = null;
}
}
Using ExchangeService service
public static void Cloud_OutLookMailStart(string EmailID, string password, string StoreFilePath)
{
try
{
LogHelper.LogMessage("<----- Cloud_OutLookMailStart Start ----->");
DistributionReplyEntity ObjDistributionReplyEntity = new DistributionReplyEntity();
ObjDistributionReplyEntity.OutLookEmailID = EmailID;
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
service.Credentials = new WebCredentials(EmailID, password);
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
//service.Url = new Uri("https://IP/EWS/Exchange.asmx");
service.AutodiscoverUrl(EmailID, RedirectionUrlValidationCallback);
Microsoft.Exchange.WebServices.Data.Folder inbox = Microsoft.Exchange.WebServices.Data.Folder.Bind(service, WellKnownFolderName.Inbox);
var items = service.FindItems(
//Find Mails from Inbox of the given Mailbox
new FolderId(WellKnownFolderName.Inbox, new Mailbox(EmailID)),
//Filter criterion
// new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter[] {
// new SearchFilter.ContainsSubstring(ItemSchema.Subject, ConfigurationManager.AppSettings["ValidEmailIdentifier"].ToString()),
new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false),
// }),
//View Size as 15
new ItemView(50));
Console.WriteLine("Email {0}, unread Total Count{1}", EmailID, items.Count());
foreach (Item item in items)
{
EmailMessage email = EmailMessage.Bind(service, new ItemId(item.Id.UniqueId.ToString()));
if (!string.IsNullOrEmpty(email.Subject) && !string.IsNullOrWhiteSpace(email.Subject))
{
var subject = email.Subject.ToString();
String[] arr = subject.Split(' ');
String firstWord = arr[0];
if (firstWord != "Undeliverable:")
{
//PROCESS EMAIL MESSAGE
Console.WriteLine("Subject :{0}", email.Subject);
// TO
if (email.ToRecipients.Count > 0)
{
var propertySet = new PropertySet(ItemSchema.UniqueBody);
EmailMessage email2 = EmailMessage.Bind(service, email.Id, propertySet);
EmailMessage str = (EmailMessage)email2;
string str1 = str.UniqueBody.Text.ToString();
var EmailBody = ExtractReply(str1, "");
// string ReceiverEmail = email.ReceivedBy != null?email.ReceivedBy.Address:"" ;
// Email Body
// var subjectEmail = ExtractReply(email.Body.ToString(), email.ReceivedBy.Address);
Console.WriteLine("Body {0}", EmailBody.ToString()); // Body
ObjDistributionReplyEntity.EmailBody = EmailBody;
string maltipleTo = string.Empty;
foreach (var toemailid in email.ToRecipients)
{
if (string.IsNullOrEmpty(maltipleTo))
{
maltipleTo = toemailid.Address.ToString();
}
else
{
maltipleTo += ";" + toemailid.Address.ToString();
}
}
Console.WriteLine("TO {0}", maltipleTo.ToString()); // TO
ObjDistributionReplyEntity.ReplyTO = maltipleTo.ToString();
}
// CC
if (email.CcRecipients.Count > 0)
{
string maltipleCC = string.Empty;
foreach (var ccemailid in email.CcRecipients)
{
if (string.IsNullOrEmpty(maltipleCC))
{
maltipleCC = ccemailid.Address.ToString();
}
else
{
maltipleCC += ";" + ccemailid.Address.ToString();
}
}
Console.WriteLine("CC {0}", maltipleCC.ToString());
ObjDistributionReplyEntity.ReplyCC = maltipleCC.ToString();
}
// Form
if (email.Sender.Address != "")
{
ObjDistributionReplyEntity.ReplyForm = email.Sender.Address;
}
Console.WriteLine("Subject {0}", email.Subject.ToString()); // Subject
ObjDistributionReplyEntity.Subject = email.Subject.ToString();
ObjDistributionReplyEntity.TransactionsID = 0;
ObjDistributionReplyEntity.IsProjectRelated = 0;
string Subject = email.Subject;
ObjDistributionReplyEntity.ReceivedTime = email.DateTimeReceived;
var getSharePointFileUrl = GetAttachmentsFromEmail(service, item.Id, StoreFilePath, ObjDistributionReplyEntity.TransactionsID);
email.IsRead = true;
email.Update(ConflictResolutionMode.AlwaysOverwrite);
}
}
}
LogHelper.LogMessage("<----- Cloud_OutLookMailStart Start ----->");
}
catch (Exception ex)
{
LogHelper.LogError("OutLookMailStart -> Cloud_OutLookMailStart Exception");
LogHelper.LogError("Exception Message :" + ex.Message);
if (ex.InnerException != null)
{
LogHelper.LogError("Exception InnerException :" + ex.InnerException);
}
LogHelper.LogError("Exception StackTrace :" + ex.StackTrace);
LogHelper.LogError("OutLookMailStart -> Cloud_OutLookMailStart Exception");
}
}
public static string GetAttachmentsFromEmail(ExchangeService service, ItemId itemId, string StoreFilePath, Int64 TransactionsID)
{
try
{
LogHelper.LogMessage("<----- GetAttachmentsFromEmail Start ----->");
// Bind to an existing message item and retrieve the attachments collection.
// This method results in an GetItem call to EWS.
EmailMessage message = EmailMessage.Bind(service, itemId, new PropertySet(ItemSchema.Attachments));
List<ResponseMessage> ObjResponseMessage = new List<ResponseMessage>();
// Iterate through the attachments collection and load each attachment.
foreach (Attachment attachment in message.Attachments)
{
if (attachment is FileAttachment)
{
FileAttachment fileAttachment = attachment as FileAttachment;
// Load the attachment into a file.
// This call results in a GetAttachment call to EWS.
fileAttachment.Load(StoreFilePath + fileAttachment.Name);
string FileName = fileAttachment.Name;
LogHelper.LogMessage("OutLookMailStart In attachments File Name :" + FileName );
Console.WriteLine("File attachment name: " + fileAttachment.Name);
}
else // Attachment is an item attachment.
{
ItemAttachment itemAttachment = attachment as ItemAttachment;
// Load attachment into memory and write out the subject.
// This does not save the file like it does with a file attachment.
// This call results in a GetAttachment call to EWS.
itemAttachment.Load();
Console.WriteLine("Item attachment name: " + itemAttachment.Name);
}
}
}
catch (Exception ex)
{
LogHelper.LogError("OutLookMailStart -> GetAttachmentsFromEmail Exception");
LogHelper.LogError("Exception Message :" + ex.Message);
if (ex.InnerException != null)
{
LogHelper.LogError("Exception InnerException :" + ex.InnerException);
}
LogHelper.LogError("Exception StackTrace :" + ex.StackTrace);
LogHelper.LogError("OutLookMailStart -> GetAttachmentsFromEmail Exception"); ;
}
LogHelper.LogMessage("<----- GetAttachmentsFromEmail End ----->");
}
I'm trying to search my inbox and all subfolders for a given string in the subject line. I found the following code online(https://www.add-in-express.com/creating-addins-blog/2012/05/31/outlook-search-csharp-vbnet/), but it returns zero results which is not the expected result.
I looked at the filter under view settings in outlook for a given search term that returns results in the outlook explorer and got this query: "http://schemas.microsoft.com/mapi/proptag/0x0037001f" LIKE '%Ticket%'
When I plug that in to the below code I likewise get zero results.
When I use LINQ to query those folders(LINQ is too slow to be a real solution here) I can get results so I'm guessing I'm making a syntactical error with advancedsearch. It is hard to find examples of usage on the web. I will appreciate anyone that can help me.
private Search RunAdvancedSearch(Outlook._Application OutlookApp, string wordInSubject)
{
string advancedSearchTag = "New Search";
string scope = "Inbox";
string filter = "\"urn:schemas:mailheader:subject\" LIKE '%"+ wordInSubject +"%'";
Outlook.Search advancedSearch = null;
Outlook.MAPIFolder folderInbox = null;
Outlook.MAPIFolder folderSentMail = null;
Outlook.NameSpace ns = null;
try
{
ns = OutlookApp.GetNamespace("MAPI");
folderInbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
folderSentMail = ns.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderSentMail);
scope = "\'" + folderInbox.FolderPath +
"\',\'" + folderSentMail.FolderPath + "\'";
advancedSearch = OutlookApp.AdvancedSearch(
scope, filter, true, advancedSearchTag);
System.Diagnostics.Debug.WriteLine(advancedSearch.Results.Count);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "An exception is thrown!");
}
finally
{
if (advancedSearch != null) Marshal.ReleaseComObject(advancedSearch);
if (folderSentMail != null) Marshal.ReleaseComObject(folderSentMail);
if (folderInbox != null) Marshal.ReleaseComObject(folderInbox);
if (ns != null) Marshal.ReleaseComObject(ns);
}
return advancedSearch;
}
I was not waiting long enough for the results. When AdvancedSearch(which runs in a separate thread) is finished it fires off an event called AdvancedSearchComplete. I had to tell the code to handle the event in order to wait for the search to complete.
In RunAdvancedSearch I do this in the Try with this:
Application.AdvancedSearchComplete += Application_AdvancedSearchComplete;
Here is the whole thing.
string advancedSearchTag = "MY FOOFOO Search";
//SEARCH Function
Search RunAdvancedSearch(Outlook.Application Application, string wordInSubject)
{
string scope = "Inbox";
string filter = "urn:schemas:mailheader:subject LIKE \'%" + wordInSubject + "%\'";
Outlook.Search advancedSearch = null;
Outlook.MAPIFolder folderInbox = null;
Outlook.MAPIFolder folderSentMail = null;
Outlook.NameSpace ns = null;
try
{
ns = Application.GetNamespace("MAPI");
folderInbox = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
folderSentMail = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderSentMail);
scope = "\'" + folderInbox.FolderPath + "\',\'" +
folderSentMail.FolderPath + "\'";
advancedSearch = Application.AdvancedSearch(
scope, filter, true, advancedSearchTag);
Application.AdvancedSearchComplete += Application_AdvancedSearchComplete;
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "An eexception is thrown");
}
finally
{
if (advancedSearch != null) Marshal.ReleaseComObject(advancedSearch);
if (folderSentMail != null) Marshal.ReleaseComObject(folderSentMail);
if (folderInbox != null) Marshal.ReleaseComObject(folderInbox);
if (ns != null) Marshal.ReleaseComObject(ns);
}
return advancedSearch;
}
//Handle AdvancedSearchComplete event
void Application_AdvancedSearchComplete(Outlook.Search SearchObject)
{
Outlook.Results advancedSearchResults = null;
Outlook.MailItem resultItem = null;
System.Text.StringBuilder strBuilder = null;
try
{
if (SearchObject.Tag == advancedSearchTag)
{
advancedSearchResults = SearchObject.Results;
System.Diagnostics.Debug.WriteLine("Count: " + advancedSearchResults.Count);
if (advancedSearchResults.Count > 0)
{
strBuilder = new System.Text.StringBuilder();
strBuilder.AppendLine("Number of items found: " +
advancedSearchResults.Count.ToString());
foreach (MailItem item in advancedSearchResults)
{
System.Diagnostics.Debug.WriteLine(item.Subject);
}
for (int i = 1; i <= advancedSearchResults.Count; i++)
{
resultItem = advancedSearchResults[i] as Outlook.MailItem;
if (resultItem != null)
{
strBuilder.Append("#" + i.ToString());
strBuilder.Append(" Subject: " + resultItem.Subject);
strBuilder.Append(" \t To: " + resultItem.To);
strBuilder.AppendLine(" \t Date: " +
resultItem.SentOn.ToString());
Marshal.ReleaseComObject(resultItem);
}
}
if (strBuilder.Length > 0)
System.Diagnostics.Debug.WriteLine(strBuilder.ToString());
else
System.Diagnostics.Debug.WriteLine(
"There are no Mail items found.");
}
else
{
System.Diagnostics.Debug.WriteLine("There are no items found.");
}
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message, "An exception is occured");
}
finally
{
if (resultItem != null) Marshal.ReleaseComObject(resultItem);
if (advancedSearchResults != null)
Marshal.ReleaseComObject(advancedSearchResults);
}
}
private void btnOutlookSrch_Click(object sender, EventArgs e)
{
Outlook.Application OLook = new Outlook.Application();
RunAdvancedSearch(OLook, "Hello?");
}
Your filter is working good, use Application:
private Search RunAdvancedSearch(Outlook.Application OutlookApp, string wordInSubject)
https://msdn.microsoft.com/en-us/library/office/microsoft.office.interop.outlook.application.aspx
Read about using _Application and Application in msdn "Remarks". There is very well written.
I'm a newbie using c# and i need to create an extension that goes to a directory and retrieves info about the users like username, name and email.
This is the login validation method that i created and it's working.
public void MssValidateUserLDAP(string ssHostname, string ssBaseDN, string ssUsername, string ssPassword, out bool ssOk, out string ssErrorMessage) {
ssOk = false;
ssErrorMessage = string.Empty;
String ssBaseRDN = string.Empty; // stores user RDN for authentication
LdapConnection connection = new LdapConnection(ssHostname);
connection.AuthType = AuthType.Basic;
try
{
SearchRequest searchRequest = new SearchRequest();
// Search parameters
searchRequest.Scope = System.DirectoryServices.Protocols.SearchScope.OneLevel;
searchRequest.DistinguishedName = ssBaseDN;
searchRequest.Filter = ssUsername;
// cast the returned directory response as a SearchResponse object
SearchResponse searchResponse = (SearchResponse)connection.SendRequest(searchRequest);
// enumerate the entries in the search response
foreach (SearchResultEntry entry in searchResponse.Entries)
{
ssBaseRDN = entry.DistinguishedName;
ssOk = true;
}
if (ssBaseRDN != "")
{
connection.Bind(new NetworkCredential(ssBaseRDN, ssPassword));
}
else { ssOk = false; ssErrorMessage = "User not found"; }
}
catch (Exception e)
{
ssErrorMessage = e.GetType().Name + " " + e.Message;
ssOk = false;
}
}
This is what i was able to do, but it's not working and i can't find the reason behind that. Any help would be appreciated!
public void MssSearch(string ssUsername, string ssPassword, string ssPath, out RLUserRecordList ssUsers, out string ssErrorMessage) {
ssErrorMessage = "";
ssUsers = new RLUserRecordList(null);
try
{
RLUserRecordList aux = new RLUserRecordList();
DirectoryEntry rootEntry = new DirectoryEntry(ssPath,ssUsername,ssPassword);
DirectorySearcher searcher = new DirectorySearcher(rootEntry);
foreach(SearchResult result in searcher.FindAll())
{
RCUserRecord u = new RCUserRecord(Convert.ToString(result.Properties["cn"][0]));
aux.Append(u);
}
ssUsers = aux;
}
catch (Exception e){
ssErrorMessage = e.GetType().Name + " " + e.Message;
}
} // MssSearch
No matter what I do, before and after for title are always null. This is an item updated receiver in the meetings or event list
!
[public override void ItemUpdated(SPItemEventProperties properties)
{
Logger.LogDebug("MeetingCalendarEvents", "ItemUpdated(SPItemEventProperties properties)", "BEGIN");
base.ItemUpdated(properties);
try
{
base.EventFiringEnabled = false;
SPSite site = properties.Web.Site;
string sitename= properties.BeforeProperties\["Title"\].ToString();
SPWeb web = site.RootWeb.Webs\[sitename\];
web.AllowUnsafeUpdates = true;
string prefix = properties.BeforeProperties\["Title"\].ToString().Substring(0, 2);
web.Title = properties.AfterProperties\["Title"\].ToString();
DateTime eventDate = properties.AfterProperties.GetValueAsDateTime(MeetingsCommon.Constants.FIELDS_EVENTDATE_NAME);
if (eventDate != DateTime.MinValue)
{
string titleMeetingCalendarItem = eventDate.ToString("yyyyMMdd");
titleMeetingCalendarItem = string.Format("{0}{1}", prefix, titleMeetingCalendarItem);
properties.AfterProperties.SetAfterPropertyValue("Title", titleMeetingCalendarItem);
web.ServerRelativeUrl = "/" + titleMeetingCalendarItem;
}
web.Update();
web.AllowUnsafeUpdates = false;
base.EventFiringEnabled = true;
}
catch (Exception ex)
{
Logger.LogError("MeetingCalendarEvents", "ItemUpdated(SPItemEventProperties properties)", ex);
properties.ErrorMessage = ex.Message;
properties.Cancel = true;
}
finally
{
base.EventFiringEnabled = true;
}
Logger.LogDebug("MeetingCalendarEvents", "ItemUpdated(SPItemEventProperties properties)", "END");
}]
answer here:
http://www.synergyonline.com/Blog/Lists/Posts/Post.aspx?ID=122