C # .Net4: правильное размещение (динамические) COM-объектов - PullRequest
9 голосов
/ 28 февраля 2011

Мне нужно автоматизировать офисные документы (Word & Excel) из моего приложения .Net4.

Поскольку я не могу заставить своих пользователей использовать определенную версию Office, я не использую сборки взаимодействия или tlbimp, поэтому мой проект не содержит никаких дополнительных ссылок, и не произойдет сбой всего приложения, если Officeне установлен (функция просто недоступна).

Вместо этого я спрашиваю систему, какой COM-сервер может обрабатывать «Word.Application» или «Excel.Application»:

dynamic app = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application"));
app.Foo();

IЯ обеспокоен тем, как правильно избавиться от объекта «приложение», когда я закончу с ним, поскольку теперь у меня есть две внутренние системы управления, о которых нужно беспокоиться (подсчет ссылок COM и отслеживание ссылок .Net).В идеале я должен иметь возможность обернуть динамический объект приложения в одноразовый класс-обертку и быть уверенным, что базовый COM-объект не будет ссылаться при удалении обертки.

РЕДАКТИРОВАТЬ: Кроме того, я хотел бы знать, как правильно заставить COM-объект "жить", когда я закончил, так как Word находится в отдельном процессе.Я должен иметь возможность создать приложение Word, автоматизировать его, а затем освободить все ссылки, но приложение Word должно оставаться открытым.

1 Ответ

8 голосов
/ 28 февраля 2011

Я бы определенно реализовал IDisposable и вызвал бы Marshal.ReleaseComObject внутри него. Убедитесь, что вы правильно внедрили одноразовый шаблон , чтобы избежать повторного освобождения COM-объекта и дальнейшего сокращения количества ссылок, хотя это может не иметь значения, если вы собираетесь создать только один экземпляр COM объект. Я успешно применял этот шаблон в прошлом, поэтому вы определенно движетесь в правильном направлении.

Я думаю, Word останется открытым, даже если в вашем приложении последний COM-объект имеет ссылку на 0, если вы явно не попросите его выйти. (Word.Application.Close()?)

...