Odd behavior with Ribbon in VSTO Outlook 2013 Addin - c#

I have a VSTO addin for Outlook 2013. The odd thing is sometimes when I do something seemingly unconnected. My button group disappears from the place it was in. Was there working perfectly for a long time. I added a ribbon group launcher, and it vanished. I then rolled back the pending changes and it still isn't there.
First, why does my ribbon group always disappear, it is set to Position: AfterOfficeId GroupMailDelete and the tab is set to TabReadMessage. This has always worked for me up until just now. I looked up the Office Id's for elements in office 2013 in the docs and they are correct (and as I said it's been fine for months).
Second, why does it not reappear when I rollback changes? I only changed that file and when I rolled back it looked like it did before I touched it.
Also it was working right until I made the change. Tested before, worked, tested again my ribbon group is gone.
I really can't stand this problem as it messes up my entire addin. Someone please offer assistance as none of the other SO answers or anything else I've found have helped.
Thanks a ton
EDIT:
Rewrote the program copying over the logic and redoing the ribbon and forms in designer. Register the event handlers was a pain as was constructing the two forms, one from EF and one using raw sql. But aside from that it works now. Why would it work when I rewrite it, but still not work when I rollback the breaking change? Not to mention that same change didn't break the copy I rewrote.

For anyone researching this in the future, try this link - which worked perfectly for me: https://msdn.microsoft.com/en-us/library/ms268871(v=vs.140).aspx

Did you check out the list of running COM add-ins right after the ribbon disappeared? Is your add-in listed in the list as an active one?
Microsoft Office applications can disable add-ins that behave unexpectedly. If an application does not load your add-in, the application might have hard disabled or soft disabled your add-in.
Hard disabling can occur when an add-in causes the application to close unexpectedly. It might also occur on your development computer if you stop the debugger while the Startup event handler in your add-in is executing.
Soft disabling can occur when an add-in produces an error that does not cause the application to unexpectedly close. For example, an application might soft disable an add-in if it throws an unhandled exception while the Startup event handler is executing.
When you re-enable a soft-disabled add-in, the application immediately attempts to load the add-in. If the problem that initially caused the application to soft disable the add-in has not been fixed, the application will soft disable the add-in again. Read more about that in the How to: Re-enable an Add-in That Has Been Disabled article.
Do you get any UI errors?
See How to: Show Add-in User Interface Errors for more information.
Finally, what ribbon XML do you use? Could you be more specific?

Related

Is there any way to prevent Outlook from disabling addins?

I developed an addin for Outlook 365 with C# .net4.5 VSTO. Users complain that Outlook disables the plugin because it slows down its launch. The plugin at Outlook startup does nothing, not even in the ribbon load. Reading the Microsoft documentation to avoid disabling the plugin you need to create two registry keys below
HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\Office\16.0\Outlook\Resiliency\AddinList --> key "<Prog-ID of Addin>" string value "1"
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Outlook\Resiliency\DoNotDisableAddinList --> key "<Prog-ID of Addin>" dword_32bit value 1
I tried to create them but Outlook keeps disabling addins. Is there any way to prevent Outlook from disabling addins?
Thanks
There are multiple reasons why your add-in could be disabled. One of them is exceptions at runtime. In that case (if it throws exceptions at runtime) your add-in will be disabled anyway. So, I'd suggest excluding most-spreaded factors first.
Typically you need to add a new key with a ProgID of the add-in set to 1 which stands to always enabled. For example, I've found this image while searching over the internet:
But anyway I'd recommend optimizing your add-in as the Preventing add-ins from being disabled section states.

C# VSTO - Slowly loading Outlook Add-in (caused by Ribbon.xml?)

