|
|
I am building an application that stores information about activites related to customers. It's using .Net 3.5 Sp1, C#, WPF, LINQ etc. One thing I want to support is the ability to drag'n'drop a bunch of emails from Outlook and extract the subject, sender, time and body from each mail, and store them as an activity. From what I gather, this should be possible via the Microsoft.Office.Interop.Outlook assembly. Whenever I get a drop operation on my window that could be one or more emails dragged over, I want to query Outlook like this;
var ol = new Microsoft.Office.Interop.Outlook.Application(); var sel = ol.ActiveExplorer().Selection;
However, it gives me an System.AccessViolationException when I try to do this.
The strange thing is that I can easily subscribe to the NewMailEx event (for instance) and be notified when new mails arrive, this works without a problem. So what do I need to do in order to have Outlook allow me to access the current selection of mails in the ActiveExplorer() so that I can get at my selected items?
I am on Windows Vista 2007 Sp1, Office 2007 Ultimate, and my assemblies are signed if that matters.
|
|
Have you checked that there actually is an ActiveExplorer? You could see if Explorers.Count > 0 and if the count is only 1 then just use Explorers[1] rather than ActiveExplorer().
-- Ken Slovak [MVP - Outlook] http://www.slovaktech.com Author: Professional Programming Outlook 2007. Reminder Manager, Extended Reminders, Attachment Options. http://www.slovaktech.com/products.htm
"Rune Jacobsen" <Rune Jacobsen[ at ]discussions.microsoft.com> wrote in message news:622B16F9-188A-4774-8EF7-76CD77EE0806[ at ]microsoft.com...
[Quoted Text] >I am building an application that stores information about activites >related > to customers. It's using .Net 3.5 Sp1, C#, WPF, LINQ etc. One thing I want > to > support is the ability to drag'n'drop a bunch of emails from Outlook and > extract the subject, sender, time and body from each mail, and store them > as > an activity. From what I gather, this should be possible via the > Microsoft.Office.Interop.Outlook assembly. Whenever I get a drop operation > on > my window that could be one or more emails dragged over, I want to query > Outlook like this; > > var ol = new Microsoft.Office.Interop.Outlook.Application(); > var sel = ol.ActiveExplorer().Selection; > > However, it gives me an System.AccessViolationException when I try to do > this. > > The strange thing is that I can easily subscribe to the NewMailEx event > (for > instance) and be notified when new mails arrive, this works without a > problem. So what do I need to do in order to have Outlook allow me to > access > the current selection of mails in the ActiveExplorer() so that I can get > at > my selected items? > > I am on Windows Vista 2007 Sp1, Office 2007 Ultimate, and my assemblies > are > signed if that matters. > >
|
|
Hi Ken,
Thanks for your reply. I tried to do as you suggest right now - however, the app.Explorers property also throws the same exception, so I can't count them or access the array in the way you suggest.
It seems like Outlook hates my application, I just can't understand why I can subscribe to events, yet not be able to read basic information like this from the Application object.
(Btw, if I subscribe to events, they work - in my example subscribing to NewMailEx and recieving a new mail, I actually do get the event with the ID)
Any other ideas? I'm scratching my head...!
Thanks again!
Rune
"Ken Slovak - [MVP - Outlook]" wrote:
[Quoted Text] > Have you checked that there actually is an ActiveExplorer? You could see if > Explorers.Count > 0 and if the count is only 1 then just use Explorers[1] > rather than ActiveExplorer().
|
|
Definitely something I've never seen or heard of. Congratulations :)
If you use your application object and put a dot after it does intellisense show the objects that are exposed under Application such as Explorers and Inspectors, etc. ?
You are referencing the correct version of Office as installed on your dev machine and it's the earliest version of Office you want to support? Are the PIA's for that version of Office installed?
-- Ken Slovak [MVP - Outlook] http://www.slovaktech.com Author: Professional Programming Outlook 2007. Reminder Manager, Extended Reminders, Attachment Options. http://www.slovaktech.com/products.htm
"Rune Jacobsen" <RuneJacobsen[ at ]discussions.microsoft.com> wrote in message news:6C0D9707-1575-4E8A-B340-45CE8F56909D[ at ]microsoft.com...
[Quoted Text] > Hi Ken, > > Thanks for your reply. I tried to do as you suggest right now - however, > the > app.Explorers property also throws the same exception, so I can't count > them > or access the array in the way you suggest. > > It seems like Outlook hates my application, I just can't understand why I > can subscribe to events, yet not be able to read basic information like > this > from the Application object. > > (Btw, if I subscribe to events, they work - in my example subscribing to > NewMailEx and recieving a new mail, I actually do get the event with the > ID) > > Any other ideas? I'm scratching my head...! > > Thanks again! > > Rune
|
|
Ken,
Thanks, I feel honored! :)
I am guessing this should "just work" then, since both Outlook 2007 and my app is running as the same user? No need to do any fancy login or anything like that, just create a new Application object?
Intellisense kicks in on my Application object, so it is definately recognizing the object type.
All my users will be on Outlook 2007 and Vista (Same as me), so that should hopefully save me some hassle (once I get it to work).
I should note that I am currently referencing Microsoft.Office.Core / Microsoft.Office.Interop.Outlook through the Microsoft Office 12.0 Object Library - found in the COM tab of the Add Reference dialog box, and the dll files referenced are in the GAC. I have also tried to do this with the Microsoft.Office.Interop.Outlook (v12.0.0.0) found in the .NET tab and installed as \Microsoft Visual Studio 9.0\Visual Studio Tools for Office\PIA\Office12\Microsoft.Office.Interop.Outlook.dll - with exactly the same result.
I will try to make a new project that does only this from scratch - a C# console app, to keep it simple - and report back if that makes a difference. However, if you have any further suggestions, I would really appreciate it; If the weekend comes without me figuring this out, I suspect my boss will find a pretty blunt object to beat me with. ;)
Thanks very much for helping out so far!
Rune
"Ken Slovak - [MVP - Outlook]" wrote:
[Quoted Text] > Definitely something I've never seen or heard of. Congratulations :) > > If you use your application object and put a dot after it does intellisense > show the objects that are exposed under Application such as Explorers and > Inspectors, etc. ? > > You are referencing the correct version of Office as installed on your dev > machine and it's the earliest version of Office you want to support? Are the > PIA's for that version of Office installed? >
|
|
Hi again,
Just a quick followup with the test project I created. I referenced the COM Interop library (which automatically included both Microsoft.Office.Core and Microsoft.Office.Interop.Outlook for me), and my console app consists of this single class (probably messed up formatting wise):
using System; using System.Collections.Generic; using System.Linq; using System.Text;
using Microsoft.Office.Interop.Outlook;
namespace OutlookTest { class Program { static void Main(string[] args) { var app = new Application(); Console.WriteLine("{0} selected", app.ActiveExplorer().Selection.Count); } } }
The app object is created, and it throws the exception on the WriteLine. If I check the app object with the debugger, I see that almost every property causes the same exception as I get in my real application.
I really don't have a clue what to do to get it to behave, so any tips would be highly appreciated!
Thanks!
Rune
"Ken Slovak - [MVP - Outlook]" wrote:
[Quoted Text] > Definitely something I've never seen or heard of. Congratulations :) > > If you use your application object and put a dot after it does intellisense > show the objects that are exposed under Application such as Explorers and > Inspectors, etc. ? > > You are referencing the correct version of Office as installed on your dev > machine and it's the earliest version of Office you want to support? Are the > PIA's for that version of Office installed?
|
|
Try fully qualifying the reference and making the objects class level, plus since it's an external app set up NameSpace. See if this works:
using System; using System.Collections.Generic; using System.Linq; using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace OutlookTest { private Outlook.Application _app = null; private Outlook.NameSpace _ns = null;
class Program { static void Main(string[] args) { _app = new Outlook.Application; _ns = _app.GetNameSpace("MAPI"); _ns.Logon("", "", false, false);
Console.WriteLine("{0} selected", app.ActiveExplorer().Selection.Count.ToString()); } } }
-- Ken Slovak [MVP - Outlook] http://www.slovaktech.com Author: Professional Programming Outlook 2007. Reminder Manager, Extended Reminders, Attachment Options. http://www.slovaktech.com/products.htm
"Rune Jacobsen" <RuneJacobsen[ at ]discussions.microsoft.com> wrote in message news:BAE51621-38AB-4FC4-B44D-D777757E50D9[ at ]microsoft.com...
[Quoted Text] > Hi again, > > Just a quick followup with the test project I created. I referenced the > COM > Interop library (which automatically included both Microsoft.Office.Core > and > Microsoft.Office.Interop.Outlook for me), and my console app consists of > this > single class (probably messed up formatting wise): > > using System; > using System.Collections.Generic; > using System.Linq; > using System.Text; > > using Microsoft.Office.Interop.Outlook; > > namespace OutlookTest > { > class Program > { > static void Main(string[] args) > { > var app = new Application(); > Console.WriteLine("{0} selected", > app.ActiveExplorer().Selection.Count); > } > } > } > > The app object is created, and it throws the exception on the WriteLine. > If > I check the app object with the debugger, I see that almost every property > causes the same exception as I get in my real application. > > I really don't have a clue what to do to get it to behave, so any tips > would > be highly appreciated! > > Thanks! > > Rune
|
|
Ken,
Thanks for following up!
I tried to do as you suggested, and reduce this to the simplest possible C# console application. Here is the complete source code for my mega advanced application:
using System; using System.Collections.Generic; using System.Linq; using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace OutlookTest { class Program { private static Outlook.Application app = null; private static Outlook.NameSpace ns = null;
static void Main(string[] args) { app = new Outlook.Application(); ns = app.GetNamespace("MAPI"); ns.Logon("", "", false, false);
Console.WriteLine("{0} selected", app.ActiveExplorer().Selection.Count); } } }
However, on the Console.WriteLine line I still get the System.AccessViolationException. It also says something about reading/writing to/from corrupted memory - not sure about the exact English wording as I get the error message already translated to my native norwegian.
So, this is strange, right? Shouldn't this just work? :)
Thanks again!
"Ken Slovak - [MVP - Outlook]" wrote:
[Quoted Text] > Try fully qualifying the reference and making the objects class level, plus > since it's an external app set up NameSpace. See if this works: > > using System; > using System.Collections.Generic; > using System.Linq; > using System.Text; > > using Outlook = Microsoft.Office.Interop.Outlook; > > namespace OutlookTest > { > private Outlook.Application _app = null; > private Outlook.NameSpace _ns = null; > > class Program > { > static void Main(string[] args) > { > _app = new Outlook.Application; > _ns = _app.GetNameSpace("MAPI"); > _ns.Logon("", "", false, false); > > Console.WriteLine("{0} selected", > app.ActiveExplorer().Selection.Count.ToString()); > } > } > } > > -- > Ken Slovak > [MVP - Outlook] > http://www.slovaktech.com> Author: Professional Programming Outlook 2007. > Reminder Manager, Extended Reminders, Attachment Options. > http://www.slovaktech.com/products.htm
|
|
It is odd. I'd probably go a little deeper to try to find out where exactly that code is failing. See what happens with something like this:
namespace OutlookTest { class Program { private static Outlook.Application app = null; private static Outlook.NameSpace ns = null;
static void Main(string[] args) { app = new Outlook.Application(); ns = app.GetNamespace("MAPI"); ns.Logon("", "", false, false);
try { Outlook.Explorer exp = app.ActiveExplorer(); Console.WriteLine("{0} selected", exp.Selection.Count); } catch (Exception ex) { Console.WriteLine(err.Message); if (app.Explorers.Count > 0) { Console.WriteLine("Explorers.Count == " + app.Explorers.Count.ToString()); } } } } }
Do you get the same error if you don't have Outlook already running as when you do have it already running when your code executes?
-- Ken Slovak [MVP - Outlook] http://www.slovaktech.com Author: Professional Programming Outlook 2007. Reminder Manager, Extended Reminders, Attachment Options. http://www.slovaktech.com/products.htm
"Rune Jacobsen" <RuneJacobsen[ at ]discussions.microsoft.com> wrote in message news:8780C962-FA97-4107-AAB7-A35611880E9A[ at ]microsoft.com...
[Quoted Text] > Ken, > > Thanks for following up! > > I tried to do as you suggested, and reduce this to the simplest possible > C# > console application. Here is the complete source code for my mega advanced > application: > > using System; > using System.Collections.Generic; > using System.Linq; > using System.Text; > > using Outlook = Microsoft.Office.Interop.Outlook; > > namespace OutlookTest > { > class Program > { > private static Outlook.Application app = null; > private static Outlook.NameSpace ns = null; > > static void Main(string[] args) > { > app = new Outlook.Application(); > ns = app.GetNamespace("MAPI"); > ns.Logon("", "", false, false); > > Console.WriteLine("{0} selected", > app.ActiveExplorer().Selection.Count); > } > } > } > > However, on the Console.WriteLine line I still get the > System.AccessViolationException. It also says something about > reading/writing > to/from corrupted memory - not sure about the exact English wording as I > get > the error message already translated to my native norwegian. > > So, this is strange, right? Shouldn't this just work? :) > > Thanks again!
|
|
Ken,
Thanks again for following up, and sorry about the late reply, have spent a few days getting beaten up by customers on site. ;)
I tried pasting your code into VS directly (just fixing the little ex -> err thing), and the following happens when Outlook is running;
1. I can actually get the Explorer object using app.ActiveExplorer(); However, this object gives me access violations on most of its' properties.
2. exp.Selection causes a System.AccessViolationException
3. The ex.Message is "Forsøk på lesing fra eller skriving til beskyttet minne. Dette er ofte en indikasjon på at annet minne er ødelagt." - this is the same message I get all the time, basically. It is a norwegian translation that roughly means "Attempt at reading from or writing to protected memory. This is often an indication that other memory is broken".
4. Inside the catch block, the if statement throws with the same exception on the app.Explorers object.
If I repeat the process with Outlook not running when I start the app in debug mode (and usually having to kill the Outlook process as it refuses to die on its own), app.ActiveExplorer() returns null, so I get a null reference exception on exp.Selection. app.Explorers still returns the same System.AccessViolationException.
Please note that I have tried to set macro security to "No security control for macros" just to see if that would make a difference - and it didn't.
Any other ideas? I can experiment wildly with this developer machine if you need me to. :)
Thanks again,
Rune
"Ken Slovak - [MVP - Outlook]" wrote:
[Quoted Text] > It is odd. I'd probably go a little deeper to try to find out where exactly > that code is failing. See what happens with something like this: > > namespace OutlookTest > { > class Program > { > private static Outlook.Application app = null; > private static Outlook.NameSpace ns = null; > > static void Main(string[] args) > { > app = new Outlook.Application(); > ns = app.GetNamespace("MAPI"); > ns.Logon("", "", false, false); > > try > { > Outlook.Explorer exp = app.ActiveExplorer(); > Console.WriteLine("{0} selected", exp.Selection.Count); > } > catch (Exception ex) > { > Console.WriteLine(err.Message); > if (app.Explorers.Count > 0) > { > Console.WriteLine("Explorers.Count == " + > app.Explorers.Count.ToString()); > } > } > } > } > } > > Do you get the same error if you don't have Outlook already running as when > you do have it already running when your code executes? > > -- > Ken Slovak > [MVP - Outlook] > http://www.slovaktech.com> Author: Professional Programming Outlook 2007. > Reminder Manager, Extended Reminders, Attachment Options. > http://www.slovaktech.com/products.htm
|
|
Well, if this happens on more than one machine I'd rule out a bad memory stick. Otherwise if this was limited to one machine I'd go for a possible hardware problem.
For the starting Outlook using code if no UI is shown then obviously ActiveExplorer() is going to be null unless you add UI. But if you're getting the same access violation on the Explorers collection then it's not that.
I'm not sure why you're getting access violations, I haven't run into that. I'm afraid my only suggestion at this point is to open a case with MS support and see what they turn up as a possible cause.
-- Ken Slovak [MVP - Outlook] http://www.slovaktech.com Author: Professional Programming Outlook 2007. Reminder Manager, Extended Reminders, Attachment Options. http://www.slovaktech.com/products.htm
"Rune Jacobsen" <RuneJacobsen[ at ]discussions.microsoft.com> wrote in message news:55B478B5-13BC-43FA-9A5A-B865474A4585[ at ]microsoft.com...
[Quoted Text] > Ken, > > Thanks again for following up, and sorry about the late reply, have spent > a > few days getting beaten up by customers on site. ;) > > I tried pasting your code into VS directly (just fixing the little ex -> > err > thing), and the following happens when Outlook is running; > > 1. I can actually get the Explorer object using app.ActiveExplorer(); > However, this object gives me access violations on most of its' > properties. > > 2. exp.Selection causes a System.AccessViolationException > > 3. The ex.Message is "Forsøk på lesing fra eller skriving til beskyttet > minne. Dette er ofte en indikasjon på at annet minne er ødelagt." - this > is > the same message I get all the time, basically. It is a norwegian > translation > that roughly means "Attempt at reading from or writing to protected > memory. > This is often an indication that other memory is broken". > > 4. Inside the catch block, the if statement throws with the same exception > on the app.Explorers object. > > If I repeat the process with Outlook not running when I start the app in > debug mode (and usually having to kill the Outlook process as it refuses > to > die on its own), app.ActiveExplorer() returns null, so I get a null > reference > exception on exp.Selection. app.Explorers still returns the same > System.AccessViolationException. > > Please note that I have tried to set macro security to "No security > control > for macros" just to see if that would make a difference - and it didn't. > > Any other ideas? I can experiment wildly with this developer machine if > you > need me to. :) > > Thanks again, > > Rune
|
|
|