ActiveSync, addins and UI

  • Thread starter Thread starter Sunny
  • Start date Start date
S

Sunny

Hi,
I know about this issue:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=u29aJb%
24NCHA.2532%40tkmsftngp13&rnum=4&prev=/groups%3Fq%3Doutlook%2520addin%
2520activesync%2520load%26hl%3Den%26lr%3D%26ie%3DUTF-8%26sa%3DN%26tab%
3Dwg

I.e., ActiveSync will launch Outlook without GUI, but it will load the
addin. So, I decided to workaround this as follows:

In OnStartupComplete method, I do check Explorers.Count, and if it is >
0, I initialize my addin normally. But if it is 0 (i.e. no UI is
presented), I just hook to Explorers.NewExplorer event to wait until an
explorer is opened, so I can initialize my addin correctly and
create/hook my commandbars and buttons.

My problem is, that in the NewExplorer event handler, the CommandBars
collection is not yet initialized, so I can not see if my commandbar and
buttons are there and to hook their event handlers. Or to recreate them
if they are not present.

Does anyone have found some solution to this so far, as I can not find
anything published.

My addin is written in C# for Outlook 2000.

Thanks
Sunny
 
Hi,
as an addition to the prev. post I have tried to use AddInMon.exe from
Microeye (thanks guys).

But it seems I can not make it run as expected. When ActiveSync launches
Outlook, I can see in TaskManager that AddInMon is started shortly and
then it disappears from the running processes. It does not disconnect my
addin (I have MessageBox.Show in OnDisconnect method so I can see when
the addin is disconnected).

Does anyone has experience with AddInMon.exe and .Net addins? Any clues
what can be wrong?

This is what I have in Connect class (only relevant info about
AddInMon):

private bool IsAddInMonProcessStarted()
{
System.Diagnostics.Process[] processes =
System.Diagnostics.Process.GetProcessesByName("addinmon");

return (processes.Length > 0);
}

[DllImport("kernel32.dll")]
private static extern long GetCurrentThreadId();

public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode,
object addInInst, ref System.Array custom)
{
if (((Outlook.Application)application).Explorers.Count <= 0)
{
//No GUI. Start AddInMon.exe to listen.
System.Diagnostics.Process currProcess =
System.Diagnostics.Process.GetCurrentProcess();

//use kernel32.dll, see below
string threadId = GetCurrentThreadId().ToString();

string addInID = ((Office.COMAddIn)addInInst).ProgId;

if (!IsAddInMonProcessStarted())
System.Diagnostics.Process.Start
(Globals.FileNamesAndPaths.AppPath + @"\addinmon.exe",
addInID + " " + currProcess.Id.ToString() + " " +
threadId);

return;
}
....other init code goes here ...
}

Cheers
Sunny
 
Sunny,

Let's get AddInMon to report back on what it's doing. In your add-in key add
a DWORD value "WriteDiagnostics" set to 1. Then launch your add-in again and
look for AddInMon.log in Temp. That should give a clue as to what's happening.

Dave Kane [MVP - Outlook]
Micro Eye, Inc.
 
Hi Dave,
thanks for the replay.
I have done what you suggest, no file is created. I searched whole my C:
drive, no log file.

AddInMon just shows for less than a second in TaskManager and goes away.

I'm wondering if something I pass as parameter to AddInMon is not
correct, but I can not figure it out.

Sunny

Sunny,

Let's get AddInMon to report back on what it's doing. In your add-in key add
a DWORD value "WriteDiagnostics" set to 1. Then launch your add-in again and
look for AddInMon.log in Temp. That should give a clue as to what's happening.

Dave Kane [MVP - Outlook]
Micro Eye, Inc.

Sunny said:
Hi,
as an addition to the prev. post I have tried to use AddInMon.exe from
Microeye (thanks guys).

But it seems I can not make it run as expected. When ActiveSync launches
Outlook, I can see in TaskManager that AddInMon is started shortly and
then it disappears from the running processes. It does not disconnect my
addin (I have MessageBox.Show in OnDisconnect method so I can see when
the addin is disconnected).

