Excel Error 406 when using both VBA and ActiveX addins. - c#

My Excel addin (XLL AddIn, call it MyAddIn) is built with C#, ExcelDNA, NetOffice, VS2010. Client has another addin (let's call it B), I guess it is written in VBA.
Client says B works fine without MyAddIn. Once MyAddIn is installed, B fails with error:
Error code: 406
Error message: Non-modal forms cannot be displayed in this host application from an ActiveX DLL, ActiveX Control, or Property Page.
I did see this Microsoft resource, but I do not want to just tell the client that B addin needs changing. I want to do something to avoid this from my side.
Here is the steps reported to see the issue:
When B addin is installed, it does not make any registry entry for the Microsoft Excel.
When MyAddin is installed, it makes a registry entry for Microsoft Excel.
Registry entries here basically tells that the addin should be opened when Excel is launched, so B addin is not launched, Excel works fine, MyAddIn works fine.
Now when B addin is launched, it gives the 406 error shown above.
We can ignore the error and keep working with the B addin; disabling MyAddIn is the workaround.
When the B addin is launched, we see that MyAddIn is loaded first before the B addin and then get the 406 error.
When we uninstall MyAddIn, this error is no longer encountered and everything works fine.
To remove this error, we tried changing the registry order to make the B addin always open before MyAddin.
This works, but then this a global change for Microsoft Excel, which means B addin will always open, even when we launch only Excel. This is not desired, as B addin then can't let users work with the static data as the B addin keeps on refreshing real-time. That is the reason the B addin doesn't make an entry in the registry settings. So registry changes are not an option. We can’t always open B addin whenever Excel is open.

