C# Microsoft.Office.Tools.Excel Некорректное подключение сборки

Рейтинг: 1Ответов: 1Опубликовано: 12.04.2023

Создаю пустой проект Console App, целевая платформа .NET 6. Добавляю ссылку на COM-сборку Microsoft Excel 16.0 Object Library, подключаю - using Excel = Microsoft.Office.Interop.Excel;. С какого то момента некоторые методы и свойства класса Excel._Workbook, которые я использовал ранее, перестали существовать. Например стал недоступен метод _Workbook.SaveAs, вместо свойств _Workbook.Worksheets и _Workbook.ActiveSheet появились методы get_Worksheets и get_ActiveSheet соответственно. Что могло привести к такому поведению и как это можно исправить, не переписывая код в старых проектах (замену SaveAs вообще даже найти не могу)?

  • Visual Studio 17.4.4
  • Microsoft Office 2303 16.0.16227.20202

Ответы

▲ 1

В с# есть возможность подключать COM-библиотеки напрямую. Долгий путь, не знаю поможет ли вам, но возможно поможет.

Как я это делал (на примере ScriptControl Как выполнить JavaScript на c#?).

  1. Открываете системный реестр. В ветке HKEY_CLASSES_ROOT Находите там ваш класс. Чаще всего работает application. Например "Excel.Application" или "Excel.Application.12" (версия офиса который у меня).

     Type TExcel=Type.GetTypeFromProgID("Excel.Application");
     object Excel = TExcel.InvokeMember(null, BindingFlags.CreateInstance, null, null, new object[0]);
    

Тут прокоментирую, COM библитотеки бывают двух видов, 32-битные, 64-битные, и двойные. Если выдаст 80040154 ошибку, и ProgID есть в реестре... то ему не нравится сборка.

  1. В либо гуглим в интернете библиотеку, или вариант 2, найтиде файл excel.exe и вытрусите с него с помощью программы Exescope, ResourceHacker раздел TypeLib, и попробуйте получить пару свойств с помощью COM методов. Они будут совпадать с теми, которые вы ранее использовали, но доступ к ним через своеобразную рефлексию будет. Ниже привожу нерабочий пример, что бы показать в какую сторону копать

    TScript.InvokeMember("Language", BindingFlags.SetProperty, null, sc, new object[]{"JavaScript"});
    TScript.InvokeMember("AddCode", BindingFlags.InvokeMethod, null, sc, new object[]{code});
    TScript.InvokeMember("SaveAs", BindingFlags.InvokeMethod, null, excelworkbook, new object[]{code});
    
  2. Если 1,2 получилось, остаётся написать обвертку которая подменит те методы которые вы используете прямым пробросом в COM-библиотеку.

Возможно кто-то уже для c# делал обвертку с# - COM Excel.Application, может погуглив удастся такое найти.

Возможно доступ к исщезнувшему методу удастся восстановить через рефлексию, как показано выше в п.2.

Вообще ситуация странная, может это какой-то баг который позже исправят... COM-библиотека это самый "нулевой" уровень доступа excel, если microsoft что-то испортили в промежуточной библиотеке, то COM - должно работать.