Does anyone has experience with AddInMon.exe and .Net addins? Any clues
what can be wrong?

This is what I have in Connect class (only relevant info about
AddInMon):

private bool IsAddInMonProcessStarted()
{
System.Diagnostics.Process[] processes =
System.Diagnostics.Process.GetProcessesByName("addinmon");

return (processes.Length > 0);
}

[DllImport("kernel32.dll")]
private static extern long GetCurrentThreadId();

public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode,
object addInInst, ref System.Array custom)
{
if (((Outlook.Application)application).Explorers.Count <= 0)
{
//No GUI. Start AddInMon.exe to listen.
System.Diagnostics.Process currProcess =
System.Diagnostics.Process.GetCurrentProcess();

//use kernel32.dll, see below
string threadId = GetCurrentThreadId().ToString();

string addInID = ((Office.COMAddIn)addInInst).ProgId;

if (!IsAddInMonProcessStarted())
System.Diagnostics.Process.Start
(Globals.FileNamesAndPaths.AppPath + @"\addinmon.exe",
addInID + " " + currProcess.Id.ToString() + " " +
threadId);

return;
}
....other init code goes here ...
}

Cheers
Sunny
 
Are there any other add-ins in either HKCU or HKLM that include an AddInMon
value? If so, the first add-in to load will be the one that launches
AddInMon, and that's where AddInMon will look for the WriteDiagnostics value.
To simplify things first make sure that yours is the only enabled add-in.

Also, I took another look at your code and you left out the parameter flags
that AddInMon expects. The command line argument should be
"/n " + addInID + " /p " + currProcess.Id.ToString() + " /t " + threadId

Sunny said:
Hi Dave,
thanks for the replay.
I have done what you suggest, no file is created. I searched whole my C:
drive, no log file.

AddInMon just shows for less than a second in TaskManager and goes away.

I'm wondering if something I pass as parameter to AddInMon is not
correct, but I can not figure it out.

Sunny

Sunny,

Let's get AddInMon to report back on what it's doing. In your add-in key add
a DWORD value "WriteDiagnostics" set to 1. Then launch your add-in again and
look for AddInMon.log in Temp. That should give a clue as to what's happening.

Dave Kane [MVP - Outlook]
Micro Eye, Inc.

Sunny said:
Hi,
as an addition to the prev. post I have tried to use AddInMon.exe from
Microeye (thanks guys).

But it seems I can not make it run as expected. When ActiveSync launches
Outlook, I can see in TaskManager that AddInMon is started shortly and
then it disappears from the running processes. It does not disconnect my
addin (I have MessageBox.Show in OnDisconnect method so I can see when
the addin is disconnected).

Does anyone has experience with AddInMon.exe and .Net addins? Any clues
what can be wrong?

This is what I have in Connect class (only relevant info about
AddInMon):

private bool IsAddInMonProcessStarted()
{
System.Diagnostics.Process[] processes =
System.Diagnostics.Process.GetProcessesByName("addinmon");

return (processes.Length > 0);
}

[DllImport("kernel32.dll")]
private static extern long GetCurrentThreadId();

public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode,
object addInInst, ref System.Array custom)
{
if (((Outlook.Application)application).Explorers.Count <= 0)
{
//No GUI. Start AddInMon.exe to listen.
System.Diagnostics.Process currProcess =
System.Diagnostics.Process.GetCurrentProcess();

//use kernel32.dll, see below
string threadId = GetCurrentThreadId().ToString();

string addInID = ((Office.COMAddIn)addInInst).ProgId;

if (!IsAddInMonProcessStarted())
System.Diagnostics.Process.Start
(Globals.FileNamesAndPaths.AppPath + @"\addinmon.exe",
addInID + " " + currProcess.Id.ToString() + " " +
threadId);

return;
}
....other init code goes here ...
}

Cheers
Sunny
 
