ASP.net C # - WINWORD.exe - PullRequest
       20

ASP.net C # - WINWORD.exe

3 голосов
/ 01 декабря 2009

Я играю с документом Microsoft Word из программы ASP.NET/C#.

Мои программы открывают документы документов внутри. используя

app = new Word.Application();
app.Documents.Open

создает экземпляр процесса winword.exe, я вижу его в диспетчере задач.

, даже если я закрою Док, используя close() и app.quit(). это должно убить процесс. но этот процесс не погибает.

любая идея, как программно завершить этот процесс.

Ответы [ 7 ]

5 голосов
/ 02 декабря 2009

Для начала, я согласен с Артуром и Иво: не используйте автоматизацию Word на сервере ... это не поддерживается и это болезненно.

  1. Если вы можете, попробуйте поддержать ввод / вывод Word в формате DOCX ( полностью документирован формат XML упакован с использованием сжатия, поддерживаемого .NET Framework и поддерживаемого pre-Office 2007 с плагином)
  2. Если не создать службу, которая обрабатывает запросы в очереди, чтобы предотвратить одновременное использование нескольких потоков (ala Ivo's answer )

Если вы должны использовать автоматизацию Word:

  1. Убедитесь, что вы устанавливаете как можно больше параметров приложения, чтобы предотвратить появление диалогов.
  2. Убедитесь, что вы передаете WdSaveOptions.wdDoNotSaveChanges в Document.Close
  3. Просмотрите этот документ: Как: закрыть диалоговое окно, отображаемое приложением Office с Visual Basic .NET (очевидно, также относится к C #)
  4. Убедитесь, что вы вызываете Marshal.ReleaseComObject для обоих объектов Document и Application, и убедитесь, что он находится в блоке finally.

winword.exe должен исчезнуть, если вы будете следовать вышеизложенному, вам не нужно будет убивать процесс.

Редактировать: Не совсем ответ на ваш вопрос, но тем не менее по теме. Имейте в виду, что у вас также будут проблемы на сервере с разрешениями. Убедитесь, что вы создали для него определенного пользователя и используете его в качестве идентификатора AppPool (или идентификатора службы). Затем вам нужно будет сделать следующее:

  1. Убедитесь, что вы установили компоненты автоматизации, очевидно,
  2. Запуск "dcomcnfg"
  3. Службы компонентов -> Компьютеры -> Мои компьютеры -> Приложения COM +
  4. «Документ Microsoft Word» (или «{000209FF-0000-0000-C000-000000000046}») -> Свойства
  5. Вкладка "Безопасность" -> Разрешения на запуск и активацию -> Настройка
  6. Нажмите «Изменить» и добавьте своего пользователя AppPool сверху
  7. Повторите шаги 5-6, но выберите «Права доступа»

Кроме того, вам все равно может понадобиться запустить winword.exe один раз, как пользователь AppPool, прямо с сервера, несмотря на параметры диалога, описанные выше, для первоначальной настройки профиля.

2 голосов
/ 01 декабря 2009

Просмотр System.Diagnostics.Process.GetProcessesByName и System.Diagnostics.Process.Kill

Попробуйте что-то вроде

string processName = "ProcessName";
Process[] processes = Process.GetProcessesByName(processName);

foreach(Process process in processes)
{
    process.Kill();
}
2 голосов
/ 01 декабря 2009

Офисные приложения не «уничтожают» первый созданный экземпляр. Вы найдете ту же проблему при использовании Excel.

Смотрите это и другие

50 способов убить Excel

Как убить процесс с именем

1 голос
/ 01 декабря 2009

Наиболее безопасный подход к использованию (Microsoft) Office на сервере - это создать службу, которая может принимать потоки и создавать экземпляр Word (или любого другого приложения Office), который выполняет свою задачу, а затем убивает приложение. Если вы этого не сделаете, ссылка на работающее офисное приложение останется в вашем рабочем процессе asp. Это означает, что многие процессы будут работать до тех пор, пока ваш рабочий процесс asp не будет переработан. Это большая потенциальная утечка памяти.

Вот как мы это сделали. Чтобы построить это правильно, нужно много времени, но это самый безопасный способ.

1 голос
/ 01 декабря 2009

Вы должны быть в состоянии захватить каждый процесс слова и убить его:

foreach(Process p in System.Diagnostics.Process.GetProcessesByName("winword"))
 {
   p.kill();
   p.WaitForExit();
 }

Также вы должны попытаться увидеть объект документа на ноль?

0 голосов
/ 01 декабря 2009

Просто скажу: офисные приложения не должны запускаться на сервере. Они также не должны использоваться из службы или веб-приложения.

Да - у нас также были требования, которые заставляли нас использовать продукты Office на сервере. И у нас всегда есть проблемы.

Если есть возможность не использовать Office (работа с WordML, новый формат Office XML), сделайте это.

0 голосов
/ 01 декабря 2009

Это сводило меня с ума, пока я не нашел это сообщение на этом сайте. Второе решение на этой странице сработало для меня - первое выглядит проще, но на самом деле может быть сложно отслеживать все скрытые COM-объекты, на которые вы ссылаетесь. Второй метод всегда работает - вам не нужно отслеживать каждый объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...