Взаимодействие с Excel создает экземпляры прокси-сервера с несколькими квартирами в потоке STA

#.net #com #interop #com-interop #excel-interop

#.net #com #взаимодействие #com-взаимодействие #excel-interop

Вопрос:

Из того, что я понимаю из квартир в .NET, когда мы создаем COM-объект с многопоточностью внутри потока STA, мы должны получить ссылку на реальный объект, а не на межквартирный прокси.

 [TestMethod]
Public void ExcelShouldNotBeMarshalled()
{
     var excelApp = new Microsoft.Office.Interop.Excel.Application();
     if (excelApp is IMarshal)
         throw new Exception(“Should not be a proxy as we are running this in a STA and registry ThreadingModel is empty”);
}
  

Я не могу заставить это работать с любой комбинацией ThreadingModel, которую я пытаюсь.

Есть ли что-нибудь, что я мог упустить?

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

Комментарии:

1. Если вы подключаетесь к нерабочему COM-серверу, вы всегда получаете прокси.

2. Просто используйте поток. currentThread. GetApartmentState() для выполнения этого теста.

3. @SimonMourier спасибо, я думаю, это решает мой первоначальный вопрос. Теперь возникает второй вопрос: есть ли какой-либо способ убедиться, что обработчики событий, передаваемые из этого объекта прокси-приложения, всегда передаются в один и тот же поток STA (как если бы он был в процессе)?

4. Не уверен, что именно вам нужно, и я не понимаю, что вы подразумеваете под «… обработчиками событий… распространяются на тот же поток STA «. Является ли ваш поток, в котором вы создали объект Excel STA или MTA?

5. Если вы хотите, чтобы ваш «тест выполнялся как можно ближе к реальному приложению» … тогда почему бы не написать дополнение и фактически использовать реальное приложение? Или … вам действительно не нужно этого делать … напишите какой-нибудь C #, который можно вызвать с помощью скрипта Excel VBA. Excel VBA может создать ваш COM-объект C #, который затем будет находиться в той же квартире, что и Excel, инициализировать объект выбранным вами объектом Excel и запустить ваш тест. Если вы вызываете Excel из другого процесса, всегда должна быть маршалинг.

Ответ №1:

Как ответил Саймон в комментариях, Excel выполняется в отдельном процессе, и часть кода «новое приложение» всегда будет предоставлять прокси-сервер — независимо от модели ввода.

Чтобы избежать прокси-объектов и запустить тест так же, как в рабочей среде, Джозеф предложил в комментариях запустить тест с помощью VBA, вызывая .Сетевые методы. Я нашел это подходящим, поэтому я реализовал использование возможностей xUnit для настройки выполнения тестов и обработки VBA, вызывающих мои методы тестирования. Это решает проблемы, связанные с моим прокси, и, как плюс, повышает скорость тестирования.

Спасибо всем участникам!