4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

`comtypes`の追加機能 - GUIDのみでモジュール生成が可能に

Posted at

論旨

PythonでCOMオブジェクトを操作するcomtypesへコントリビュートを行い、私が追加した機能を含むものがバージョン1.1.13で最近リリースされたのでその紹介です。

追加機能概要

client.GetModule(("{ライブラリのGUID}",))でモジュールが生成・取得できるようになります。

GUIDとは

Globally Unique Identifier「グローバル一意識別子」のこと。
{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}(xは16進数)で表現されます。
COMオブジェクトやCOM型ライブラリは、(レジストリに登録されていれば)この一意のIDから呼び出すことが可能です。
https://ja.wikipedia.org/wiki/GUID

Examples

from comtypes.client import GetModule
GetModule(("{00020813-0000-0000-C000-000000000046}",))  # Excel
GetModule(("{00020905-0000-0000-C000-000000000046}",))  # Word

従来機能との違い

これまでもGetModuleに様々な引数を渡すことでCOM型ライブラリからPythonのモジュールを生成/呼び出すことは可能でした。

# `(GUID, メジャーバージョン, マイナーバージョン)`のタプル
GetModule(("{00020813-0000-0000-C000-000000000046}", 1, 9))  # Excel
# 型ライブラリ情報があるファイルのフルパス
GetModule("C:\\Program Files\\Microsoft Office\\Root\\Office16\\EXCEL.EXE")  # Excel
# 環境変数にアサインされたDLL(TLB)名
GetModule("UIAutomationCore.dll")  # UIAutomationClient
GetModule("stdole2.tlb")  # stdole
# GetModule("EXCEL.EXE")  # これは(デフォルトで)環境変数にアサインされていないため不可

ですが、環境によってライブラリのメジャーバージョンやマイナーバージョン、型ライブラリファイルのフルパスは異なります。
client.CreateObject("Excel.Application")のようにオブジェクトの生成は環境が違ってもクラス名文字列(VersionIndependentProgID)のみでバージョン情報が不要だったのに対し、client.GetModuleによるモジュールの生成はバージョン情報の指定が必要でした。
今回の機能追加によって、ライブラリGUIDのみのタプルが渡された場合にはclient.GetModule関数内部でレジストリを調べて規定値のバージョンを取得してモジュールを生成できるようになります。

新機能がどう役立つか

私が参画しているプロジェクトでは、comtypesでExcelを操作する際にcomtypes.gen.Excelモジュールが環境内で確実に存在する必要がある実装をしているスクリプトがあります。
そのためにスクリプト実行前にclient.CreateObject("Excel.Application")でアプリケーションオブジェクトを生成して、その副作用によってcomtypes.gen.Excelモジュールが作成されるようにしていました。
しかし、オブジェクトを操作したいわけでもないのにオブジェクトを生成していることは不健全です。

  • オブジェクトの生成に時間がかかります(手元環境で31.79秒)
  • ユーザーがスクリプトの本処理が始まらないことに焦れて途中で処理を終了させると、comtypes.gen.Excelモジュールの作成に失敗して、一度genフォルダを消さない限り何度再実行してもスクリプトが異常終了し続けることがあります

代わりに、client.GetModule(("{00020813-0000-0000-C000-000000000046}",))を使うことで、オブジェクトを生成することなくモジュールが生成できるため

  • 時間がかからない(手元環境で3.33秒)
  • ユーザーが焦れる要因が少なくなる
  • 後続処理を早く進める

ことが可能となります。

今後

現在、私はcomtypesへのコントリビュートを続けています。
機能追加の計画やバグフィックスなど最新の情報はリポジトリをご覧ください。
みなさんのコントリビュートもお待ちしております。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?