Как сделать Excel Interop на Windows 2008? - PullRequest
0 голосов
/ 02 сентября 2010

Недавно развернуло мое веб-приложение на Windows Server2008, IIS7 (с установленным Office).

После погони (и перехвата) различных других ошибок я столкнулся с одной, я не уверен даже, с чего начать.

На Cassini (Visual Studio Dev Server) все работало безупречно (чтение Excel через Excel Interop).

На w2008 IIS выдает неопределенную ошибку:

Значение не может быть нулевым. Имя параметра: o

[ArgumentNullException: значение не может быть нулевым. Имя параметра: o] System.Runtime.InteropServices.Marshal.FinalReleaseComObject (Object o) +9430474 longnamespace.ExcelReader.Dispose () в c: \ longpath \ ExcelReader.cs: 23 longnamespace.ApplicationFormReader.Read (String path) в каталоге c: \ longpath \ ApplicationFormReader.cs: 32

В настоящее время я собираюсь добавить нулевую проверку и посмотреть, все ли улучшится, но я подозреваю, что он просто взрывается и удаляет блок finally еще до того, как начинает что-либо читать.

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

Есть идеи?


Вот как выглядит метод dispose

    ///141932/kak-pravilno-ochistit-obekty-vzaimodeistviya-excel#141948
    public void Dispose(){
      GC.Collect();
      GC.WaitForPendingFinalizers();
      GC.Collect();
      GC.WaitForPendingFinalizers();
      Marshal.FinalReleaseComObject(_ws); //Worksheet, line 23
      _wb.Close();
      Marshal.FinalReleaseComObject(_wb); //Workbook
      _ap.Quit();
      Marshal.FinalReleaseComObject(_ap); //Application
    }

Я считаю, что это событие связано

Настройки разрешений по умолчанию для компьютера не предоставляют разрешения локальной активации для приложения COM-сервера с CLSID {00024500-0000-0000-C000-000000000046} пользователю NT AUTHORITY \ NETWORK SERVICE SID (S-1-5-20) с адреса LocalHost (с использованием LRPC). Это разрешение безопасности можно изменить с помощью инструмента администрирования служб компонентов.

Если так - кто-нибудь может перевести?

Добавление права на Microsoft Excel Application к Network service в службах компонентов как-то не сработало. вид.

Удаление уровня аутентификации тоже не помогло.


Изменено на

  if (_ws != null)
    Marshal.FinalReleaseComObject(_ws);
  if (_wb != null)
  {
    _wb.Close();
    Marshal.FinalReleaseComObject(_wb);
  }
  if (_ap != null)
  {
    _ap.Quit();
    Marshal.FinalReleaseComObject(_ap);
  }

посмотрим как пойдет ...

1 Ответ

2 голосов
/ 02 сентября 2010

Исключение выглядит довольно просто: в строке 23 вашего кода вы вызываете Marshal.FinalReleaseComObject, передавая нулевую ссылку.

Так что _ws, _wb или _ap - это нулевая ссылка. Вы сможете увидеть, что, если вы посмотрите на строку 23.

Для решения этой проблемы проверьте нулевое значение перед вызовом FinalReleaseComObject.

GUID {00024500-0000-0000-C000-000000000046}, на который ссылается ваше мероприятие, - это Excel - как вы сможете увидеть с помощью RegEdit.

Итак, я подозреваю, что код, который вы не опубликовали и пытается создать экземпляр объекта приложения Excel (_ap?), Выдает исключение из-за недостаточного разрешения. Тогда, поскольку ваш метод Dispose не проверяет, является ли _ap нулевым, он снова выбрасывает его туда.

Я подозреваю, что вы на правильном пути, когда хотите предоставить локальную активацию разрешению учетной записи сетевой службы. Не знаете, почему это не работает, может быть, вам нужно перезагрузить или перезапустить IIS?

ОБНОВЛЕНИЕ Также Excel Interop не рекомендуется в серверных приложениях. Лучше манипулировать документами Excel другим способом, например, используя сторонний компонент, такой как Aspose.

Одна вещь, которую я, похоже, помню, - это то, что Excel должен работать под учетной записью, имеющей локальный профиль, что может не подходить для учетной записи сетевой службы. Поэтому запуск его под другой учетной записью, как вы упомянули в комментарии, может быть лучшим решением, если вам нужно использовать Excel Interop.

...