Hi Dave,
my addin is the only one :). But maybe the problem indeed in that
missing command line switches. I'll try with them later and keep you
informed. Thanks for the suggestion.

Meanwhile, I have created my own addin, which monitors the appearance of
the first explorer and then connects the main one.

The only problem is that NewExplorer event is fired before the explorer
is fully initialized, and if the other addin is connected immediately,
it fails as the explorer is still not valid, so I needed to add a small
delay.

As you have a more deep experience in that, can you tell if there is
another way (I have read somewhere how AddInMon works, I.e. monitoring
the Outlook thread and detecting the opening of specific window). I was
just hoping that it can be done inside Outlook.

Thanks
Sunny

Are there any other add-ins in either HKCU or HKLM that include an AddInMon
value? If so, the first add-in to load will be the one that launches
AddInMon, and that's where AddInMon will look for the WriteDiagnostics value.
To simplify things first make sure that yours is the only enabled add-in.

Also, I took another look at your code and you left out the parameter flags
that AddInMon expects. The command line argument should be
"/n " + addInID + " /p " + currProcess.Id.ToString() + " /t " + threadId

Sunny said:
Hi Dave,
thanks for the replay.
I have done what you suggest, no file is created. I searched whole my C:
drive, no log file.

AddInMon just shows for less than a second in TaskManager and goes away.

I'm wondering if something I pass as parameter to AddInMon is not
correct, but I can not figure it out.

Sunny

Sunny,

Let's get AddInMon to report back on what it's doing. In your add-in key add
a DWORD value "WriteDiagnostics" set to 1. Then launch your add-in again and
look for AddInMon.log in Temp. That should give a clue as to what's happening.

Dave Kane [MVP - Outlook]
Micro Eye, Inc.

:

Hi,
as an addition to the prev. post I have tried to use AddInMon.exe from
Microeye (thanks guys).

But it seems I can not make it run as expected. When ActiveSync launches
Outlook, I can see in TaskManager that AddInMon is started shortly and
then it disappears from the running processes. It does not disconnect my
addin (I have MessageBox.Show in OnDisconnect method so I can see when
the addin is disconnected).

Does anyone has experience with AddInMon.exe and .Net addins? Any clues
what can be wrong?

This is what I have in Connect class (only relevant info about
AddInMon):

private bool IsAddInMonProcessStarted()
{
System.Diagnostics.Process[] processes =
System.Diagnostics.Process.GetProcessesByName("addinmon");

return (processes.Length > 0);
}

[DllImport("kernel32.dll")]
private static extern long GetCurrentThreadId();

public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode,
object addInInst, ref System.Array custom)
{
if (((Outlook.Application)application).Explorers.Count <= 0)
{
//No GUI. Start AddInMon.exe to listen.
System.Diagnostics.Process currProcess =
System.Diagnostics.Process.GetCurrentProcess();

//use kernel32.dll, see below
string threadId = GetCurrentThreadId().ToString();

string addInID = ((Office.COMAddIn)addInInst).ProgId;

if (!IsAddInMonProcessStarted())
System.Diagnostics.Process.Start
(Globals.FileNamesAndPaths.AppPath + @"\addinmon.exe",
addInID + " " + currProcess.Id.ToString() + " " +
threadId);

return;
}
....other init code goes here ...
}

Cheers
Sunny
 
Sunny,

If we had been able to figure out a solution that worked from within Outlook
we wouldn't have had to create a hack like AddInMon! The problem with your
little "minder" add-in is that if Outlook never opens with UI and the program
that originally launched it closes, there won't be any Explorer.Close or
Inspector.Close event to let the helper add-in know Outlook is trying to shut
down. And since it will have an open reference to one or more Outlook objects
you won't get OnDisconnection or OnBeginShutdown events, so the helper won't
know to release its references and Outlook will remain in memory.

Sunny said:
Hi Dave,
my addin is the only one :). But maybe the problem indeed in that
missing command line switches. I'll try with them later and keep you
informed. Thanks for the suggestion.

