View control & Add-In conflicts

S

seacuke

I am not even sure how to search for instances of this issue, so please
forgive me if this is a duplicate.

I have two seperate programs that are playing with Outlook. One is a
view control that's wrapped in a .net user control that is hit via a
web site. The other is an add-in that adds a button to Outlook and
does some processing with it.

Both seem to work fine... if Outlook is started before the view control
page is hit. However, if Outlook is not started, and the Add-in *is*
loaded into Outlook, and the user hits the view control, there are
exceptions thrown. No real indication of what kind of exception is
thrown, basically the user control doesn't load.

I am suspicious of my add-in's logic for attaching its button to the
command bar; but does anyone know a good, reliable way to determine if
a command bar is present, and if not, *unload* the add-in?

This is to support OLK2000 and later, and as I mentioned, everything
functions fine if Outlook is started before the view control is loaded;
but there is no guarantee that Outlook *will* be started before the
view control is loaded.


Here's part of my add-in code (maybe cut/paste to get the formatting
better?):


public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode, object addInInst, ref
System.Array custom)
{
try
{
if (application is Outlook.Application)
{
applicationObject = (Outlook.Application)application;
addInInstance = addInInst;

versionNumber =
int.Parse(applicationObject.Version.Substring(0,applicationObject.Version.IndexOf('.')));
if (versionNumber < 9)
{
MessageBox.Show("Only Outlook versions 2000 and later
are supported at this time.",
"Incompatible Outlook Version");
}
this.sessionId = "";
}
else
{
applicationObject = null;
addInInstance = null;
}
}
catch (System.Exception e)
{
MessageBox.Show(e.ToString(),"OnConnection");
}
}


public void OnStartupComplete(ref System.Array custom)
{
if (applicationObject == null)
{
return;
}
if (addInInstance == null)
{
return;
}
if (versionNumber < 9)
{
return;
}

Office.CommandBars commandBars;
try
{
activeMailItems = new Hashtable(25);
sentMailItems = new ArrayList(25);

// Need to add an event handler for when
//the 'sent items' folder gets a new
// email applied to it.
sentItems = applicationObject.GetNamespace
("MAPI").GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderSentMail).Items;
sentItems.ItemAdd +=new
Outlook.ItemsEvents_ItemAddEventHandler(sentItems_ItemAdd);

activeExplorer.SelectionChange += new
Outlook.ExplorerEvents_SelectionChangeEventHandler(activeExplorer_SelectionChange);
activeExplorer.FolderSwitch += new
Outlook.ExplorerEvents_FolderSwitchEventHandler(activeExplorer_FolderSwitch);


inspectorsClass =
(Outlook.InspectorsClass)applicationObject.Inspectors;
if (inspectorsClass != null)
{
inspectorsClass.NewInspector +=new
Outlook.InspectorsEvents_NewInspectorEventHandler(inspectorsClass_NewInspector);
}

activeExplorer =
(Outlook.Explorer)applicationObject.ActiveExplorer();

if (activeExplorer != null)
{
new
RNTOutlookSync.outlookExplorerCloseEvent(activeExplorer,new
RNTOutlookSync.outlookExplorerCloseEvent.Handler(this.explorerClose));


commandBars = activeExplorer.CommandBars;
if (commandBars != null)
{
syncButton =
(Office.CommandBarButton)commandBars["Standard"].FindControl(Office.MsoControlType.msoControlButton,
System.Reflection.Missing.Value,
"MainSync",
System.Reflection.Missing.Value,
false);

...

}
}
}
catch (System.Exception e)
{
MessageBox.Show(e.ToString(),"On Startup Complete");
}

}
 
K

Ken Slovak - [MVP - Outlook]

Why not use one addin, it would make things a lot easier to handle and
coordinate.

If you get ActiveExplorer.CommandBars you can iterate that collection and
see if your button is there on one of the CommandBar objects. You can also
use CommandBar.FindControl with the Recursive argument set to True to find
your button. It shouldn't be there anyway if you add it using the Temporary
argument and set that to True and Outlook is just starting up.

A COM addin will never be loaded with Outlook versions earlier than Outlook
2000, they aren't supported. Only Exchange extensions are supported prior to
Outlook 2000.




seacuke said:
I am not even sure how to search for instances of this issue, so please
forgive me if this is a duplicate.

I have two seperate programs that are playing with Outlook. One is a
view control that's wrapped in a .net user control that is hit via a
web site. The other is an add-in that adds a button to Outlook and
does some processing with it.

Both seem to work fine... if Outlook is started before the view control
page is hit. However, if Outlook is not started, and the Add-in *is*
loaded into Outlook, and the user hits the view control, there are
exceptions thrown. No real indication of what kind of exception is
thrown, basically the user control doesn't load.

I am suspicious of my add-in's logic for attaching its button to the
command bar; but does anyone know a good, reliable way to determine if
a command bar is present, and if not, *unload* the add-in?

This is to support OLK2000 and later, and as I mentioned, everything
functions fine if Outlook is started before the view control is loaded;
but there is no guarantee that Outlook *will* be started before the
view control is loaded.


Here's part of my add-in code (maybe cut/paste to get the formatting
better?):


public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode, object addInInst, ref
System.Array custom)
{
try
{
if (application is Outlook.Application)
{
applicationObject = (Outlook.Application)application;
addInInstance = addInInst;

versionNumber =
int.Parse(applicationObject.Version.Substring(0,applicationObject.Version.IndexOf('.')));
if (versionNumber < 9)
{
MessageBox.Show("Only Outlook versions 2000 and later
are supported at this time.",
"Incompatible Outlook Version");
}
this.sessionId = "";
}
else
{
applicationObject = null;
addInInstance = null;
}
}
catch (System.Exception e)
{
MessageBox.Show(e.ToString(),"OnConnection");
}
}


