Download sourcecode (804 kb)
Introduction
Outlook Logger is a console base application that scans your MS Outlook Inbox folder and saves the meta-data of your emails in MS Access database For Example: sender information, Email Subject, Attachments Count, Message sent and Receive time, Message Importance etc. Further it also saves the TO,CC,BCC information for each email in another table.
Application creates an outlook .msg and save i Emails directory. Emails are saved in sub-folders named as recieved date of emails.
Finally it moves Email from inbox to "Personal Folders\InBoxBackup" Folder.
Outlook Redemption has been used to get rid of Security Prompts in outlook.
Not a tough thing to do!! So move on...
Note: Following Steps to run application
---------------------------------------
1. Register redemption.dll (provided with code) using regsvr32 on your Computer.
2. Create Personal Folders\InBoxBackup Folder in outlook
Database Side:
Outlook logger stores the meta-data of emails in 'OutLook_DB.mdb' database that is located in \bin folder. Database contains the following four tables.
1) 'Outlook_logger_tmp' : Temporary Storage of EntryID of all emails in inbox.
2) 'Outlook_logger_message': Store Emails Meta-data as described above.
3) 'Outlook_logger_Recipients': Stores the information of Emails Recipients, as To,Bcc and CC.
4) 'Outlook_logger_Attachments': Attachments data of emails
EntryID is the property of Outlook that uniquely identifies each email (in a folder). I have appended sender email address to apply more uniqueness for example:
0000000094991EDBACA62B41A7E88CDEC57A942824002000-sajid.mahmood@hotmail
Every Email has its own ID and tracked against it. Linked in tables and also the .msg file name.
Functionality
a. NEW EMAILS IDENTIFICATION
-------------------------------
a) Delete All Recs from outlook_logger_tmp table.
b) Get EntryID for each email from Inbox in 'Outlook_logger_tmp'.
c) Compare EntryIDs in outlook_logger_tmp with 'Outlook_logger_message' table and identify New Emails (EntryIDs).
d) Save new EntryIDs in an ArrayList.
b. Start Processing each Email one by one
----------------------------------------------
a) Save Emails Meta-deta in outlook_logger_message table.
a) Save To,CC,BCC to 'OUTLOOK_LOGGER_RECIPIENTS' table.
b) Check if attachment then save the attachment metadata in 'OUTLOOK_LOGGER_ATTACHMENTS'.
c) Save Email File
d) Move Email in backup folder
Lets jump into source Code:
<FONT color=#0000ff></FONT>
<FONT color=#0000ff>
Sub</FONT><FONT size=2> Main()
</FONT><FONT color=#0000ff size=2>Try
</FONT><FONT size=2>
</FONT><FONT color=#008000 size=2>
</FONT><FONT size=2>
</FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> outlook_Profile </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2> = "Default Outlook Profile"
oApp = </FONT><FONT color=#0000ff size=2>New</FONT><FONT size=2> Outlook.Application()
oNS = oApp.GetNamespace("mapi")
oNS.Logon(outlook_Profile, , </FONT><FONT color=#0000ff size=2>False</FONT><FONT size=2>, </FONT><FONT color=#0000ff size=2>True</FONT><FONT size=2>)
destinationFolder = CurDir() & "\Emails"
</FONT><FONT color=#008000 size=2>
</FONT><FONT size=2>
BackUpFolder = ConfigurationSettings.AppSettings.Get("BackUpFolder")
</FONT><FONT color=#008000 size=2>
</FONT><FONT size=2>
conString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & CurDir() & "\OutLook_DB.mdb" & ";User Id=admin;Password=;"
dbCon = </FONT><FONT color=#0000ff size=2>New</FONT><FONT size=2> OleDbConnection(conString)
dbCon.Open()
</FONT><FONT color=#008000 size=2>
</FONT><FONT size=2>
mainCode()
</FONT><FONT color=#0000ff size=2>Catch</FONT><FONT size=2> ex </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> System.Exception
Console.WriteLine(ex.Message)
</FONT><FONT color=#0000ff size=2>Catch</FONT><FONT size=2> olkExp </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> COMException
Console.WriteLine(olkExp.Message)
</FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Try
</FONT><FONT size=2>
</FONT><FONT color=#0000ff size=2>If</FONT><FONT size=2> dbCon.State = ConnectionState.Open </FONT><FONT color=#0000ff size=2>Then
</FONT><FONT size=2>
dbCon.Close()
</FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>If
</FONT><FONT size=2>
oNS.Logoff()
</FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT>
<FONT size=2><P></FONT><FONT color=#0000ff size=2>Private</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT><FONT size=2> mainCode()</P><P></FONT><FONT color=#008000 size=2>'FIRST CHECK FOR DESTINATION FOLDER of Emails</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>If</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Not</FONT><FONT size=2> checkDirPath(destinationFolder) </FONT><FONT color=#0000ff size=2>Then</P></FONT><FONT size=2><P>Console.WriteLine("Destination directory " & destinationFolder & " - Not Accessable")</P><P></FONT><FONT color=#0000ff size=2>Exit</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>If</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Const</FONT><FONT size=2> olFolderInbox = 6</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> inboxFolder </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> Outlook.MAPIFolder = oNS.GetDefaultFolder(olFolderInbox)</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> sInboxItem </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>New</FONT><FONT size=2> Redemption.SafeMailItem()</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> inboxItems </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> Outlook.Items = inboxFolder.Items</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> rCurrentUser </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>New</FONT><FONT size=2> Redemption.SafeCurrentUser()</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> currentUserEmailAddr, insertQuery </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</P></FONT><FONT size=2><P></FONT><FONT color=#008000 size=2>'Get Current User Email Address</P></FONT><FONT size=2><P>currentUserEmailAddr = rCurrentUser.Address.ToLower</P><P>Console.WriteLine("Started Scanning Emails on : " & currentUserEmailAddr)</P><P></FONT><FONT color=#008000 size=2>'DELETE ALL MAILS EntryIDs DATA (OLD) FROM TEMP TABLE</P></FONT><FONT size=2><P>deleteTmpTable()</P><P></FONT><FONT color=#008000 size=2>'Store Inbox EntryIDs Emails in Tmp Table</P></FONT><FONT size=2><P>loadTmpTable(inboxItems)</P><P>Console.WriteLine("Total " & inboxItems.Count & " emails found in Inbox")</P><P></FONT><FONT color=#008000 size=2>'Store New Emails's EntryIDs </P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> mailIDs </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> ArrayList = getNewEntryIDs()</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> mailID </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> id </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</P></FONT><FONT size=2><P></FONT><FONT color=#008000 size=2>'Now Process Emails One by One</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>For</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Each</FONT><FONT size=2> mailID </FONT><FONT color=#0000ff size=2>In</FONT><FONT size=2> mailIDs</P><P></FONT><FONT color=#0000ff size=2>If</FONT><FONT size=2> inboxItems.Count <> 0 </FONT><FONT color=#0000ff size=2>Then</P></FONT><FONT size=2><P>sInboxItem.Item = inboxItems.GetFirst</P><P></FONT><FONT color=#0000ff size=2>Else</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Exit</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>For</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>If</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>While</FONT><FONT size=2> TypeName(sInboxItem.Item) <> "Nothing"</P><P>id = sInboxItem.EntryID & "-" & sInboxItem.SenderEmailAddress</P><P></FONT><FONT color=#0000ff size=2>If</FONT><FONT size=2> id = mailID </FONT><FONT color=#0000ff size=2>Then</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> msgRecvDate </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Date</FONT><FONT size=2> = </FONT><FONT color=#0000ff size=2>CDate</FONT><FONT size=2>(sInboxItem.ReceivedTime)</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> FolderName </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2> = DatePart(DateInterval.Year, msgRecvDate) & "-" & DatePart(DateInterval.Month, msgRecvDate) & "-" & DatePart(DateInterval.Day, msgRecvDate)</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> destSubFolder </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2> = destinationFolder & "\" & FolderName</P><P>MkFolder(destSubFolder)</P><P>logMessage(mailID, sInboxItem, currentUserEmailAddr, destSubFolder)</P><P></FONT><FONT color=#008000 size=2>'Save Recipients data</P></FONT><FONT size=2><P>saveRecipientsInfo(mailID, sInboxItem, "TO")</P><P>saveRecipientsInfo(mailID, sInboxItem, "CC")</P><P>saveRecipientsInfo(mailID, sInboxItem, "BCC")</P><P></FONT><FONT color=#008000 size=2>'Save Attachments Meta-Data</P></FONT><FONT size=2><P>saveAttachments(mailID, sInboxItem)</P><P></FONT><FONT color=#008000 size=2>'Save Message</P></FONT><FONT size=2><P>saveMessageFile(mailID, sInboxItem, destSubFolder)</P><P></FONT><FONT color=#008000 size=2>'Move Email to Backup Folder</P></FONT><FONT size=2><P>moveToBackup(sInboxItem)</P><P></FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>If</P></FONT><FONT size=2><P>sInboxItem.Item = inboxItems.GetNext()</P><P></FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>While</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Next</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT></P>
<P><FONT color=#0000ff size=2></FONT> </P><FONT color=#0000ff size=2><FONT size=2><P></FONT><FONT color=#0000ff size=2>Private</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT><FONT size=2> logMessage(</FONT><FONT color=#0000ff size=2>ByVal</FONT><FONT size=2> mailID </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2>, </FONT><FONT color=#0000ff size=2>ByRef</FONT><FONT size=2> sInboxItem </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> Redemption.SafeMailItem, </FONT><FONT color=#0000ff size=2>ByVal</FONT><FONT size=2> currentUserEmailAddr </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2>, </FONT><FONT color=#0000ff size=2>ByVal</FONT><FONT size=2> destSubFolder </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2>)</P><P></FONT><FONT color=#008000 size=2>
</FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2></FONT> </P><FONT color=#0000ff size=2><P><FONT color=#008000 size=2>
</FONT>Private</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT><FONT size=2> saveRecipientsInfo(</FONT><FONT color=#0000ff size=2>ByVal</FONT><FONT size=2> mailID </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2>, </FONT><FONT color=#0000ff size=2>ByRef</FONT><FONT size=2> sInboxItem </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> Redemption.SafeMailItem, </FONT><FONT color=#0000ff size=2>ByVal</FONT><FONT size=2> recipientType </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2>)</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> contactsLongStr </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>New</FONT><FONT size=2> ArrayList()</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> insertQuery </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> recipientsLine </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>If</FONT><FONT size=2> recipientType = "TO" </FONT><FONT color=#0000ff size=2>Then</P></FONT><FONT size=2><P>recipientsLine = sInboxItem.To</P><P></FONT><FONT color=#0000ff size=2>ElseIf</FONT><FONT size=2> recipientType = "CC" </FONT><FONT color=#0000ff size=2>Then</P></FONT><FONT size=2><P>recipientsLine = sInboxItem.CC</P><P></FONT><FONT color=#0000ff size=2>ElseIf</FONT><FONT size=2> recipientType = "BCC" </FONT><FONT color=#0000ff size=2>Then</P></FONT><FONT size=2><P>recipientsLine = sInboxItem.BCC</P><P></FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>If</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>If</FONT><FONT size=2> recipientsLine <> "" </FONT><FONT color=#0000ff size=2>Then</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> Contacts </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2> = Replace(recipientsLine, "'", "")</P><P>contactsLongStr = divideContacts(Contacts, 1000)</P><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> contactLine </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Dim</FONT><FONT size=2> cmd </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>New</FONT><FONT size=2> OleDbCommand()</P><P>cmd.Connection = dbCon</P><P></FONT><FONT color=#0000ff size=2>For</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Each</FONT><FONT size=2> contactLine </FONT><FONT color=#0000ff size=2>In</FONT><FONT size=2> contactsLongStr</P><P>insertQuery = "insert into OUTLOOK_LOGGER_RECIPIENTS (" & _</P><P>"MSG_ID, RECIPIENTS_EMAILADDR, TOORCCORBCC " & _</P><P>" ) values ('" & _</P><P>mailID & "','" & contactLine & "','" & recipientType & "')"</P><P>cmd.CommandText = insertQuery</P><P>cmd.ExecuteNonQuery()</P><P></FONT><FONT color=#0000ff size=2>Next</P></FONT><FONT size=2><P>cmd.Dispose()</P><P></FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>If</P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>End</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub
</FONT></P>
<P><FONT color=#0000ff size=2> </P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Private</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT><FONT size=2> saveAttachments(</FONT><FONT color=#0000ff size=2>ByVal</FONT><FONT size=2> mailID </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2>, </FONT><FONT color=#0000ff size=2>ByRef</FONT><FONT size=2> sInboxItem </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> Redemption.SafeMailItem)</P><P></FONT><FONT color=#008000 size=2>
</FONT></P>
<P><FONT color=#0000ff size=2> </P></FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Private</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT><FONT size=2> saveMessageFile(</FONT><FONT color=#0000ff size=2>ByVal</FONT><FONT size=2> mailID </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2>, </FONT><FONT color=#0000ff size=2>ByRef</FONT><FONT size=2> sInboxItem </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> Redemption.SafeMailItem, </FONT><FONT color=#0000ff size=2>ByVal</FONT><FONT size=2> destSubFolder </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>String</FONT><FONT size=2>)</P><P></FONT><FONT color=#008000 size=2>
</FONT><FONT size=2><P></FONT><FONT color=#0000ff size=2>Private</FONT><FONT size=2> </FONT><FONT color=#0000ff size=2>Sub</FONT><FONT size=2> moveToBackup(</FONT><FONT color=#0000ff size=2>ByRef</FONT><FONT size=2> sInboxItem </FONT><FONT color=#0000ff size=2>As</FONT><FONT size=2> Redemption.SafeMailItem)</P><P></FONT><FONT color=#008000 size=2>
Conclusion
Main theme behind writing this article was to develop an understanding of working with MS Outlook in .Net and use of Outlook Redemption to get rid of security prompts in Outlook, when emails are accessed outside MS-Outook (with service pack installed).
Author has Master's degree in Computer Science. Worked in VC++ earlier. Now working in .Net technologies.
Some Experience in Multimedia and E-Learning as well. Now a days he is developing software applications for Telecom and mobile sector.