Приведенный ниже код используется для получения настраиваемых свойств документа для книги Excel.

var xlApp = Globals.ThisAddIn.Application; // This works in VSTO Excel Add-in
var xlApp = new global::Microsoft.Office.Interop.Excel.Application(); // This doesn't work anywhere
xlApp.Visible = true;
global::Microsoft.Office.Interop.Excel.Workbook workbook = xlApp.Workbooks.Open(file, false, true, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, false, Type.Missing, Type.Missing);

global::Microsoft.Office.Core.DocumentProperties properties = workbook.CustomDocumentProperties; // Exception occurs here
global::Microsoft.Office.Core.DocumentProperty property = properties["propertyname"];

Первые две строки - это ссылки на Excel Application. Один получает ссылку из внутреннего устройства надстройки VSTO, другой - обычный new Application().

При использовании Application из внутренних компонентов VSTO код запускает штрафы без каких-либо проблем. Но при использовании new Application() строка workbook.CustomDocumentProperties выдает InvalidCastException:

Невозможно преобразовать COM-объект типа «System .__ ComObject» к типу интерфейса «Microsoft.Office.Core.DocumentProperties». Эта операция завершилась неудачно, поскольку вызов QueryInterface для COM-компонента для интерфейса с IID '{2DF8D04D-5BFA-101B-BDE5-00AA0044DE52}' завершился неудачно из-за следующей ошибки: такой интерфейс не поддерживается (исключение из HRESULT: 0x80004002 (E_NOINTERFACE)) .

Я пытаюсь заставить его работать над проектом winforms С # без VSTO. Во многих примерах и учебных пособиях new Application() используется для взаимодействия с Excel, но я заметил, что Microsoft.Office.Interop.Excel.Application - это интерфейс, поэтому использование new в интерфейсе для меня на самом деле странно. Как я могу создать подходящее приложение, которое может получить CustomDocumentProperties?

Эталонные сборки, которые я использую:

  • Microsoft.Office.Interop.Excel v2.0.50727 Версия 14.0.0.0
  • Microsoft.CSharp v4.0.30319 Версия 4.0.0.0
4
Jake 11 Мар 2015 в 11:29

3 ответа

Лучший ответ

Я заметил, что Microsoft.Office.Interop.Excel.Application - это интерфейс, поэтому использование нового интерфейса для меня на самом деле странно.

Это действительно странно, но по замыслу. Интерфейс Excel.Application украшен атрибутом CoClass, сообщающим фактическому классу о необходимости создания экземпляра при "создании экземпляра" интерфейса. Подробнее об этом здесь .

Но при использовании new Application() строка workbook.CustomDocumentProperties выдает InvalidCastException:

И снова действительно странно. Я сам столкнулся с некоторыми проблемами при использовании свойств документа. Кажется, что фактически возвращаемый класс отличается от спецификации, поэтому я перешел на использование dynamic, чтобы предотвратить проблемы с приведением типов.

Итак, вместо этого:

Microsoft.Office.Core.DocumentProperties properties = workbook.CustomDocumentProperties;

Использование:

dynamic properties = workbook.CustomDocumentProperties;
2
Community 23 Май 2017 в 12:17

У меня была такая же проблема. Сегодня это решено. Есть другой подход к получению результатов. Вопрос и ответ на него находятся на

Как я могу прочитать пользовательское свойство документа Excel с помощью взаимодействия C # Excel

Вот моя реализация.

public string CheckDocProp(string propName, object props)
        {
            Excel.Workbook workBk = Globals.ThisAddIn.Application.ActiveWorkbook;

            object customProperties = workBk.CustomDocumentProperties;
            Type docPropsType = customProperties.GetType();
            object nrProps;
            object itemProp = null;
            object oPropName;
            object oPropVal = null;

            nrProps = docPropsType.InvokeMember("Count",
                BindingFlags.GetProperty | BindingFlags.Default,
                null, props, new object[] { });
            int iProps = (int)nrProps;

            for (int counter = 1; counter <= ((int)nrProps); counter++)
            {
                itemProp = docPropsType.InvokeMember("Item",
                    BindingFlags.GetProperty | BindingFlags.Default,
                    null, props, new object[] { counter });

                oPropName = docPropsType.InvokeMember("Name",
                    BindingFlags.GetProperty | BindingFlags.Default,
                    null, itemProp, new object[] { });

                if (propName == oPropName.ToString())
                {
                    oPropVal = docPropsType.InvokeMember("Value",
                        BindingFlags.GetProperty | BindingFlags.Default,
                        null, itemProp, new object[] { });
                    return oPropVal.ToString();
                    break;
                }
                else
                {
                    return "Not Found.";
                }
            }
            return "Not Found.";
        }

Применение:

object docProps = wb.CustomDocumentProperties;
            string prop1 = ExistsDocProp("<CustomProperty>", docProps);
0
Hesoti 11 Янв 2020 в 14:53

Как я могу создать подходящее приложение, которое может получить CustomDocumentProperties?

Если вы разрабатываете надстройку, нет необходимости создавать новый экземпляр приложения Excel. Вы должны использовать свойство Application, предоставляемое средой выполнения VSTO:

var xlApp = Globals.ThisAddIn.Application; // This works in VSTO Excel Add-in

Но если вы разрабатываете автономное приложение, автоматизирующее Excel, в этом случае вам необходимо создать новый экземпляр приложения с помощью оператора new:

var xlApp = new global::Microsoft.Office.Interop.Excel.Application(); 

Используйте технологию позднего связывания (Type.InvokeMember) для получения или установки свойства документа в качестве Как использовать Предлагается в статье "Автоматизация получения и установки свойств документа Office с помощью Visual C # .NET".

0
Eugene Astafiev 11 Мар 2015 в 09:56