Meanwhile, I have created my own addin, which monitors the appearance of
the first explorer and then connects the main one.

The only problem is that NewExplorer event is fired before the explorer
is fully initialized, and if the other addin is connected immediately,
it fails as the explorer is still not valid, so I needed to add a small
delay.

As you have a more deep experience in that, can you tell if there is
another way (I have read somewhere how AddInMon works, I.e. monitoring
the Outlook thread and detecting the opening of specific window). I was
just hoping that it can be done inside Outlook.

Thanks
Sunny

Are there any other add-ins in either HKCU or HKLM that include an AddInMon
value? If so, the first add-in to load will be the one that launches
AddInMon, and that's where AddInMon will look for the WriteDiagnostics value.
To simplify things first make sure that yours is the only enabled add-in.

Also, I took another look at your code and you left out the parameter flags
that AddInMon expects. The command line argument should be
"/n " + addInID + " /p " + currProcess.Id.ToString() + " /t " + threadId

Sunny said:
Hi Dave,
thanks for the replay.
I have done what you suggest, no file is created. I searched whole my C:
drive, no log file.

AddInMon just shows for less than a second in TaskManager and goes away.

I'm wondering if something I pass as parameter to AddInMon is not
correct, but I can not figure it out.

Sunny

Sunny,

Let's get AddInMon to report back on what it's doing. In your add-in key add
a DWORD value "WriteDiagnostics" set to 1. Then launch your add-in again and
look for AddInMon.log in Temp. That should give a clue as to what's happening.

Dave Kane [MVP - Outlook]
Micro Eye, Inc.

:

Hi,
as an addition to the prev. post I have tried to use AddInMon.exe from
Microeye (thanks guys).

But it seems I can not make it run as expected. When ActiveSync launches
Outlook, I can see in TaskManager that AddInMon is started shortly and
then it disappears from the running processes. It does not disconnect my
addin (I have MessageBox.Show in OnDisconnect method so I can see when
the addin is disconnected).

Does anyone has experience with AddInMon.exe and .Net addins? Any clues
what can be wrong?

This is what I have in Connect class (only relevant info about
AddInMon):

private bool IsAddInMonProcessStarted()
{
System.Diagnostics.Process[] processes =
System.Diagnostics.Process.GetProcessesByName("addinmon");

return (processes.Length > 0);
}

[DllImport("kernel32.dll")]
private static extern long GetCurrentThreadId();

public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode,
object addInInst, ref System.Array custom)
{
if (((Outlook.Application)application).Explorers.Count <= 0)
{
//No GUI. Start AddInMon.exe to listen.
System.Diagnostics.Process currProcess =
System.Diagnostics.Process.GetCurrentProcess();

//use kernel32.dll, see below
string threadId = GetCurrentThreadId().ToString();

string addInID = ((Office.COMAddIn)addInInst).ProgId;

if (!IsAddInMonProcessStarted())
System.Diagnostics.Process.Start
(Globals.FileNamesAndPaths.AppPath + @"\addinmon.exe",
addInID + " " + currProcess.Id.ToString() + " " +
threadId);

return;
}
....other init code goes here ...
}

Cheers
Sunny
 
Sunny,

If we had been able to figure out a solution that worked from within Outlook
we wouldn't have had to create a hack like AddInMon! The problem with your
little "minder" add-in is that if Outlook never opens with UI and the program
that originally launched it closes, there won't be any Explorer.Close or
Inspector.Close event to let the helper add-in know Outlook is trying to shut
down. And since it will have an open reference to one or more Outlook objects
you won't get OnDisconnection or OnBeginShutdown events, so the helper won't
know to release its references and Outlook will remain in memory.


Hmmm, the strange thing is that it does not hang. It works exactly as it
should. At least with Win2K pro and Outlook 2000 on my dev machine. I
haven't tested it yet with other vresions, but I'll keep you informed.

Cheers
Sunny
 
Back
Top