Доступ к свойству CommandBarButton.Picture поздним ограниченным способом - PullRequest
2 голосов
/ 28 января 2020

Я пытаюсь прочитать информацию Microsoft Access (Office) CommandBars, содержащуюся в * .mdb. Я мог бы использовать Microsoft.Office.Interop.Access для этого; однако эти сборки PIA привязаны к указанным c версиям Office. Поэтому, чтобы быть независимым от версии, я делаю это с поздним связыванием через тип C# dynamic. Т.е. у меня нет ссылок на Microsoft Office, специфицированные сборки c. Ценой этого является то, что доступ к панелям команд теперь слабо набран.

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

dynamic access =  Activator.CreateInstance(Type.GetTypeFromProgID("Access.Application", true));
// Starts an Access XP (2002) process in my case, but could be any version.

foreach (dynamic commandBar in access.CommandBars) {
    if (!commandBar.BuiltIn) { // Only my menus and toolbars.
        foreach (dynamic control in commandBar.Controls) {
            if (control.Type == (int)MsoControlType.msoControlButton && !control.BuiltInFace) {
                string caption = control.Caption; // Works.
                stdole.IPictureDisp picture = control.Picture; // <==== Throws exception! ====
                // ...
            }
        }
    }
}

При вызове метода получения свойства CommandBarButton.Picture выдается следующее исключение:

Catastrophi c ошибка (исключение из HRESULT: 0x8000FFFF (E_UNEXPECTED))

в System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal (Int32 errorCode, IntPtr errorInfo) в System.Dynami c .CrowExunHeck (Intres hresult, ExcepInfo & excepInfo, UInt32 argErr, String message)
в System.Dynami c .UpdateDelegates.UpdateAndExecute1 [T0, TRet] (сайт CallSite, T0 arg0)
в System.Dynami * 1067. UpdateDelegates.UpdateAndExecute1 [T0, TRet] (сайт CallSite, T0 arg0)
в MyApplication.MyMethod в MyApplication.cs: строка 64

Как получить изображение, избегая этого исключения?

Обратите внимание, что этот вопрос не о преобразовании объекта IPictureDisp в объект System.Drawing.Image. У меня уже есть решение для этого. Кроме того, не имеет значения, введен ли picture как object, dynamic или IPictureDisp. Это свойство существует, в противном случае я получу исключение 'System.__ComObject' does not contain a definition for 'Picture'.

. Это. NET Framework 4.0 Windows Проект Forms, скомпилированный для x86 (32-разрядный).


Редактировать : Переключение на основные сборки взаимодействия (PIA) позволяет осуществлять строгую типизацию, но не решает проблему. Исключение сохраняется .

Тем временем я читал больше о PIA. Начиная с. NET Framework 4.0, вы можете настроить свойства ссылки на сборку, чтобы сделать их независимыми от версии. Щелкните правой кнопкой мыши References / Microsoft.Office.Interop.Access и

  • Установите Embed Interop Types на True.
  • Установите Specific Version на False.

Сделайте это также для Рекомендации / офис . Поэтому я буду переключаться на PIA вместо использования dynamic.

...