mike950

I'm trying to use the SafeMailItem as an alternative to the OutlookMailItem, but Subject, ReceivedTime and Delete don't seem to be available to the Redemption SafeMailItem. Can anybody help me out Any help would be really appreciated.



Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

Sue Mosher - Outlook MVP

You should be able to get those directly from SafeMailItem.Item, e.g. SafeMailItem.Item.Subject. They're not properties subject to Outlook security.



Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

mike950

From SafeMailItem.Item I can only access Equals, GetHashCode, GetType and ToString e.g.

if (colIdea is Redemption.SafeMailItem)

{

Redemption.SafeMailItem oMsg = (Redemption.SafeMailItem)colIdea;

oMsg.Item....

How do I gain access to Subject, ReceivedTime and Delete





Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

Sue Mosher - Outlook MVP

Sorry, I was working in VB.NET with Option Strict set to custom (default for VSTO add-ins). I don't write C# code, and Reflection is not my strong suit, but that's the approach you'd use. This is how it might look in VB.NET:

Code Snippet

rt = oMsg.Item.GetType

s = rt.InvokeMember("Subject", Reflection.BindingFlags.GetProperty, Nothing, oMsg, Nothing).ToString

MessageBox.Show(s)

Of course, depending on how you are instantiating oMsg, you may have the original Outlook MailItem available, in which case, you just use its properties and methods, relying on Redemption only for the blocked members.





Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

mike950

What data types are rt and s meant to me



Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

Sue Mosher - Outlook MVP

rt = Type, s = String



Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

mike950

Apologies, I'm new to the Outlook and Redemption object models, and I don't understand how this is going to get me access to Subject and ReceivedTime and enable me to execute the Delete method.



Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

Sue Mosher - Outlook MVP

The Item object property of the Redemption Safe*Item is effectively a late bound object pointing to the original Outlook item. Because it's late bound, you need to use .NET reflection (System.Reflection) to access its properties or methods, as I showed with an example of getting the Subject value. Or, if your code connects the Safe*Item with an Outlook object model item like this:

mySafeMailItem.Item = myMailItem

then you can use the myMailItem object to return property values from that original Outlook.MailItem object and use mySafeMailItem for the properties that otherwise would trigger security prompts.





Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

mike950

Thanks, I am following what you are trying to do now. Do I use exactly the same procedure for the Delete method

Also, this code never returns true :

if (colIdea is Redemption.SafeMailItem)

Whereas the original code does :

if (colIdea is Microsoft.Office.Interop.Outlook.MailItem)

Any ideas why





Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

Sue Mosher - Outlook MVP

Great! For Delete or any other method, you'd change the second parameter to the correct binding flag.

Where does col(i) come from





Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

mike950

How do I know which binding flag to use Is there a different binding flag for properties and then another one for methods

Col(i) comes from the line below. So I'm guessing that I need to change this code from a collection of Outlook items to a collection of Redemption items If so, do you know how to do that

Microsoft.Office.Interop.Outlook.Items oItems = oInbox.Items





Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

Sue Mosher - Outlook MVP

Yes, just look at the enumeration that Intellisense displays when you use the method. As I said, Reflection is not my strong point, but I can at least pick from an enumeration.

There are a couple of different ways to work with Redemption items, depending on just what you want to accomplish (which you have not described in any detail). The standard technique to work with an individual message using SafeMailItem requires three steps:

  1. Return the message (Outlook.MailItem).
  2. Instantiate a new Redemption.SafeMailItem object.
  3. Assign the SafeMailItem.Item property to the message in #1.

Your code is doing only #1, but not yet #2 and #3. And this gets back to one of my earlier points: If you already have a MailItem, the one returned in #1, then you can use that object to get Subject, do Delete, etc. You don't need Redemption for that if you have the original Outlook.MailItem.

OTOH, if you want performant access to a large number of items, then spend some time on the Redemption web looking at RDO.

Bottom line: Without knowing what you're hoping to do with these items, it's hard to give you much guidance beyond how to use basic techniques.





Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

mike950

What I am trying to do is open the local inbox, put all the items in the inbox into a collection, and then loop through the collection, writing certain details about each email (such as SenderEmailAddress, Subject and ReceivedTime) to a table, and then moving each item to the Deleted Items folder before deleting everything from the Deleted Items folder. My code basically does this, I was just looking for a way to prevent the security alert through Redemption.

Here is my code as it is at the moment :

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Data.SqlClient;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using Microsoft.Office.Interop.Outlook;

using Redemption;

namespace OutlookInboxArchiver

{

public partial class Form1 : Form

{

int Mailitem = 0;

bool blnOnlyInvalidMessagesLeft = false;

bool blnOnlyInvalidMessagesLeftDeleted = false;

public Form1()

{

InitializeComponent();

}

private void btnGo_Click(object sender, EventArgs e)

{

DoSomeWork();

}

private void DoSomeWork()

{

try

{

#region create app

//programmatically start local Outlook

System.Diagnostics.Process proc = new System.Diagnostics.Process();

proc.StartInfo.FileName = "outlook.exe";

proc.Start();

Microsoft.Office.Interop.Outlook.Application oApp = new Microsoft.Office.Interop.Outlook.ApplicationClass();

//Get MAPI namespace

Microsoft.Office.Interop.Outlook.NameSpace oNS = oApp.GetNamespace("mapi");

string strUserName = System.Environment.UserName.ToString();

try

{

oNS.Logon(strUserName, System.Reflection.Missing.Value, false, true);

}

catch

{

throw new LogonException();

}

//Get Messages collection of Inbox

Microsoft.Office.Interop.Outlook.MAPIFolder oInbox = oNS.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);

try

{

Microsoft.Office.Interop.Outlook.MAPIFolder destfolderTest = oInbox.Folders["Archive"];

}

catch

{

throw new MissingFolderException();

}

Microsoft.Office.Interop.Outlook.MAPIFolder destfolder = oInbox.Folders["Archive"];

Microsoft.Office.Interop.Outlook.Items oItems = oInbox.Items;

int intTotalNumberOfItemsInInbox = oItems.Count;

if (intTotalNumberOfItemsInInbox == 0)

throw new NoMessagesException();

SqlConnection objConn = new SqlConnection();

objConn.ConnectionString = "server=e2bvsql4\\inst1; user id=datawriter; password=rover9; database=SurveyResults";

try

{

objConn.Open();

}

catch

{

throw new DatabaseException();

}

#endregion

for (int i = 0; i < oItems.Count; i++)

{

oItems = oInbox.Items;

int intInvalidItem = 0;

MoveMail(oItems, destfolder, objConn, intInvalidItem);

if (blnOnlyInvalidMessagesLeft == true)

{

lblStatus.ForeColor = System.Drawing.Color.Blue;

lblStatus.Text = "**Inbox messages successfully transferred**";

return;

}

if (i > 0)

{

i = 0;

}

}

#region close and catch blocks

objConn.Close();

//delete from deleted items folder

Microsoft.Office.Interop.Outlook.MAPIFolder oDeletedItems = oNS.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderDeletedItems);

Microsoft.Office.Interop.Outlook.Items oItems2 = oDeletedItems.Items;

for (int k = 0; k < oItems2.Count; k++)

{

oItems2 = oDeletedItems.Items;

int intInvalidItemDeleted = 0;

DeleteMail(oItems2, intInvalidItemDeleted);

if (blnOnlyInvalidMessagesLeftDeleted == true)

{

lblStatus.ForeColor = System.Drawing.Color.Blue;

lblStatus.Text = "**Inbox messages successfully transferred**";

return;

}

if (k > 0)

{

k = 0;

}

}

oNS.Logoff();

//Clean up

oApp = null;

oNS = null;

oItems = null;

lblStatus.ForeColor = System.Drawing.Color.Blue;

lblStatus.Text = "**Inbox messages successfully transferred**";

}

catch (LogonException)

{

lblStatus.ForeColor = System.Drawing.Color.Red;

lblStatus.Text = "**Outlook Logon Error**";

}

catch (MissingFolderException)

{

lblStatus.ForeColor = System.Drawing.Color.Red;

lblStatus.Text = "**Please create Archive folder within local Inbox folder**";

}

catch (NoMessagesException)

{

lblStatus.ForeColor = System.Drawing.Color.Red;

lblStatus.Text = "**There are no messages in the local Inbox to be transferred**";

}

catch (DatabaseException)

{

lblStatus.ForeColor = System.Drawing.Color.Red;

lblStatus.Text = "**Database Error**";

}

#endregion

}

private void DeleteMail(Microsoft.Office.Interop.Outlook.Items col, int intInvalidItemDeleted)

{

for (int j = 1; j < col.Count; j++)

{

int dd = col.Count;

if (j > dd)

{

return;

}

if (col[j] is Microsoft.Office.Interop.Outlook.MailItem)

{

Microsoft.Office.Interop.Outlook.MailItem oMsg = (Microsoft.Office.Interop.Outlook.MailItem)col[j];

oMsg.Delete();

}

else

{

intInvalidItemDeleted += 1;

if (col[j] is Microsoft.Office.Interop.Outlook.MeetingItem)

{

Microsoft.Office.Interop.Outlook.MeetingItem oMeeting = (Microsoft.Office.Interop.Outlook.MeetingItem)col[j];

oMeeting.Delete();

}

if (col[j] is Microsoft.Office.Interop.Outlook.AppointmentItem)

{

Microsoft.Office.Interop.Outlook.AppointmentItem oAppt = (Microsoft.Office.Interop.Outlook.AppointmentItem)col[j];

oAppt.Delete();

}

if (col[j] is Microsoft.Office.Interop.Outlook.ContactItem)

{

Microsoft.Office.Interop.Outlook.ContactItem oContact = (Microsoft.Office.Interop.Outlook.ContactItem)col[j];

oContact.Delete();

}

if (col[j] is Microsoft.Office.Interop.Outlook.DistListItem)

{

Microsoft.Office.Interop.Outlook.DistListItem oDist = (Microsoft.Office.Interop.Outlook.DistListItem)col[j];

oDist.Delete();

}

if (col[j] is Microsoft.Office.Interop.Outlook.JournalItem)

{

Microsoft.Office.Interop.Outlook.JournalItem oJournal = (Microsoft.Office.Interop.Outlook.JournalItem)col[j];

oJournal.Delete();

}

if (col[j] is Microsoft.Office.Interop.Outlook.NoteItem)

{

Microsoft.Office.Interop.Outlook.NoteItem oNote = (Microsoft.Office.Interop.Outlook.NoteItem)col[j];

oNote.Delete();

}

if (col[j] is Microsoft.Office.Interop.Outlook.PostItem)

{

Microsoft.Office.Interop.Outlook.PostItem oPost = (Microsoft.Office.Interop.Outlook.PostItem)col[j];

oPost.Delete();

}

if (col[j] is Microsoft.Office.Interop.Outlook.TaskItem)

{

Microsoft.Office.Interop.Outlook.TaskItem oTask = (Microsoft.Office.Interop.Outlook.TaskItem)col[j];

oTask.Delete();

}

if (intInvalidItemDeleted == col.Count)

{

blnOnlyInvalidMessagesLeftDeleted = true;

return;

}

}

}

}

private void MoveMail(Microsoft.Office.Interop.Outlook.Items col, Microsoft.Office.Interop.Outlook.MAPIFolder destfolder, SqlConnection objConn, int intInvalidItem)

{

string strInsertQuery = "";

#region loop

for (int i = 1; i < col.Count; i++)

//foreach (MailItem i in col)

{

//test line

//lblInfo1.Text = "Item " + i.ToString() + " of " + col.Count.ToString();

//test line

int dd = col.Count;

if (i > dd)

{

return;

}

if (colIdea is Redemption.SafeMailItem)

//if (colIdea is Microsoft.Office.Interop.Outlook.MailItem)

{

Redemption.SafeMailItem oMsg = (Redemption.SafeMailItem)colIdea;

//Microsoft.Office.Interop.Outlook.MailItem oMsg = (Microsoft.Office.Interop.Outlook.MailItem)colIdea;

Type rt = oMsg.Item.GetType();

string strSubject = rt.InvokeMember("Subject", System.Reflection.BindingFlags.GetProperty, null, oMsg, null).ToString();

string strReceivedTime = rt.InvokeMember("ReceivedTime", System.Reflection.BindingFlags.GetProperty, null, oMsg, null).ToString();

//subject

if ((strSubject == null) || (strSubject == ""))

{

strSubject = "blank";

}

else

{

//escape quotes in subject

strSubject = strSubject.Replace("'", "''");

}

//Microsoft.Office.Interop.Outlook.MailItem oMsg2 = oMsg.Reply();

//Microsoft.Office.Interop.Outlook.Recipient oRecipient = oMsg2.Recipients[1];

//string strSenderEmail = oRecipient.Address.ToString();

if (oMsg.ReceivedByName == null)

{

if (oMsg.SenderEmailAddress != null)

{

if (oMsg.SenderEmailAddress.IndexOf("'") != -1)

{

string strSenderName = oMsg.SenderEmailAddress.Replace("'", "''");

strInsertQuery = "INSERT INTO SeedingResults (SenderName, ReceivedTime, Subject) VALUES ('" + strSenderName + "','" + strReceivedTime + "','" + strSubject + "')";

}

else

{

strInsertQuery = "INSERT INTO SeedingResults (SenderName, ReceivedTime, Subject) VALUES ('" + oMsg.SenderEmailAddress.ToString() + "','" + strReceivedTime + "','" + strSubject + "')";

}

}

else

{

strInsertQuery = "INSERT INTO SeedingResults (SenderName, ReceivedTime, Subject) VALUES ('blank','" + strReceivedTime + "','" + strSubject + "')";

}

}

else

{

if (oMsg.SenderEmailAddress != null)

{

if (oMsg.SenderEmailAddress.IndexOf("'") != -1)

{

string strSenderName2 = oMsg.SenderEmailAddress.Replace("'", "''");

strInsertQuery = "INSERT INTO SeedingResults (ReceivedByName, SenderName, ReceivedTime, Subject) VALUES ('" + oMsg.ReceivedByName.ToString() + "','" + strSenderName2 + "','" + strReceivedTime + "','" + strSubject + "')";

}

else

{

strInsertQuery = "INSERT INTO SeedingResults (ReceivedByName, SenderName, ReceivedTime, Subject) VALUES ('" + oMsg.ReceivedByName.ToString() + "','" + oMsg.SenderEmailAddress.ToString() + "','" + strReceivedTime + "','" + strSubject + "')";

}

}

else

{

strInsertQuery = "INSERT INTO SeedingResults (ReceivedByName, SenderName, ReceivedTime, Subject) VALUES ('" + oMsg.ReceivedByName.ToString() + "','blank','" + strReceivedTime + "','" + strSubject + "')";

}

}

//write to database

SqlCommand objInsertCommand = new SqlCommand(strInsertQuery, objConn);

try

{

objInsertCommand.ExecuteNonQuery();

}

catch

{

throw new DatabaseException();

}

//oMsg.Move(destfolder);

//oMsg.Delete();

}

else

{

intInvalidItem += 1;

if(colIdea is Microsoft.Office.Interop.Outlook.MeetingItem)

{

Microsoft.Office.Interop.Outlook.MeetingItem oMeeting = (Microsoft.Office.Interop.Outlook.MeetingItem)colIdea;

oMeeting.Delete();

}

if (colIdea is Microsoft.Office.Interop.Outlook.AppointmentItem)

{

Microsoft.Office.Interop.Outlook.AppointmentItem oAppt = (Microsoft.Office.Interop.Outlook.AppointmentItem)colIdea;

oAppt.Delete();

}

if (colIdea is Microsoft.Office.Interop.Outlook.ContactItem)

{

Microsoft.Office.Interop.Outlook.ContactItem oContact = (Microsoft.Office.Interop.Outlook.ContactItem)colIdea;

oContact.Delete();

}

if (colIdea is Microsoft.Office.Interop.Outlook.DistListItem)

{

Microsoft.Office.Interop.Outlook.DistListItem oDist = (Microsoft.Office.Interop.Outlook.DistListItem)colIdea;

oDist.Delete();

}

if (colIdea is Microsoft.Office.Interop.Outlook.JournalItem)

{

Microsoft.Office.Interop.Outlook.JournalItem oJournal = (Microsoft.Office.Interop.Outlook.JournalItem)colIdea;

oJournal.Delete();

}

if (colIdea is Microsoft.Office.Interop.Outlook.NoteItem)

{

Microsoft.Office.Interop.Outlook.NoteItem oNote = (Microsoft.Office.Interop.Outlook.NoteItem)colIdea;

oNote.Delete();

}

if (colIdea is Microsoft.Office.Interop.Outlook.PostItem)

{

Microsoft.Office.Interop.Outlook.PostItem oPost = (Microsoft.Office.Interop.Outlook.PostItem)colIdea;

oPost.Delete();

}

if (colIdea is Microsoft.Office.Interop.Outlook.TaskItem)

{

Microsoft.Office.Interop.Outlook.TaskItem oTask = (Microsoft.Office.Interop.Outlook.TaskItem)colIdea;

oTask.Delete();

}

if (intInvalidItem == col.Count)

{

blnOnlyInvalidMessagesLeft = true;

return;

}

}

#endregion

}

}

}

}





Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

Sue Mosher - Outlook MVP

So this is an external application Please note that this forum is specifically for VSTO applications, including Outlook add-ins, which have a different security story from external automation programs. The forum for general Outlook programming issues is "down the hall" at http://www.microsoft.com/office/community/en-us/default.mspx dg=microsoft.public.outlook.program_vba.

I would suggest using RDO for that kind of bulk operation; see http://www.dimastr.com/redemption/rdo/default.htm





Re: Visual Studio Tools for Office Redemption equivalent objects to Outlook

mike950

This app will be running locally not externally.