I am trying to access the message store of an Exchange account.
I am using MAPI. The IMsgStore object is initialized using IMAPISession::OpenMsgStore.
The problem is that when using Exchange Cached Mode, the root folder for the 'Inbox' and Sent' is IPM_SUBTREE, while for online mesage store it is Top of Information Store.
How can I tell if the message store is located online or it is a local file path ?
I would like to be able to tell that from IMsgStore.
And another thing, do I have to supply the MDB_ONLINE to the IMAPISession::OpenMsgStore call if the message store is online?
This is how it looks now:
hRes = lpSession->OpenMsgStore( NULL,
storeEntryID.cb,
(LPENTRYID) storeEntryID.lpb,
&IID_IMsgStore,
/*MDB_ONLINE | */MDB_WRITE,
(LPMDB *)&msgStore);
Outlook 2010
Check the PR_STORE_OFFLINE property (true for OST, false for online online store).
EDIT
Use Store.PropertyAccessor.GetProperty. PR_STORE_OFFLINE property DASL name is
http://schemas.microsoft.com/mapi/proptag/0x6632000B
Related
I used Google People API v1.otherContacts.copyOtherContactToMyContactsGroup (reference) to copy a contact from "Other Contacts" to "myContacts" contact group. I now want to delete the original contact from "Other Contacts" using the same API.
REST Resource v1.otherContacts (reference) does not list a DELETE action.
I tried using v1.people.deleteContact (reference) passing the resource name of my "Other Contact":
import pickle
from googleapiclient.discovery import build
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
people_api = build('people', 'v1', credentials=creds)
people_service = people_api.people()
response = people_service.deleteContact(resourceName='otherContacts/c1971897568350947161').execute()
But I got an error saying:
TypeError: Parameter "resourceName" value "otherContacts/c1971897568350947161" does not match the pattern "^people/[^/]+$"
Looks like v1.people.deleteContact does not work for deleting a contact in "Other Contacts".
How can I programmatically delete a contact from "Other Contacts"?
EDIT: Based on #DaImTo's suggestion below, I tried replacing otherContacts/ in the resource name with people/ and invoking the v1.people.deleteContact API, but I got an error saying:
googleapiclient.errors.HttpError: <HttpError 404 when requesting https://people.googleapis.com/v1/people/c1971897568350947161:deleteContact?alt=json returned " generic::NOT_FOUND: Contact person resources are not found.". Details: "[{'#type': 'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations': [{'field': 'resourceNames[0]', 'description': 'Resource not found.'}]}]">
I advice consulting the documentation for people.deleteContact
Required. The resource name of the contact to delete.
DELETE https://people.googleapis.com/v1/{resourceName=people/*}:deleteContact
That means it should be people/c1971897568350947161 assuming that is the id of the user you want to delete c1971897568350947161.
Looks like Other Contacts are read only, according to this announcement from Google: https://developers.google.com/contacts/v3/announcement
The new People API has the same functionality as the legacy Contacts
API for all features, with the following exceptions for “Other
Contacts”:
Administrators have read-only permissions for “Other Contacts” through
the new scope. As sending mutate/write signals back to “Other
Contacts” is not supported, your users will have to add the Other
Contact as a My Contact if they wish to update its data fields.
I have a .NET application that interacts with Outlook like this:
Microsoft.Office.Interop.Outlook.Application app = new
Microsoft.Office.Interop.Outlook.Application();
Microsoft.Office.Interop.Outlook.MailItem item = app.CreateItem((Microsoft.Office.Interop.Outlook.OlItemType.olMailItem));
item.PropertyAccessor.SetProperty(PsInternetHeaders + Foobar, 1031);
item.BodyFormat = Microsoft.Office.Interop.Outlook.OlBodyFormat.olFormatHTML;
item.To = "a#test.com;b#test.com;c#test.com";
item.BCC = "cc#test.com";
item.Body = "Hello There!";
item.Display();
Be aware that I need to access the "PropertyAccessor" property.
In a normal environment this runs fine, but in a "secure" enviroment with this registry keys in place it just fails with Operation aborted (Exception from HRESULT: 0x80004004 (E_ABORT)):
[HKEY_CURRENT_USER\Software\Policies\Microsoft\office\16.0\outlook\security]
"PromptOOMAddressBookAccess"=dword:00000000
"AdminSecurityMode"=dword:00000003
"PromptOOMAddressInformationAccess"=dword:00000000
Outlooks security model seems to have a "trustedaddins" list, but I'm not really sure if this applies to "external applications" as well and that exactly I need to register unter TrustedAddins (see here).
My main question would be: Can I just register and foobar.exe unter trustedaddins or is this not possible at all?
I know that I could lower or disable the security stuff, but this is not my choice ;)
Your only options are listed at How to avoid Outlook Security Alert when sending Outlook message from VBScript?
You also might want to set PsInternetHeaders properties to strings only, not ints.
We are currently using MAPI to load contact information into a form.
Within a MapiSession we are creating a RDOAddressEntry "recepient" with this bit of code
using (MapiSession session = new MapiSession())
{
//open outlook contact dialog
RDOAddressEntry recipient = session.GetAddressEntryFromID(contact.EntryId);
if (recipient.Type == null)
{
throw new ArgumentException("type not defined");
}
recipient.Details(handle.ToInt32());
}
Our problem seems to be that the dialog that opens with the last line of code creates two different dialogs. One for exchange contacts and another one for SMTP contacts.
In the last version of our application it was always opening the same dialog for both RDOAddressEntry-types and we did NOT change anything in our code...
Can you help me fix this issue so that both SMTP and exchange will bring the same dialogs again?
I am not sure why you were getting the same dialog for both before - the dialog is actually provided by the particular address book provider, so it will be different for the entries from different providers.
When attachment is Email I could simply get the mime content and save it. But when the attachment is Contact I am not able to get the MimeContent. Here is the code
itemAttachment.Load(new PropertySet(ItemSchema.MimeContent));
MimeContent mc = itemAttachment.Item.MimeContent;
//Convert it to bytes
byte[] contentBytes = mc.Content;
When attachment is contact I am getting below exception
Microsoft.Exchange.WebServices.Data.ServiceResponseException occurred
HResult=-2146233088 Message=MIME conversion is not supported for
this item type. Source=Microsoft.Exchange.WebServices StackTrace:
at Microsoft.Exchange.WebServices.Data.ServiceResponse.InternalThrowIfNecessary()
at Microsoft.Exchange.WebServices.Data.ServiceResponse.ThrowIfNecessary()
at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest1.Execute()
at Microsoft.Exchange.WebServices.Data.ExchangeService.InternalGetAttachments(IEnumerable1
attachments, Nullable1 bodyType, IEnumerable1 additionalProperties,
ServiceErrorHandling errorHandling)
at Microsoft.Exchange.WebServices.Data.ExchangeService.GetAttachment(Attachment
attachment, Nullable1 bodyType, IEnumerable1 additionalProperties)
at Microsoft.Exchange.WebServices.Data.Attachment.InternalLoad(Nullable1
bodyType, IEnumerable1 additionalProperties)
at Microsoft.Exchange.WebServices.Data.ItemAttachment.Load(IEnumerable`1
additionalProperties)
at Presensoft.JournalEmailVerification.EmailVerification.DownloadFailedAttachments(EmailMessage
msg, JournalEmail journalEmail) in C:\Users\sameer\Presensoft\Email
Archiving\Presensoft.JournalEmailVerification\EmailVerification.cs:line
605 InnerException:
What is the proper way to download and save Contact attachment?
Saving as a contact in Exchange
Using MimeContent on a contact will not work because the server does not support the conversion. You can get MimeContent for a contact, you just can't save MimeContent as a contact.
Unfortunately there is no easy way to save an attached contact. What I would suggest is to manually clone the contact. Using EWS Managed API you can access the ItemAttachment as a contact. You would then need to create a new contact on the server, copy all the properties from the attached contact to the new contact using TryGetProperty(), then save the new contact.
I know it would make sense to just use the Save method on the contact object when you access the ItemAttachment. The problem is that there is a read only property on the object, IsAttachment, that is set to true and will not allow the object to be saved. If you try you will get an exception that this method is not available for attachments.
Saving as a .vcf file
If you are trying to save the contact to your local file system there are just a couple lines of code necessary.
itemAttachment.Load(ItemSchema.MimeContent);
File.WriteAllBytes("Contact.vcf", itemAttachment.Item.MimeContent.Content);
I hope this information helps. If this does resolve your problem, please mark the post as answered.
Thanks,
--- Bob ---
I am trying to send an email from a client PC (i.e. Windows) with an attachment and have the attachment saved to a local folder on the same client PC. I have looked at a couple of alternatives, such as MailDrop (email to dropbox) and Outlook 2003 Interop library - but want to make sure I am implementing this the best way.
Does anyone have any different ideas on a simple/elegant solution?
As long as you know Outlook will be installed on all the clients the Outlook solution works very well. You can create a file and save it, then in your outlook interop you just attach and send. You didn't specify what tools you are using but here's the basic email creation method I use for Outlook in C# (Where OutlookSetup.OutlookApp is just a static method that returns the currently open instance of the Outlook application or creates a new one if Outlook isn't open). Otherwise there are several examples here on SO of using SmtpClient to achieve similar ends.
public EmailMessage(EmailInfo emailInfo, string filenameToAttach=null)
{
Message = OutlookSetup.OutlookApp.CreateItem(OL.OlItemType.olMailItem);
Message.To = emailInfo.To;
Message.CC = emailInfo.Cc ?? "";
Message.Subject = emailInfo.Subject;
if (filenameToAttach != null)
{
Message.Attachments.Add(filenameToAttach);
}
}