views:

418

answers:

3

I'm trying to write an Outlook 2007 VSTO add-in that lets you do some stuff with Sharepoint webservices. I'd really like to make it as simple as possible for the users; ideally, all that they would have to do is connect a Sharepoint list to Outlook. From there, my add-in would ideally grab the actual Sharepoint URL from the list and do its thing. Unfortunately, I can't seem to find where Outlook stores this information while running.

The best solution I've been able to find is to read in the files found in C:\Documents and Settings(username)\Local Settings\Application Data\Microsoft\Outlook*.sharing.xml.obi.

However, these files are only updated when you close Outlook. That means that the user would have to connect to the list, restart Outlook, and then things would work. I'd rather not have things get to that level.

It's almost like the information just magics its way into the sharing.xml.obi files. I've Googled, I've used OutlookSpy and in desperation I've used mfcmapi.exe, all to no avail. Where the heck does Outlook store this?

+2  A: 

You can use the object model (or direct MAPI calls) to query this information from the outlook folder. First use the .isSharePointFolder property to locate your folder. The URL of the SharePoint List in outlook is then stored as the subject of a "hidden" message in the associated contents table.

Bonus tip: If you are not using it already, get yourself a copy of the excellent OutlookSpy. It makes figuring this kind of stuff out so much easier.

Paul-Jan
Ohhh that's what it's called. About an hour after I posted I stumbled across the associated contents table while poking around with mfcmapi.exe, but the name wasn't descriptive enough for me to be able to Google it properly, and getting at it using PropertyAccessor.GetProperty() wasn't going to work (it's of type PT_OBJECT, and .net doesn't support retrieving those) Now all I need to do is find out how to get at it from a C# add-in.
Tacroy
I [i]think[/i] a Folder.GetTable using the olHiddenItems argument might get you access to the associated contents, but my only experience is with direct MAPI access, so I can't say for sure.
Paul-Jan
+1  A: 

With Paul-Jan's pointer, I've figured this out. Since I hate it when I only find indirect hints while googling, here's exactly the code you need:

    private string getSharepointURL(Microsoft.Office.Interop.Outlook.Folder SharepointFolder)
    {
        if (!SharepointFolder.IsSharePointFolder)
            throw new Exception("Cannot get the SharePoint URL of " + SharepointFolder.FullFolderPath + ", because it is not a SharePoint folder.");
        return (string)((object[])SharepointFolder.GetTable("", 1).FindRow("[From] = SharePoint").GetValues())[1];
    }

That may be the ugliest return statement I've ever written. Here's what it does:

  1. Calls Outlook.Folder.GetTable("",1). The first argument is a filter, which means "anything", and the second argument is equivalent to olHiddenItems. (I couldn't find the actual enumeration)
  2. Gets the next row of that table whose sender (the [From] field) is "SharePoint". The information we want is always held in this hidden message.
  3. Gets the values of that hidden message. This comes back as an object, but is secretly an object[].
  4. Casts the values to an object[].
  5. Gets the second item of the values, which is the url.
  6. Casts the url to a string.

Fortunately, you can do all these steps yourself in OutlookSpy. That was a real help in figuring out how to get at this precious nugget of information.

Tacroy
A: 

Well, here is what I use... (C#3/VS2008, Outlook2007)

Outlook.Folder folder = GetSomeSpFolder(); // requirement :)

// Things to look for here, not in the columns by default
// the values can be found in OutlookSpy or perhaps MSDN (haha)
// this value refers to the SP site (not the full URL)
var SHARING_REMOTE_STORE_UID = "http://schemas.microsoft.com/mapi/id/{00062040-0000-0000-C000-000000000046}/8A48001E";

var table = folder.GetTable("[From] = SharePoint", Outlook.OlTableContents.olHiddenItems);
// note: if table.EndOfTable is true then nothing found (not SP folder or horribly broken)
// setup columns to look through
table.Columns.RemoveAll();
table.Columns.Add(SHARING_REMOTE_STORE_UID);
var row = table.GetNextRow();
var siteURL = row[SHARING_REMOTE_STORE_UID];

Also check out http://msdn.microsoft.com/en-us/library/bb176406.aspx

Happy coding!

pst