Что может заставить Outlook изменить LoadBehavior COM-плагина на 2 - кроме необработанных исключений? - PullRequest
18 голосов
/ 13 февраля 2009

Вот уже несколько недель мы боремся с проблемой, из-за которой у небольшого числа клиентов наш плагин Outlook выгружается и отключается по еще не определенным причинам. Под «отключенным» я подразумеваю, что Outlook изменяет следующее значение реестра с 3 на 2, что фактически означает, что надстройка не будет загружена при следующем запуске:

HKEY_LOCAL_MACHINE\Software\Microsoft\Office\Outlook\Addins\[OurAddin.sProgID]\LoadBehavior

Нет сообщения об ошибке, и никакие исключения не отображаются в файлах журнала, которые производит наш плагин.

Я уже нашел следующую страницу, которая конкретно касается проблемы изменения LoadBehavior: http://blogs.msdn.com/vsod/archive/2008/04/22/Troubleshooting-com-add-in-load-failures.aspx

Однако ни одна из возможных причин, предложенных там, не представляется применимой:

  • Надстройка не просто указана в списке отключенных элементов.
  • Не существует необработанных исключений ни в методах IDTExtensibility2, ни где-либо еще в коде. Весь код обернут в эквиваленты try / catch, и весь вывод исключений передается только через OutputDebugString или в файл журнала.
  • Ошибка, по-видимому, не зависит от антивирусного программного обеспечения, т. Е. Также возникает при ее отключении.
  • Отключение всех других надстроек также не влияет на ошибку.

Итак, что еще может заставить Outlook отключить надстройку?

Некоторые подробности / наблюдения:

  • До сих пор нам не удавалось воспроизвести проблему в наших тестовых средах, поэтому мы еще не смогли подключить отладчик во время возникновения проблемы.
  • Эта проблема никогда не возникает, пока мы пытаемся посмотреть, что происходит через удаленную поддержку (TeamViewer). Я подозреваю, что это потому, что TeamViewer использует подключаемую библиотеку DLL, которая внедряется во все запущенные процессы (включая Outlook) и, таким образом, влияет на структуру памяти, время, порядок потоков, что угодно.
  • Всякий раз, когда мы компилируем новую версию надстройки, чтобы опробовать что-то новое, надстройка будет нормально работать в течение пары часов или даже дней, чтобы в конечном итоге снова отключиться. Как только это произойдет, все последующие попытки загрузить надстройку для загрузки на эту машину (путем ручного изменения значения LoadBehavior) потерпят неудачу (т. Е. LoadBehaviour просто вернется к 2), пока мы не скомпилируем и не развернем другую сборку (или не попытаемся наблюдать с TeamViewer - см. Выше).
  • Обычно надстройка выгружается прямо при запуске Outlook, хотя иногда это также происходит после того, как Outlook уже работает в течение некоторого времени. Файл журнала в этих случаях выглядит совершенно незаметно - надстройка просто проходит обычные шаги завершения работы, как если бы Outlook был нормально закрыт.
  • Насколько я могу судить по нашим файлам журналов и наблюдая за проблемой через SysInternals ProcessMonitor, когда надстройка отключается при запуске Outlook (а не во время сеанса), DLL выгружается даже до COM-объекта (то есть надстройки). ) создается (сообщения журнала в конструкторе никогда не отображаются).
  • Мы поместили OutputDebugString сообщений в initialization разделы (это DLL-библиотека Delphi). Ни один из них не появляется, когда надстройка не загружается.
  • Эта проблема затрагивает только очень небольшую часть наших клиентов. У нас есть несколько десятков тысяч установок, от которых мы не получили никаких сообщений об этом.

  • ОБНОВЛЕНИЕ: Кажется, что часто (но не всегда) одна из последних вещей, которая регистрируется перед выгрузкой надстройки, является исключением с текстом «OLE error 800A01A8». Это исключение отлавливается глобальным обработчиком исключений, встроенным в используемый мной фреймворк ( Add-in-Express ), и, по-видимому, нигде не создается из моего собственного кода, каждый метод которого к настоящему времени полностью завернутый в try..catch. Обычно это происходит сразу после того, как я установил видимость моих CommandBarButtons из обработчика событий инспектора Activate.

Общие свойства всех затронутых машин:

  • Windows XP Professional, современный уровень исправлений
  • Outlook 2003 Professional, современный уровень исправлений
  • различные версии McAfee Virus Scan (хотя отключение не имеет никакого эффекта - см. Выше)
  • Пользователи являются членами локальной группы администраторов

Еще одна вещь, на которую стоит обратить внимание, что, вероятно, также очень важно (хотя, может быть, не так сильно, как я думал):
Мы используем модуль лицензирования / защиты от копирования от стороннего производителя, который упаковывает скомпилированную DLL в «оболочку» и распаковывает ее только на лету. С тех пор, как я узнал, что надстройка выгружается еще до того, как исполняется какой-либо наш собственный код, это стало моим главным подозрением. Тем не менее, хотя поставщик подтвердил, что в их коде могут быть необработанные исключения, файл журнала, созданный специальной отладочной версией оболочки защиты, показал, что процесс распаковки завершен успешно, и управление уже передано защищенной DLL до того, как Outlook выгрузил надстройку , Таким образом, кажется, что все, что заставляет Outlook выгружать наш плагин, происходит между завершением инициализации оболочки защиты и нашим собственным кодом.

Есть еще идеи?

Ответы [ 5 ]

5 голосов
/ 20 мая 2009