I have developed a Microsoft Outlook Add-in for reporting suspicious emails to our IT Sec team. The Add-in basically consists of a button which is shown in the "Outlook Mail Explorer Ribbon", the "Outlook Mail Read Ribbon" and the context menu which opens up when right-clicking any email. The Add-in simply forwards any selected email to our IT Sec's mailbox for spam/phishing/...
The Add-in itself performs as expected, I only have trouble with the loading times (whenever I start Outlook, not only when first starting after installation).
I have taken a lot of information regarding Ribbon Designer VS XML from this SO answer (thanks bud!). I have decided to go for the Ribbon XML because of the ability to manipulate the context menu and the easy and clean way to design it. In addition, I created a Windows installer for installing the Add-in system-wide (see information below).
When developing this Add-in on my private PC, I had "normal" loading times and no problems with the Add-in. However, with the notebook of my company I am experiencing very high loading times. Outlook itself states that the average delay caused by the Add-in is around 2 seconds. The Add-in does not get disabled because of a GPO which places the Add-in on the "DoNotDisableAddinList" as described here.
Nevertheless, I do want to boost the performance. In the end, you can even see at the Outlook loading screen that Outlook "gets stuck" for those 2 seconds when loading the Add-in. This is not a solution for me.
What I have done so far
Basically, I tried a lot of stuff to boost the performance. First, I was having a look at this article of Microsoft which is about how to boost the performance of Office Add-ins. Unfortunately, I found none of these hints applicable for my case or I have already realized them (correct me if I am wrong):
Load VSTO Add-ins on demand: I want the buttons to be available as soon as Outlook starts, so that's not an option for me I guess
Publish Office solutions by using Windows Installer: Already done as described in this article of Microsoft
Bypass Ribbon reflection: Tried to do so but in my eyes not possible when using Ribbon XML
Perform expensive operations in a separate execution thread: Not applicable, there are no "expensive operations", simply the Add-in buttons should be loaded
What I could find out
I then tried to identify any "expensive" operation and therefore started my application in debug mode with a breakpoint at
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return new Ribbon();
}
After stepping over the first breakpoint (2 x F10), the Outlook loading screen shortly shows up and then Visual Studio shows up again with the next operation which is the GetCustomUI-method of my Ribbon.cs. This one loads the XML which contains the definition of my button (location, callback, image, label, ...). As you can see in the picture below, the execution time for this functions is very long (> 2000 ms). This screenshot is taken from my company notebook. On my private PC, the loading time is around 300 - 400 ms.
I then thought about slow IO for loading the XML file and hardcoded the XML content into the source code (I know, very dirty, but just for testing purposes), but no change. The function still executed for 2000 ms.
Right now, I don't know what to try next and I am a bit helpless. Maybe someone of you has any idea. When required, I can also post more parts of the source code. Any help is appreciated. Thank you in advance!
If your addin only acts in response to ribbon and context menu clicks, it needs to be on-demand - Outlook loads it the first time, then caches the Ribbon XML and the next time it is loaded only when the users clicks on your control.
Also keep in mind that you get punished for using .Net - Outlook has to load the specific version of .Net you are using before it executes anything in your addin.

VSTO Outlook Add-In published ClickOnce slow load time

I created VSTO Outlook add-in that has a button within the main ribbon of outlook and when clicked it lunches windows form. It works great to send the data from the form to the database and it composes email as well.
My problem is that users within a company that had it installed are getting slow load notification and the add-in is disabled. I tried to fix it and change all code for multi-threading but it seems not to improve the load time much. Is there any other way to make sure add-in on all user's machines is always enabled. Maybe some other way to publish other than ClickOnce.
Thanks in advance for any help.
Multithreading won't help you much - Outlook looks at your addin startup times, not the time it takes to respond to the button click.
If you are using .Net, you get punished for that - the .Net run-time has to be loaded before a single line of your addin code gets executed. Unless you switch to an unmanaged language (such as C++ or Delphi), there is nothing you can do about that.

Outlook 2007 process does not terminate after applying fix for addin menu item click issue

With an Outlook 2007 VSTO addin using WPF I have the issue described here. I applied the proposed solution and adapted it a little bit because I have multiple menus and context menus. This fixes the issue but it causes the Outlook.exe process to remain running when Outlook is closed. The Outlook window closes but the process stays around preventing Outlook from starting up again. Any ideas?
The Outlook window closes but the process stays around preventing Outlook from starting up again. Any ideas?
Make sure that all underlying COM objects are released in the code. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article in MSDN.
We solved the issue by executing
Dispatcher.ExitAllFrames();
in the Unloaded event handler of the UserControl because we had noticed that there always was a DispatcherFrame left running.
In addition, by registering the GotFocus and LostFocus event handlers for every single MenuItem instead of the whole Menu or ContextMenu we fixed the issue with the very first click on the first menu item not being handled.

Excel 2013 crashing

