Что определяет, к какому экземпляру Excel подключается COM-объект Excel.Application?

import win32com.client as win32

excel = win32.gencache.EnsureDispatch('Excel.Application')
for wb in excel.Workbooks:
    print(wb.Name)

Когда я запускаю этот скрипт с помощью Sublime Text: печатается список имен открытых книг.

Когда я запускаю этот скрипт с помощью PyCharm: я получаю пустой список.

Оба находятся на одном ПК и используют одну и ту же версию Python (32-разрядная версия 3.5).

Не уверен, что эта информация имеет значение, но я никогда не запускал установщик PyCharm, когда впервые загрузил PyCharm. Я скачал zip-файл и каждый раз запускал PyCharm.exe из разархивированной папки. Может ли это быть причиной?


person ambiguous58    schedule 29.09.2018    source источник
comment
Обе ваши IDE работают от имени одного и того же пользователя и без повышения прав?   -  person ivan_pozdeev    schedule 30.09.2018
comment
Теперь, когда я об этом думаю, я запускаю PyCharm в качестве администратора. Как вы думаете, это может объяснить это?   -  person ambiguous58    schedule 30.09.2018
comment
Да, Excel COM не использует повторно хост-процессы другими пользователями (работа с повышением прав выполняется от имени другого пользователя). Я добавил это к ответу.   -  person ivan_pozdeev    schedule 30.09.2018
comment
Действительно, после отключения опции «Запуск от имени администратора» для PyCharm.exe скрипт работал как положено, отображая список открытых книг. Благодарю вас!   -  person ambiguous58    schedule 30.09.2018


Ответы (1)


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

Чтобы обеспечить подключение к существующему экземпляру, вы можете использовать win32com.client.GetActiveObject(<ProgID>) в соответствии с Присоединение к уже запущенному приложению Office из вашего приложения с помощью GetActiveObject или BindToMoniker — .NET4Office.


Я заметил следующие шаблоны, которые определяют, к какому экземпляру Excel подключается объект Excel.Application:

  • Если у вас есть экземпляр Excel, который был запущен вручную перед запуском вашей программы, программа подключается к этому экземпляру.
  • If not, an excel.exe instance is spawned by the svchost.exe process hosting the DCOM process launcher service
    • This instance doesn't initially have any workbooks open
  • Однако если вы после этого запустите Excel вручную, будет создан второй экземпляр. Экземпляр DCOM имеет приоритет.
  • Экземпляр не закрывается даже после .Quit, если на него есть ссылки , поэтому любые дальнейшие отправки из того же процесса, пока у него есть ссылки на него, получат тот же экземпляр.
  • Вы не можете подключаться к процессам Excel, запущенным от имени разных пользователей (в том числе с повышением прав и без).

Итак, если вы, например. запускайте свой код из интерактивной консоли, или среда IDE не перезапускает процесс Python каждый раз (маловероятно, но возможно), у вас могут быть старые существующие ссылки.

person ivan_pozdeev    schedule 29.09.2018