InterIMAP, Viewing UNREAD IMAP mail and Downloading Attachments in C# - c#

I was wondering if anyone can help me on this cause its driving me mad trying get this working
I was working with the trail of mail.dll from http://www.lesnikowski.com/mail/ which is an extremely fantastic tool which unfortunately i cannot afford being a student (even though its around 150eur, its still very expensive to me :/) and this would be a small module in my thesis and my faculty cannot afford to buy these things for students either :/ so anyway I had to go for a free tool (so please dont suggest any non open source ones - trust me i have tried them ALL)..
Well, i'm trying to explore InterIMAP, and for several hours have been trying to list unread emails from my gmail account but it just doesn't seem to be working. I can connect just fine but finding the unread emails seems to be no easy task.. I have tried countless approaches but non seem to give me unread emails in my inbox (I have loads of emails in my inbox and i just want the unread ones). Would someone please assist me? I have been trying to get this working for ages now, but documentation is rather lacking and my every attempt has resulted in a fail so far.
Please help!!
Some code i currently have:
` IMAPConfig config = new IMAPConfig("myhost", "username", "pass", true, true, "");
config.CacheFile = "";
IMAPClient client = null;
try
{
client = new IMAPClient(config, null, 5);
}
catch (IMAPException e)
{
Console.WriteLine(e.Message);
return;
}
Console.WriteLine(DateTime.Now.ToString());
IMAPFolder f = client.Folders["INBOX"];
IMAPSearchResult sResult = f.Search(IMAPSearchQuery.QuickSearchNew()); // <--- Gives me no results even though i do have unread messages!

If you did't reach your goal, here we go:
You should code in the following way:
1st: Inside your SearchQuery class, add a new property "unread", for example.
2nd: Add a new Method that returns an IMAPSearchQuery. It'll quick search unread mails. Something like that:
public static IMAPSearchQuery QuickSearchUnread()
{
IMAPSearchQuery query = new IMAPSearchQuery();
query.unread = true;
return query;
}
3td: Inside your class IMAPFolder, you have a method called that will return an IMAPSearchResult type and that receives an IMAPSearchQuery as parameter.
This method "build" your query with IMAP command queries (IMAP based protocol).
To the Unread query you should add:
public IMAPSearchResult Search(IMAPSearchQuery query)
{
...
if (query.Unread)
searchTerms.Add("UNSEEN");
.
.
...
}
4th: Call the Search method with the new QuickSearch:
config.CacheFile = "";
IMAPClient client = null;
try
{
client = new IMAPClient(config, null, 5);
}
catch (IMAPException e)
{
Console.WriteLine(e.Message);
return;
}
Console.WriteLine(DateTime.Now.ToString());
IMAPFolder f = client.Folders["INBOX"];
IMAPSearchResult sResult = f.Search(IMAPSearchQuery.QuickSearchUnread());
Let me know about your progress.
I hope it can be helpful.
Bye.

I honestly just ended up using Mail.dll trial version as interIMAP was not working properly for me and way to slow because it indexes the emails for some reason :s

Related

Sharepoint 365 allowing me to only write two items then stops responding

Background; it was working with SP2013, but a supplier has switched to SP365.
Modifying the authentication using OfficeDevPnP.Core.AuthenticationManager, ClientID and ClientSecret I can get the access token. I can then do all the JSON reads I like, but it will only allow me to write two items to a list (orders), then it just times out. I restart the project and it does exactly the same. I can read the list to make sure the order hasn't been uploaded already, but when it comes to writing the third item it just throws timeout errors.
I updated the code to call for a new access token for each write and just get "Token Request Failed" after the second write.
Any thoughts on how to approach the supplier on config options, or change my approach?
Thanks in advance.
Found the answer, changing up the usage of GetAppOnlyAuthenticatedContext to something like this works wonders.
public void CreateListItemV2(string listName, QDS_WorkOrderEntry entry)
{
OfficeDevPnP.Core.AuthenticationManager authMgr = new OfficeDevPnP.Core.AuthenticationManager();
using (var context = authMgr.GetAppOnlyAuthenticatedContext(SPSiteUrl, "<clientid>", "<secret>"))
{
List list = context.Web.Lists.GetByTitle(listName);
var itemCreateInfo = new ListItemCreationInformation();
var newItem = list.AddItem(itemCreateInfo);
newItem["HHSDetails"] = entry.HHSDetails?.HHSDetailsId;
...
newItem.Update();
context.Load(newItem);
context.ExecuteQuery();
}
}

How to get the MessageId from all exchange items

Hello I recently got into development around EWS. One of the issue came up to me is that a client ask me to import emails into database and he wants to detect the duplicate based on InternetMessageID this way he doesn't have to import the duplicate emails and my code came up to this point.
private static string GetInternetMessageID(Microsoft.Exchange.WebServices.Data.Item email)
{
EmailMessage emailMsg = email as EmailMessage;
string returnId = string.Empty;
if ((emailMsg != null)) {
try {
emailMsg.Load();
//loads additional info, without calling this ToRecipients (and more) is empty
} catch (ArgumentException ex) {
//retry
email.Load();
}
returnId = emailMsg.InternetMessageId;
} else {
//what to do?
}
return returnId;
}
I can handle regular emails, but for special exchange objects such as contact, Calendar, Posts etc it does not work because it could not cast it to an EmailMessage object.
And I know you can extract the internetMessageId from those objects. Because the client used to have another software that extract this ID for them, maybe the property is not called internetMessageID, I think I probally have to extract it from the internetMessageHeader. However when ever I try to get it from the item object it just throws me an error. How do I get the internet messageID from these "Special" exchange items?
PS i am aware of item.id.UniqueID however that is not what I want as this id changes if I move items from folder to another folder in exchange
Only objects that have been sent via the Transport service will have an InternetMessageId so things like Contacts and Tasks because they aren't messages and have never been routed via the Transport service will never have an Internet MessageId. You probably want to look at using a few properties to do this InternetMessageId can be useful for messages PidTagSearchKey https://msdn.microsoft.com/en-us/library/office/cc815908.aspx is one that can be used (if you good this there are various examples of using this property).
If your going to use it in Code don't use the method your using to load the property on each item this is very inefficient as it will make a separate call for each object. Because these I'd's are under 256 Kb just retrieve then when using FindItems. eg
ExtendedPropertyDefinition PidTagSearchKey = new ExtendedPropertyDefinition(0x300B, MapiPropertyType.Binary);
ExtendedPropertyDefinition PidTagInternetMessageId = new ExtendedPropertyDefinition(0x1035, MapiPropertyType.String);
PropertySet psPropSet = new PropertySet(BasePropertySet.IdOnly);
psPropSet.Add(PidTagSearchKey);
psPropSet.Add(PidTagInternetMessageId);
ItemView ItemVeiwSet = new ItemView(1000);
ItemVeiwSet.PropertySet = psPropSet;
FindItemsResults<Item> fiRess = null;
do
{
fiRess = service.FindItems(WellKnownFolderName.Inbox, ItemVeiwSet);
foreach (Item itItem in fiRess)
{
Object SearchKeyVal = null;
if (itItem.TryGetProperty(PidTagSearchKey, out SearchKeyVal))
{
Console.WriteLine(BitConverter.ToString((Byte[])SearchKeyVal));
}
Object InternetMessageIdVal = null;
if (itItem.TryGetProperty(PidTagInternetMessageId, out InternetMessageIdVal))
{
Console.WriteLine(InternetMessageIdVal);
}
}
ItemVeiwSet.Offset += fiRess.Items.Count;
} while (fiRess.MoreAvailable);
If you need larger properties like the Body using the LoadPropertiesForItems Method https://blogs.msdn.microsoft.com/exchangedev/2010/03/16/loading-properties-for-multiple-items-with-one-call-to-exchange-web-services/

Searching user tasks by task.body text

Good morning all! I have spent a good bit of time searching and reading forums about this, but I can't seem to find a solution. Any help you all can offer is greatly appreciated.
I have created an Outlook Add-In via C# and Visual Studio 2013. This add-in will create a number of custom tasks, which is working. The problem I am having is searching for those custom created tasks and deleting them. I have code working to search based on a strict subject line, but nothing using "LIKE" to find partial search matches. I've also read that the find method cannot search the body, so then advanced search is better. I am trying to work with the advanced search documentation I can find, but am not sure of what the "scope" parameter would be for tasks, or even if this is the best solution.
I figured the best approach was to append all custom created tasks with a footer notated "DO NOT DELETE" and output text here that I could search to determine the task was created by my add-in and then delete it. I have also considered storing the custom task's EntryID at the time of creation, but have read that this number can change, so I am not sure this will be the best method to always find and delete the custom created tasks.
I am hoping one of you would be able to assist with a code sample of searching a user's task folder for all tasks containing a string in the body of the task. Alternatively, I can definitely work with a search of all tasks containing a string in the subject line. I am pulling my hair out over this, and I appreciate any guidance, articles, or code samples you all can provide! I either find examples in VB, or partial explanations that I am unable to put into practice.
EDIT: SOLVED
Thanks to the below response marked as an answer, I wanted to give more code detail here in case anybody needs a more detailed answer in the future. This solution does not search the body text as stated in this post title as that solution was not the best way to accomplish what I needed.
Creating the task
using Outlook = Microsoft.Office.Interop.Outlook;
Outlook.Application app = new Outlook.Application();
Outlook.TaskItem task = app.CreateItem(Outlook.OlItemType.olTaskItem) as Outlook.TaskItem;
Outlook.UserProperties taskUserProperties = null;
Outlook.UserProperty taskUserProperty = null;
try {
taskUserProperties = task.UserProperties;
taskUserProperty = taskUserProperties.Add("Custom Property Name", Outlook.OlUserPropertyType.olText, true, 1);
taskUserProperty.Value = "Custom value";
task.Save();
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
finally {
if (taskUserProperty != null) Marshal.ReleaseComObject(taskUserProperty);
if (taskUserProperties != null) Marshal.ReleaseComObject(taskUserProperties);
}
Finding it
string searchCriteria = "[Custom Property Name] = 'VALUE TO FIND'";
Outlook.Application app = new Outlook.Application();
Outlook._NameSpace ns = app.GetNamespace("MAPI");
Outlook.MAPIFolder folder = ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderTasks);
Outlook._TaskItem taskItem = null;
Outlook.Items folderItems = null;
object resultItem = null;
try {
folderItems = folder.Items;
folderItems.IncludeRecurrences = true;
if (folderItems.Count > 0) {
resultItem = folderItems.Find(searchCriteria);
if (resultItem != null) {
if (resultItem is Outlook._TaskItem) {
taskItem = resultItem as Outlook._TaskItem;
MessageBox.Show(taskItem.Subject, "Task found!", MessageBoxButtons.OK);
}
}
Marshal.ReleaseComObject(resultItem);
}
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
finally {
if (folderItems != null) Marshal.ReleaseComObject(folderItems);
}
Why not use the user properties (TaksItem.UserPropertiers.Add)?
If the user fields is added to the folder fields, you can search for that property using Items.Find/FindNext/Restrict.

How to update a test run in HP ALM via c#?

I can get connected to HP ALM via c# OTA no problem. It's what is supposed to happen next that isn't clear. I have looked all over HPs documentation for OTA but not much there in regards to updating a test run.
I can make a connection to ALM no problem. I then create a TestSetFactory and RunFactory. I don't know what to do from here. I'm trying to add a run for a particular test set in ALM. I want to add a run and set it to either Pass or Fail and add a comment.
TestSetFactory tsFactory = (TestSetFactory)qcConn.TestSetFactory;
RunFactory runFactory = (RunFactory)qcConn.RunFactory();
Does anyone know how to do this? Is there a previous post that I can't find? Please give me the link and I will happily go there.
If anyone else has figured this out can you please post your code?
Okay, after much trial and error I figured it out. I'm sure there are easier ways to do it but I haven't figured them out yet.
To create a run and update it's status and that of it's steps here's what you need to run:
//This assumes you are already connected to ALM and your project.
string testFolder = #"Root\whatever your folder name is";
TestSetFactory tstFactory = (TestSetFactory)qcConn.TestSetFactory;
TestSetTreeManager tsTreeMgr = (TestSetTreeManager)qcConn.TestSetTreeManager;
TestSetFolder tsFolder = (TestSetFolder)tsTreeMgr.get_NodeByPath(testFolder);
List tsList = tsFolder.FindTestSets("MyTestSet", false, null);
foreach (TestSet ts in tsList)
{
TestSetFolder tstFolder = (TestSetFolder)ts.TestSetFolder;
TSTestFactory tsTestFactory = (TSTestFactory)ts.TSTestFactory;
List mylist = tsTestFactory.NewList("");
foreach (TSTest tsTest in mylist)
{
RunFactory runFactory = (RunFactory)tsTest.RunFactory;
Run run = (Run)runFactory.AddItem("Name of your run here");
run.CopyDesignSteps();
run.Status = "Passed";
run.Post();
StepFactory stepFactory = (StepFactory)run.StepFactory;
dynamic stepList = stepFactory.NewList("");
var rstepList = (TDAPIOLELib.List)stepList;
foreach (dynamic rstep in rstepList)
{
rstep.Status = "Passed";
rstep.Post();
}
}
}

Lotus Note PassThruHTML

I’m trying to send an email using LOTUS NOTES with the help of “domino” dll (Programming language : C#).
I want to attach a mail signature into the body of email. I’m hoping to add a .jpg for the signature. I also have other email body formatting. Hence I have decided to use HTML for styling and attaching the signature. After browsing the web found out that in NotesRichTextStyle there is a property PassThruHTML. The legal values that can be given for it as per this link are (-1), (0), (255).
The ISSUE is that when I set (-1) the app popup a message saying that “Style value must be True, False, or STYLE_NO_CHANGE (YES, NO, or MAYBE for Java)”.
But in c sharp code it accepts only int values but not the values given in the popup.
Following is the C# code for the answer given by Ken Pespisa's reference link.
NotesSession LNSession = new NotesSession();
NotesDatabase LNDatabase = null;
NotesDocument LNDocument;
NotesMIMEEntity LNBody;
NotesStream LNStream;
NotesMIMEHeader LNHeader;
try
{
LNSession.Initialize(txtPassword.Text);
LNDatabase = LNSession.GetDatabase(txtServer.Text, txtUserName.Text, false);
LNStream = LNSession.CreateStream();
LNSession.ConvertMime = false;
//Create an email
LNDocument = LNDatabase.CreateDocument();
LNDocument.ReplaceItemValue("Form", "Memo");
LNBody = LNDocument.CreateMIMEEntity();
LNHeader = LNBody.CreateHeader("Subject");
LNHeader.SetHeaderVal("Add your subject here");
LNHeader = LNBody.CreateHeader("To");
LNHeader.SetHeaderVal("Give your recipient email address");
LNStream.WriteText("<html>");
LNStream.WriteText("<body bgcolor=\"blue\" text=\"white\">");
LNStream.WriteText("<table border=\"2\">");
LNStream.WriteText("<tr>");
LNStream.WriteText("<td>Hello World!</td>");
LNStream.WriteText("</tr>");
LNStream.WriteText("</table>");
LNStream.WriteText("</body>");
LNStream.WriteText("</html>");
LNBody.SetContentFromText(LNStream, "text/HTML;charset=UTF-8", MIME_ENCODING.ENC_IDENTITY_7BIT);
LNDocument.Send(false);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
If you're just sending email you should look at the NotesMimeEntity classes, and review this website for examples: http://www-01.ibm.com/support/docview.wss?uid=swg21098323
PassThruHTML won't help you much unless you're trying to display custom HTML in a browser when viewing a Notes document or form via Domino.

Categories