public void OnStartupComplete(ref System.Array custom)
{
if (applicationObject == null)
{
return;
}
if (addInInstance == null)
{
return;
}
if (versionNumber < 9)
{
return;
}

Office.CommandBars commandBars;
try
{
activeMailItems = new Hashtable(25);
sentMailItems = new ArrayList(25);

// Need to add an event handler for when
//the 'sent items' folder gets a new
// email applied to it.
sentItems = applicationObject.GetNamespace
("MAPI").GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderSentMail).Items;
sentItems.ItemAdd +=new
Outlook.ItemsEvents_ItemAddEventHandler(sentItems_ItemAdd);

activeExplorer.SelectionChange += new
Outlook.ExplorerEvents_SelectionChangeEventHandler(activeExplorer_SelectionChange);
activeExplorer.FolderSwitch += new
Outlook.ExplorerEvents_FolderSwitchEventHandler(activeExplorer_FolderSwitch);


inspectorsClass =
(Outlook.InspectorsClass)applicationObject.Inspectors;
if (inspectorsClass != null)
{
inspectorsClass.NewInspector +=new
Outlook.InspectorsEvents_NewInspectorEventHandler(inspectorsClass_NewInspector);
}

activeExplorer =
(Outlook.Explorer)applicationObject.ActiveExplorer();

if (activeExplorer != null)
{
new
RNTOutlookSync.outlookExplorerCloseEvent(activeExplorer,new
RNTOutlookSync.outlookExplorerCloseEvent.Handler(this.explorerClose));


commandBars = activeExplorer.CommandBars;
if (commandBars != null)
{
syncButton =
(Office.CommandBarButton)commandBars["Standard"].FindControl(Office.MsoControlType.msoControlButton,
System.Reflection.Missing.Value,
"MainSync",
System.Reflection.Missing.Value,
false);

...

}
}
}
catch (System.Exception e)
{
MessageBox.Show(e.ToString(),"On Startup Complete");
}

}
 
S

seacuke

Hi Ken,

I think there's somewhat of a misunderstanding. There are two
seperate products hitting Outlook here; one is a web page with a built
in .net user control that uses an AxInterop.OLXLib.OutlookViewControl
(or some such thing) to view an Outlook calendar in a web page.

The second is an add-in that does manipulation of the user's email.
(the code above)

So the first item isn't an add-in at all, rather it's something that
hits Outlook 'from the outside' and just presents a view of the
end-user's calendar folder. This viewer is what is affected by the
behavior of the add-in. When Outlook isn't running on the end-user's
machine, the AxInterop.OLXLib.OutlookViewControl will launch Outlook,
but since it's only a view of a folder, the add-in has issues with
attaching itself to a toolbar (since there isn't one present), and
Outlook crashes in a pretty obscene way. Interestingly enough, the
view control continues to work.

Anyways, what I'm looking to do is to put a check in place (I thought
I had sufficient checks in my OnStartupComplete code above) to NOT LOAD
the add-in if the end-user has started the View Control web page
without having Outlook loaded, or at least to stop the loading process,
and unload itself. Is there any attribute of the application object or
explorer that tells whether Outlook is being used as the full blow
Outlook ap, or whether just a view control is being used?
 
K

Ken Slovak - [MVP - Outlook]

Checking for Application.ActiveExplorer or more generally for
Explorers.Count > 0 is what most of us do to see if Outlook was opened with
a UI. I don't know if that would work with the application that's causing
the problem however.

You can also iterate through the Application.COMAddins collection and check
the connect status of any addin to see if it's running and connected. You
can also toggle that Boolean to disconnect an addin.

You cannot however control the order in which any addin is loaded and
initialized.

My initial thought here is if this application is causing such problems
would be to not use it :)
 
S

seacuke

Hey Ken,

I think there is still a misunderstanding (do I sound like a broken
record?) There really is only 1 add-in. I promise. The second
application is embedded in a web page, and is an Outlook view control.
And believe me, if there was a way I could be not using either of these
applications I would be in a much, much happier place. However, I am
only the trained monkey, I do not make the decisions.

Anyways, I think your suggestion of checking the explorerCount is
probably exactly what I need to be doing. So let's say an add-in sees
an explorerCount of 0, and decides it's best not to continue. What
does the add-in do? Exit()? Call its "onDisconnect?"

Thanks again,
brian
 
K

Ken Slovak - [MVP - Outlook]

In On_Connection if Application.Explorers.Count = 0 then just don't
instantiate the addin. Meaning don't instantiate any Outlook objects unless
you're going to be monitoring for a later addition of an Explorer (if
Outlook is running with no UI and then the user starts Outlook with a UI).

If you monitor like that then you'd instantiate a module level Explorers
collection declared WithEvents in the designer module or whatever is
handling the On_Connection event and set up a NewExplorer event handler.
Then when that event fires you can instantiate your addin.
 
S

seacuke

Hi Ken,

So in the OnConnection method, I added the following:

applicationObject.Explorers.NewExplorer +=new
Outlook.ExplorersEvents_NewExplorerEventHandler(Explorers_NewExplorer);

And am getting the event as I would expect any time someone launches
a new Outlook UI. The problem is that the commandBars member of the
new Explorer is undefined, if I try and get reference to it I get a
null exception. When I look at the Explorer in question using the
debugger, there are several fields that are seemingly empty.
 
K

Ken Slovak - [MVP - Outlook]

You would have to wait until ActiveExplorer is a valid Explorer object. At
that point you can get all the Explorer's properties.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top