I'm trying to embed Excel 2013 in a WPF app. The problem is that when I call SetWindowLongPtr in the following code, Excel 2013 crashes immediately. I digged it and found that if I comment out WS.CHILD style, it works fine, but the Excel sheet becomes readonly, which is not what I want. The same code works fine with Excel 2010.
Excel.Application _excelApp;
IntPtr _wrappedApplicationHandle;
Int64 lngStyle;
Int64 lExStyle;
private void Button_Click_1(object sender, RoutedEventArgs e)
{
_excelApp = new Excel.Application()
{
Visible = true,
DisplayFormulaBar = true,
};
_wrappedApplicationHandle = new IntPtr( _excelApp.Hwnd);
lngStyle = GetWindowLongPtr(_wrappedApplicationHandle, (int)GWL.STYLE).ToInt64();
lngStyle &= ~(int)WS.CAPTION;
lngStyle &= ~(int)WS.SIZEBOX;
lngStyle |= (int)WS.MAXIMIZE;
lngStyle |= (int)WS.CHILD; //<< crashes with this line
lngStyle |= (int)WS.CLIPSIBLINGS;
lngStyle |= (int)WS.CLIPCHILDREN;
SetWindowLongPtr(new HandleRef(_excelApp, _wrappedApplicationHandle),
(int)GWL.STYLE,
new IntPtr(lngStyle));
...
}
EDIT
Some more information as I'm digging through. I tried wrapping the above code in a try/catch block to see what happens. It never reaches the catch block. Excel 2013 crashes with the infamous "Application has stopped working. Send report to MS" error. I have already turned on all Win32 / COM / C++ Exceptions in Visual Studio (through Debug menu > Exceptions dialog), but that doesn't help either. There is a Debug button in the error dialog. If I click that and open a debugger, the error msg I see is " 0xC0000005: Access violation reading location 0x0000000000000000."
I also found that commenting out the WS.CHILD line in the above code doesn't strictly make the worksheet readonly. It just blocks common keyboard/mouse input from reaching the worksheet. But some keys like the context-menu key of the keyboard still reaches there and the context menu is shown (right-clicking through the mouse doesn't work though). Similarly, I can interact with the Office Ribbon through the mouse. It appears as if only the worksheet area (the grid with the white background) is not receiving keyboard/mouse input.
EDIT 2
I just recalled that (apparently) in contrast to what Hans Passant has explained in his post below, VS2010 hosts an Excel instance in itself when you create a Excel VSTO Workbook project. Though I don't have VS2013 (Full) with me and can't confirm, I suspect VS2013 would do the same with Excel 2013 VSTO Workbook projects. Considering that VS2010 and above are all WPF applications themselves, how does that fit in the picture?
EDIT 3
That private interfaces theory suggested by #acelent (see comment below) appears to be correct. I spied into VS2010-hosted Excel instance and found that there was a new window with classname = EXCELI which is not there when we normally open Excel (normal hierarchy of windows is XLMAIN (application) > XLDESK (workspace area) > EXCEL7 (workbook)). Also that workbook is no longer available as an ActiveX object, which used to be the cases back when Office Web Components library was available (last shipped with Office 2003). So all in all, we seem to be on a dead end and I'm going to suggest #Hans's answer to my client unless someone comes up with an actual working method in the next few hours.
You'll need to give up on this, you cannot make it work reliably.
WS_CHILD cannot work by design, Windows has the rock-hard requirement that the parent window and its child belong to the same process. They pass messages between each other, the child will crash when it tries to dereference a pointer that belongs to the parent's process.
Windows does have some appcompat support for SetParent(), required because this was commonly done in Windows 3.x programs. The notion of processes with separate address spaces was entirely absent in that Windows version so it wasn't a problem back then. The odds that this still actually works properly after 20 years is proportional to how much the process behaves like a Windows 3.x app. It works okayish for a console window or a simple app like Notepad. Office 2013 apps are considerably beyond simple and 3.x. Having trouble with input is certainly a hallmark for this. You could tinker with AttachThreadInput() to try to solve it but you'll likely just run head-on into the next problem, including its nasty habit of causing deadlock when you debug.
Embedding Office apps used to be a strongly supported feature in Office, Microsoft intentionally designed them to be embeddable. The underlying technology was called OLE Linking and Embedding. This technology is however strongly deprecated. Support for it was intentionally left out of the .NET Framework. Office 2003 was the last version that still supported it well. Trouble started at 2007 and it was completely scrapped for 2010. It will not come back.
The way ahead here is the exact opposite one. Don't embed the Office app, let the Office app embed you. Writing add-ins for Office programs is strongly supported.

Categories

Resources