Is there a way to synchronize Outlook local shared calendars with their Exchange vesion programatically?
I tried Namespace.SendAndReceive() but it seems it doesn't affect calendars...
Is there something I miss or is it just impossible ?
I would like to perform a "send" from my local shared calendar folder to his server folder.
(I know it is possible to work directly on the server version by unchecking "Download shared calendar" as showed here but I can't do this way)
EDIT :
Why do I try to force sync?
In my add-in, users create new appointments in a shared calendar, and then lauch a function that makes a HTTP request to a script working with EWS to get this exchange calendar. But as the new appointments aren't sent, the script communicating with EWS don't get new appointments.
I found out the "update folder" button in Send/Receive sends the folder to exchange server but looking at the folder object I don't find how to do it programatically...
I finally found a way to synchronize Outlook application's locally shared calendars with the exchange server version (actually it does a "send").
The VB.NET code below progratically opens each shared calendar and then simulate the click on "update calendar" button.
Dim app As New Outlook.Application
Dim ns As Outlook.NameSpace
Dim objExpl As Outlook.Explorer
Dim recip As Outlook.Recipient
Dim olPane As Outlook.NavigationPane
Dim olModule As Outlook.NavigationModule
Dim olGroup As Outlook.NavigationGroup
Dim navFoldersCount As Integer
ns = app.GetNamespace("MAPI")
objExpl = app.ActiveExplorer
For k = 1 To ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar).Folders.Count
Try
'Try catch allows to exclude non-shared calendars to work only with share ones
recip = ns.CreateRecipient(ns.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar).Folders.Item(k).Name)
recip.Resolve()
If recip.Resolved Then
objExpl.CurrentFolder = ns.GetSharedDefaultFolder(recip, Outlook.OlDefaultFolders.olFolderCalendar)
'accessing to the shared calendars creates their "Calendar - xxx#xxx.xxx" clone.
If Not objExpl Is Nothing Then
'Simulate the click on "UpdateFolder button
objExpl.CommandBars.ExecuteMso("UpdateFolder")
End If
End If
Catch
End Try
Next
olPane = ns.Application.ActiveExplorer.NavigationPane
olModule = olPane.Modules.GetNavigationModule(Outlook.OlNavigationModuleType.olModuleCalendar)
olGroup = olModule.NavigationGroups.GetDefaultNavigationGroup(Outlook.OlGroupType.olPeopleFoldersGroup)
'Removing calendar clones from the navigation pane
navFoldersCount = olGroup.NavigationFolders.Count
For i = navFoldersCount To 1 Step -1
If (olGroup.NavigationFolders.Item(i).DisplayName.Contains("Calendar - ")) Then
olGroup.NavigationFolders.Remove(olGroup.NavigationFolders.Item(i))
End If
Next
Related
I've written a C# application with .net framework. The purpose is to request data from an online spreadsheet app, do stuff with it, then send back updated data.
I think the best way to trigger the exe would be to use webhooks/callbacks, but I gather this would require runnning my program on a web sever with an external IP address.
Rather than periodically polling the spreadsheet app I would like the app to send emails to a specified account upon certain data changes. Upon receiving the email, VBA code checks that the email is from the app then runs the executable.
To run exe on receipt of email:
Private Sub Application_NewMail()
Dim path As String
Dim shl As Variant
path = "C:\Users\***\Desktop\SmartPlugin.exe"
shl = Shell(path, 1)
End Sub
How do I check the sender? The examples I found online loop through all emails but what I'm after is a method of returning the last email received.
Use Application.NewMailEx event instead - it passes the entry id of the new message as the parameter. Use that entry id to call Application.Session.GetItemfromID.
Got it working.
Private Sub Application_NewMail()
Dim objN As NameSpace
Dim objF As MAPIFolder
Set objN = GetNamespace("MAPI")
Set objF = objN.GetDefaultFolder(olFolderInbox)
Set mlItems = objF.Items
mlItems.Sort "CreationTime", True
Set mlItem = mlItems.Item(1)
Dim path As String
Dim shl As Variant
Dim sndString As String
sndString = CStr(mlItem.SenderName)
If InStr(1, sndString, "SmartSheet", vbTextCompare) > 0 Then
path = "C:\Users\Alex Rose\Desktop\SmartPlugin.exe"
shl = Shell(path, 1)
End If
End Sub
I have a task which i need to create a program that converts outlook email to pdf.
this is my code
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
NameSpace outlookNs = app.GetNamespace("MAPI");
MAPIFolder rootFolder = outlookNs.Stores["Blah"].GetRootFolder();
List<MailItem> mailItems = new List<MailItem>();
Folders subFolders = rootFolder.Folders;
foreach (Folder folder in subFolders)
{
if (folder.Name == "Inbox")
{
Items items = folder.Items;
foreach (object item in items)
{
if (item is MailItem)
{
MailItem mailItem = item as MailItem;
string fileName = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "New folder", mailItem.EntryID + mailItem.SenderName.Replace("/", "") + ".msg");
mailItem.SaveAs(fileName, Microsoft.Office.Interop.Outlook.OlSaveAsType.olMSG);
}
}
}
}
the code is working but the outlook contains thousands of email. The outlook prompt a message every 10 minutes similar to the screenshot below
is there a way to avoid getting the message? Programatically or a setting will do?
Basically, it's not related to the programming instead of it's related the outlook security settings.
For every version of outlook you can find the settings for this pop-up just follow the instruction on this blog.
You can do a setting in your out look.
Mine is outlook 2013.
File->options : a window opens
In the window select Trust Center
You can see a button Trust center Settings
Options in window changes. Select Programmatic access
UnCheck the radio button Never warn me about suspicious activity (not recommended)
Through program, you can change below registry settings:
Go to "HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\15.0\outlook\security"
Change below settings programatically:
PromptSimpleMAPISend -- 2
PromptSimpleMAPINameResolve -- 2
PromptSimpleMAPIOpenMessage -- 2
By default when outlook is installed, the above values comes with zero value. What I do in my program is, I turn them to "2" programatically just before sending the email and turn them back to zero later point of time.
I am using EWS for searching for and displaying emails. However the final step of the project is to save specific messages as .msg files on the file system. I understand that this is not possible with EWS, so I will need to use Interop.Outlook to accomplish this. My question is: What is the best way to find the Outlook message given the information available from EWS. I have attempted to associate the Message.Id and ConversationId obtained from exchange via EWS with Outlook's messageId but have so far been unsuccessful.
Here is my current (failed) code for finding the ConversationID:
OUTLOOK.Application olApp = new OUTLOOK.Application();
OUTLOOK.NameSpace olNS = olApp.GetNamespace("MAPI");
OUTLOOK.MAPIFolder oFolder = olNS.GetDefaultFolder(OUTLOOK.OlDefaultFolders.olFolderInbox);
OUTLOOK.Items oItems = oFolder.Items;
String sFilter = string.Format("#SQL=\"http://schemas.microsoft.com/mapi/proptag/0x1035001F\" = '{0}'", missive.ConversationID.UniqueId);
object obj = oItems.Find(sFilter);
OUTLOOK.MailItem oEmail = (OUTLOOK.MailItem)obj;
if (oEmail != null)
{
return oEmail;
}
else
{
throw new Exception("MAIL ITEM NOT IN OUTLOOK");
}
As a side: I was looking for a reference for Outlookd filters That is the property names for the [property]=value version; and the hex values for use with the #SQL version. Does someone have a link to a good reference for that?
There's a ConvertIdType request you can use; see: https://msdn.microsoft.com/en-us/library/office/bb856559(v=exchg.140).aspx.
For a listing of MAPI properties and their DASL names and property tag values, see: https://msdn.microsoft.com/en-us/library/office/cc815517.aspx. Although Outlook Spy is a great tool for this as well.
I'm using ExchangeServer 2010 SP2
and Outlook 2013
First I'm saving a Mail to the Draft folder using EWS
EmailMessage.Save()
After that I'm trying to open the mail via Interop
but I'm getting a COMException that the item doesn't exist
Outlook.Application app = new Outlook.Application();
Outlook.NameSpace mapi = app.GetNamespace("MAPI");
Outlook.MAPIFolder draftFolder = mapi.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderDrafts);
//Custom function to get EntryID
string entryId = GetMessageId(email,IdFormat.HexEntryId);
string storeId = draftFolder.StoreID;
MailItem item = null;
try
{
item = mapi.GetItemFromID(entryId, storeId);
}
catch (COMException)
{
//Item not found
}
Is there any way to force Outlook to sync the Draft folder with the Exchange server?
I have used
Session.SendAndRecieve(true)
but it doesn't show any effect and I can't find any other Interop functions doing the desired thing.
EDIT: When disabling Cache-Mode everything runs fine but as soon as I turn it on I have no clue how to force it to get the Message
Thank you very much!
You can either
wait until the sync finishes - use Namespace.SyncObjects collection, retrieve the first SyncObject object, call SyncObject.Start and wait for the SyncObject.SyncEnd event to fire.
On the Extended MAPI level (C++ or Delphi) or Redemption (I am its author, it wraps Extended MAPI and can be used in any language), open the message in the online mode by using the MAPI_NO_CACHE (0x200) flag (IMsgStore::OpenEntry in Extended MAPI or RDOStore.GetMessageFromID in Redemption).
I am using Outlook redemption to access all rules from outlook.
How could we get RDORules using Outlook Redemption in c# ?
I have tried accessing this using below code
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook._NameSpace ns = app.GetNamespace("MAPI");
Redemption.RDOSessionClass rdoSession = new Redemption.RDOSessionClass();
rdoSession.MAPIOBJECT = ns.MAPIOBJECT;
rdoSession.Stores.DefaultStore.Rules - Here Rules property not exist.
The reason is rdoSession.Stores.DefaultStore return RDOStore object and Rules property exist in RDOExchangeStore object.
and i am not able to access RDOExchangeStore object. cause store kind is
"skPstUnicode"
Is there any way to access RDORules ?
Could be a couple of things up here .. have you iterated through the stores to find the exchange store ? as it looks like that you are not connected to exchange or the default store is configured to be a PST.
Update: to Answer your extra questions.
You can use RDO directly against the Exchange Server i.e Out side of outlook as long as you are online
Redemption.RDOSession rdoSession = new Redemption.RDOSession();
Use the logon method on the RDOSession object.