Моя компания мирилась с тем, что звучит как та же проблема, с которой вы сталкивались годами. У нас есть надстройка VB6 COM для Outlook 2003, которая развернута на нескольких сотнях машин, которые работают циклически сотни (если не тысячи) раз в день. Мы много проходим циклы загрузки и выгрузки.

Мы получаем довольно много общих ошибок, когда плагин загружается, но не подключается, и мы обрабатываем это в коде. (Очевидно не качество продукции)

Dim outlook As outlook.Application
Set outlook = CreateObject("Outlook.Application")
outlook.COMAddIns("MyFancyDancyPlugin").Connect = True

Редко, но не так редко, чтобы это не раздражало, мы видим, что плагин достигает состояния, в котором он загружен, и мы видим его в «Инструменты> Параметры> Другие> Дополнительные параметры> Надстройки Com ”, Но мы просто не можем подключиться к этой вещи. Если вы пытаетесь подключиться, вы не получаете сообщение об ошибке, оно просто переключается обратно на отключенное. [Эквивалент переключения обратно на 2 в разделе реестра] Насколько я могу судить, COM-объект никогда не создается. Предмет не указан в Отключенных предметах.

На самом деле нам не нужно повторно развертывать, чтобы исправить эту ошибку. Удаление объекта через диалог надстроек Com и последующее добавление его туда, похоже, решает проблему. Это по-прежнему неприемлемое решение, но оно позволяет восстановить работу без переустановки.

  • Windows XP Professional, последняя версия уровень патча
  • Outlook 2003 Профессиональный, современный уровень патчей
  • различные версии McAfee Virus Scan (хотя отключение не имеет никакого эффекта - см. выше)
  • Пользователи являются членами группа локальных администраторов

Кажется, это подходит, мы не используем McAfee, но антивирусный сканер также не взаимодействует с outlook или надстройками com. Мы также не используем приложение для защиты от копирования.

Извините, я не могу вам помочь, но я бы с радостью объяснил это.

2 голосов
/ 03 февраля 2012

Просто, чтобы закрыть это: проблема, в конце концов, была вызвана ошибкой в ​​сторонней оболочке лицензирования, которую мы использовали. Это было подтверждено поставщиком и исправлено в более поздних выпусках.

2 голосов
/ 16 августа 2011

Если у ваших пользователей есть возможность запустить программу отладки, чтобы получить больше информации о проблеме, когда она возникает, попробуйте использовать Add-in Spy от Microsoft.

http://msdn.microsoft.com/en-us/library/cc984533(v=office.12).aspx

Мне не удалось загрузить надстройку, и я обнаружил, что это происходит из-за того, что зависимость не загружается предварительно. Этот инструмент должен быть в состоянии сообщить вам, какая конкретная ошибка происходит, когда не удается загрузить надстройку Outlook.

2 голосов
/ 31 мая 2011

возможно, вы жертва политики блокировки. добавить обходной ключ в реестр, тогда он работает. современные офисные версии или vsto создает ключ при установке. эффект: установить современный офис тоже, и дополнение теперь загружается в старом офисе. пожалуйста, посмотрите

фрагмент кода взят из NetOffice http://netoffice.codeplex.com

public static void RegisterFunction(Type type)
{
            try
            {
                // add codebase value
                Assembly thisAssembly = Assembly.GetAssembly(typeof(ExampleClassicAddin));
                RegistryKey key = Registry.ClassesRoot.CreateSubKey("CLSID\\{" + type.GUID.ToString().ToUpper() + "}\\InprocServer32\\1.0.0.0");
                key.SetValue("CodeBase", thisAssembly.CodeBase);
                key.Close();

                key = Registry.ClassesRoot.CreateSubKey("CLSID\\{" + type.GUID.ToString().ToUpper() + "}\\InprocServer32");
                key.SetValue("CodeBase", thisAssembly.CodeBase);
                key.Close();

                // add bypass key
                // http://support.microsoft.com/kb/948461
                key = Registry.ClassesRoot.CreateSubKey("Interface\\{000C0601-0000-0000-C000-000000000046}");
                string defaultValue = key.GetValue("") as string;
                if (null == defaultValue)
                    key.SetValue("", "Office .NET Framework Lockback Bypass Key");
                key.Close();

                // add addin key
                Registry.ClassesRoot.CreateSubKey(@"CLSID\{" + type.GUID.ToString().ToUpper() + @"}\Programmable");
                Registry.CurrentUser.CreateSubKey(_addinRegistryKey + _prodId);
                RegistryKey rk = Registry.CurrentUser.OpenSubKey(_addinRegistryKey + _prodId, true);
                rk.SetValue("LoadBehavior", Convert.ToInt32(3));
                rk.SetValue("FriendlyName", _addinName);
                rk.SetValue("Description", "NetOffice COMAddinExample with classic UI");
                rk.Close();
            }
            catch (Exception ex)
            {
                string details = string.Format("{1}{1}Details:{1}{1}{0}", ex.Message, Environment.NewLine);
                MessageBox.Show("An error occured." + details, "Register " + _addinName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
}
2 голосов
/ 27 февраля 2009

Я также работаю над надстройкой Outlook и знаю одну причину, когда надстройка отключается. Иногда, когда Outlook резко закрывается или пользователь принудительно закрывает Outlook, надстройка отключается. Я не уверен, является ли это причиной в вашем случае, но это также может дать вам некоторое направление для размышлений. Некоторое время я использовал этот метод (закрытие внешнего вида с помощью диспетчера задач, когда он все еще загружается) для имитации этого поведения, и на самом деле я разработал инструмент, который сканирует все предоставленные ему машины и проверяет, отключена ли надстройка на машине и если да, он изменяет значение реестра, чтобы включить его.

...