I don't have an answer, but here are a couple of things you can try.
You can tell what type of Addin you are dealing with by executing File | Options and selecting the Addins Tab.
If the event happens as soon as you load Addin B, it probably means you are calling a non-modal dialog box as it states, but there are a few other things that could give you similar errors.
Based on your description, it sounds like the error could either be a dialog box in your Addin, or it could be in the other addin, and it gets called as a side effect of some state change your addin made.
To get to the bottom of it, you need to attach a debugger. You can do that by making Excel your Startup Project, or by attaching later. The former is probably easier in this case.
In Visual Studio, Use Project | Properties | Debug, select Start external program and put in the fully qualified pathname to Excel.
Load Addin B manually to give yourself the error
Break into the debugger and examine the call stack.
That will frequently but not always give you good clue as to where the problem is, but it's always the first step. If it doesn't give you useful information (stack info is frequently completely lost in transitions between addins), you may want to put some breakpoints in your projects in any events you handle. Even this doesn't reliably work all the time, but it's worth a shot.
If I had to guess, I would say probably have some event handlers in your add-in that are causing the problem, And you might have to do something like change a .Show to a `.ShowDialog', or defer the processing of the form until outside the event handler but that's just a guess.

Related

Outlook 2007 Addin Startup Crash due when Outlook startup trigger via Send Mail option on Word or Excel

Having started development on a Outlook 2007 Addin at my new job, a user encountered the following error:
Object reference not set to an instance of an object during Outlook startup. After trying to track the issue via additional try catches as the initial VSTO exception message from the unsuppressed alerting was not particularly useful. I tracked the issue to the method that starts with this code:
if (newToolBar == null)
{
Office.CommandBars cmdBars = this.Application.ActiveExplorer().CommandBars;
newToolBar = cmdBars.Add("Data Team Toolbar", Office.MsoBarPosition.msoBarTop, false, true);
}
Being relatively new to VSTO, my first assumption was that ActiveExplorer().CommandBars was returning null.
After further correspondence, with my end user I was able to confirm that they had started Outlook using Excel's Send mail option from the mail menu. (not a scenario I had foreseen at all.) This seemed to collaborate my theory of the main Outlook window not being open at time, and I was able to successfully reproduce the crash consistently.
As such I added the following code
if (this.Application.ActiveExplorer() == null )
{
// If Outlook is opened via some other method ie. send on Excel or Word
// Kill Addin nicely.
this.OnShutdown();
}
However, I soon realized when I published this version under UAT (as I cannot seem to find a way to reproduce the issue within Visual Studio (Command Switches (https://support.office.com/en-sg/article/Command-line-switches-for-Microsoft-Office-Outlook-2007-92de9e0b-4f97-42a2-8e02-89c4a8294916)
Specifically "/c ipm.note" set as a debug argument seems to have no impact on debug startup process.
That this appears to close Outlook as per this link (VSTO Outlook integration - Outlook shutdown event for synchronization) and not just the Addin as I had thought.
The only solution I have thought of from a design prospective (whilst not ideal) would be a way of disabling the Addin from taking further action under this scenario but allow it to run again under normal startup conditions without user intervention. I'm thinking the logic could be included in a guard clause like so,
if (this.Application.ActiveExplorer().Caption != "Microsoft Outlook")
{
//Disabling code//
}
But I'm not sure how or if I want to implement this,
As my Addin has a lot of dependencies on the toolbar (This solution would mean a lot of very specific guard clauses to check the toolbar existed would need to be added, something I rather avoid if at all possible. Ideally I would like the Addin to be able to detect if it's run under a different approach if opened this way, and only load the Toolbar if and when the main window for Outlook is visible, I already have a background main loop as part of other requirements. So possibly something along the lines of?
if(DataTeamAddin.LoadStyle != "Normal")
{
if(OutlookMainWindowVisible == true && ToolbarIsNotLoaded == true)
{
BeginToolbarSetup();
}
else
{
//Resume Main Loop
}
}
However I'm unsure how to go about it? let alone how to test this using automated testing in MSTest, as I cannot even reproduce the issue within my VS2013 IDE?
First, Command bars were deprecated. Consider using the Fluent UI instead. You can read more about the new UI in the following series of articles in MSDN:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)
Second, it is a known case when Outlook is run from other Office applications. Only the inspector window is available. You can subscribe to the NewInspector or InspectorActivate events to be aware that the add-in is run when the Send To command is used.
Can you run your code when everything is ready?
https://msdn.microsoft.com/en-us/library/bb147656(v=office.12).aspx

Outlook just hangs while debugging VSTO Addin

I am using Visual Studio 2013 and trying to develop a C# Outlook Add-In project for Outlook 2013 client installations at my enterprise employer.
What could cause Outlook to not load completely, i.e. upon pressing F5 to Start Debugging my application via the VS IDE, the Outlook Splash Screen loads for a second, but Outlook never actually loads. Via the Task Manager, I am able to see a process for Outlook running in the background, but it never materializes into an App process.
I have done the following: in the project's Properties page, I have set Outlook.EXE local path as the Start an external program and also set the working directory.
When I run my code "Start Without Debugging", Outlook indeed does load and I can run my Outlook Add-In, but I am not able to step through my code which, of course, is invaluable.
Any ideas on what I should maybe look for?
UPDATE:
As per #Sarvesh's answer, I created a new Outlook Add-In project without setting any Properties and just one line of code as shown and still the same behavior:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Console.Writeline("ThisAddIn_Startup was called...");
}
In the project's Properties page, I have set Outlook's local path as
the Start an external program and also set the working directory.
Why you have set these?
If you are developing VSTO addin using templates provided by VS, you don't need to set these properties manually.
Set it back to default and then Debug.
Be aware, only one instance of Outlook can be run at the same time. So, first of all check out the list of running processes for Outlook.exe before starting your project. Only then you can start your add-in under the debugger.
Also I'd suggest disabling all other add-ins in Outlook. Outlook may disable add-ins that take a lot of time for loading. Try to reproduce the issue with a newly created empty add-in project. Set a breakppoint to the Startup event handler and run it under the debugger. Does it work?
Outlook 2013 monitors add-in performance metrics such as add-in startup, shutdown, folder switch, item open, and invoke frequency. Outlook records the elapsed time in milliseconds for each performance monitoring metric.
For example, the startup metric measures the time required by each connected add-in during Outlook startup. Outlook then computes the median startup time over 5 successive iterations. If the median startup time exceeds 1000 milliseconds (1 second), then Outlook disables the add-in and displays a notification to the user that an add-in has been disabled. The user has the option of always enabling the add-in, in which case Outlook will not disable the add-in even if the add-in exceeds the 1000 millisecond performance threshold.
Make sure that the add-in is always enabled.
See Performance criteria for keeping add-ins enabled for more information.
I had this same issue just recently - I resolved it by building and installing the addin in Outlook, which when launched threw an error and popped up with the exception.
In the end, the solution to my issue was to create a registry key in the 64-bit hive named EnableVSTOLocalUNC set to value 00000001 (as a dword) in the key [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Vsto
Runtime Setup\v4].
Here are some other potential issues you may come across once you've installed the addin.

Shared addin (Outlook currently) - toolbar button works a bit, then stops, no errors given

Bit of a weird one this: I've got a shared Office addin that currently targets Outlook 2007 on XP and Win7 (Excel/Word and other versions later). It adds a toolbar button, and this fires off my code. My code just reads data from Outlook. First time round, it works a treat. Second time, the button click does nothing. No errors, nothing. The rest of Outlook responds as normal.
The entire event code is in a try/catch that writes any exceptions out to a temporary file (this mechanism works if a throw an exception in code), but nothing is picked up.
According to the "Trust Center", my addin is active (not inactive or disabled). If I restart Outlook, or stop and start the addin via the Trust Center, it again works once and then stops.
If I reduce the amount of work my code does, the button will sometimes respond for about ten clicks or so, then gives up. Whichever version of my code I try, resources don't seem to change much (memory moves up a mite, the thread count stays the same).
I've read of a similar thing with Word, but this was explained by Word recreating the toolbars or menus every time it loads a document (not sure how correct this is). For me, I select an email, click once, it works, click again (no changing views in Outlook, selecting different emails, etc), and it doesn't.
Has anybody got any clues here?
You should place the variable that contains your toolbar buttons to a global scope (You can keep then as fields of the addin object). If you don't keep a valid path to them at all times, .NET garbage collector will eventually clean up these objects and the event handlers with it. This will however not remove the visible button so it will still be visible.

Add-in makes Excel crash when starting minimized

I start Excel from within my C# WinForms application using Process.Start(...) (this has a reason). I want to start it in background, without distracting the user, so I try to start it minimized or hidden. In both cases, I experience a very weird behavior:
After some seconds, Excel restores the window (even makes it visible if it's hidden) and then crashes saying: "Microsoft Office Excel has encountered a problem and needs to close. (Win XP crash message.)"
The same thing happens if I start Excel manually by double-clicking its Shortcut Icon on the Desktop and then just switch to another application window immediately, such that the Excel window loses focus during startup.
The problem appears only if any of the XLA add-in contains a UserForm. If I remove the UserForm, the problem disappears. If I remove the add-in, the problem disappears.
Any help is appreciated, as long as it is
An explanation of why this happens
Something I can change in the add-in
A way how to work around this bug (without using COM)
Not a suggestion to use COM. (See here to understand why I don't.)
Not an advice to update Excel (I can't)
Steps to reproduce:
Start Excel 2007 with an empty workbook.
Save As...
File Type: Excel 2003 Add-in (*.xla)
Location: %APPDATA%\Microsoft\Excel\XLSTART\foobar.xla
Alt + F11 (open VBA editor)
Add a UserForm to the project.
Save and Quit Excel
Start Excel and then immediately click on the Firefox or whatever tab in the taskbar to activate any window other than Excel.
Wait and watch Excel start, until it crashes.
After restarting Excel it says:
Excel experienced a serious problem with the 'foobar' add-in. If you have seen this message multiple times, you should disable this add-in and check to see if an update is available. Do you want to disable this add-in?
Details/Findings:
Excel version: 12.0.6535.5002, SP2 MSO 12.0.6425.1000
0xA3 reported in his comment he could reproduce it on 32 bit machine with Excel 12.0.6535.5002, SP2 MSO 12.0.6535.5002
I've tried with a 2007 add-in (XLAM). The same problem, except that it even crashes if it doesn't contain any UserForms.
0xA3 reported that on his 64 bit machine it worked, however Excel still pops up unexpectedly (but doesn't crash). The same holds for 2 machines of my testers so far.
This is the code I wanted to use in C# (note that the problem can be reproduced completely independent of any C# app, see above).
Process.Start(new ProcessStartInfo("excel.exe")
{ WindowStyle = ProcessWindowStyle.Minimized });

C# WebBrowser control not firing the DocumentCompleted event

I have a program that is using the C# WebBrowser control and it needs to detect which page is loaded to determine what to do next. The program works fine on most of the employee's computers at the office, but it does not work on some.
I have determined the problem is that the documentCompleted event is not firing on those computers it does not work on.
This program does use threads to process data, and the webbrowser.navigate call is made through a delegate. But I have also changed the code to not use delegates for the navigate action with no change in the result.
I also made a separate program that has just a basic WebBrowser and debug textfield, and the DocumentCompleted event does fire when using that program.
NOTE: The computers that it is not firing on are older PCs with single core/thread processors.
I am out of ideas on this one, any help would be appreciated.
As explained by CodeBlock, this seems to be related by the installation state of Microsoft.mshtml.dll
We've got customers where the Microsoft.mshtml.dll is not present in GAC (nor in computer), and then the WebBrowser component never fires any event.
By using Reflector in the WebBrowser class, the DocumentComplete event is raised by a subclass named WebBrowserEvent, which implement a private interface DWebBrowserEvents2.
This interface is a ComImport of {34A715A0-6587-11D0-924A-0020AFC7AC4D}, which, I suppose, is related to Microsoft.mshtml.dll.
So our solution was to install the Office 2003 Redistributable Primary Interop Assemblies, which install the DLL on Program Files then register it on the GAC.
Note : Don't pay attention to the .NET Framework 1.1 required or office required, it just copies some dlls.
Note 2 : The 2007 package seems to include the same dll.
#Pavel L:
The problem here is you used a web browser control from mshtml.dll but .NET framework does not include this file. The solution for this is simply copy mshtml.dll to your app dir or set 'Copy local' property of Microsoft.mshtml to True.
Sorry for my bad english :D
If it is a threading issue, make sure you are calling Application.DoEvents(). I've had problems with WebBrowser not working right when I failed to do that.
Well I'd like to share even more simple solution rather than installing a package.
As it was stated before the DocumentComplete event somehow depends on Microsoft.mshtml.dll file. You can find it on a machine with Visual Studio installed. So it needs to be copied and installed to the target machine. Here's the description of the process:
Place the Microsoft.mshtml.dll file into the "%ProgramFiles%\Microsoft.NET\Primary Interop Assemblies" folder.
Then drag and drop it into the "%SystemRoot%\Assembly" folder.
Register the library with RegAsm.exe utility (which is located in the appropriate subfolder of "%windir%\Microsoft.NET\Framework").
P.S. May be it may be done in a better way but this solution works and I hope it'll be useful for you.
In order for the documentCompleted-Event to fire,
the visible property of the web browser needs to be set to true.
It can also be on visible, if you have multiple screens.
If you have > 1 screen, switch off all but the main screen, this should resolve the problem.
Alternatively, move the window to the 2nd screen.
Make sure webbrowser.Visible=true; this works for me, I had similar problems previously.

Categories