0. 前置き
PC を使う場合、多くの人は Windows の画面操作に慣れており、CLI / CUI*1 は言うに及ばず、Tk や Web ブラウザの操作でさえ極端に嫌がります。
その人たちが決まって口にするのは「今までと違うから認めない」です。
この「今まで」というのは過去の遺物である VisualBasic*2 や VisualC のクラスライブラリで作成された操作画面を指します。
*1CUI は CLI を包含する意味があるのに、なぜか Wikipedia では同一に扱われている。
CUI とは Character User Interface の略で、罫線文字や色文字を巧みに配置して GUI を模倣した画面を含む。(例: Vim)
CLI とは Command Line Interface の略で REPL の形態を指す。入出力行の表示は単方向で、画面の座標を扱わない。(例: Bash)
*2以下 VB と呼称する。
21 世紀も 25 年を消化する今では PC の性能が十分に高性能になったため、
アルゴリズムに融通の利かない VB をわざわざ使用するのは面倒なだけで意味がありません。
(多次元の可変長リストや、ビット幅の異なる複数の返戻値を返す関数を VB で実装するとか、考えるだけで嫌になる)
事務用画面の場合は、大規模かつ高速性を得意とする C/C++ を使用するのも効率が悪すぎます。(そもそも C ができる技術者がいない)
また、画面に納得がいかない人に限って、その分のコストを負担しようとしません*3。
*3GUI の入力は想定外事象が多すぎて作業が煩雑になるのに、それを理解する頭を持ち合わせていない。
そこで、
という考えにたどり着くのは必然と言えます。
- 画面は VB で作成
- そのほかのロジックは VB 以外の言語で作成
ここでは、フロントエンドを VB にして、バックエンドを Python で実装します。
VB と Python の連携手法はいくつかありますが、高速性と保守性*4に優れる COM オブジェクト*5で Python を使用します。
*4HTTP サーバ形式にすると管理の負荷が上がる。コマンド呼び出しにするとオーバーヘッドが問題になる。ライブラリ形式ならそれらよりマシ。
*5COM: Component Object Model の略称。規約に則っていれば相互に呼び出すことが可能な API のライブラリのこと。
Python は COM の呼び側、呼ばれ側のどちらにもなれる。
1. Visual Studio のインストールと確認
1-1. ここを参考にして Visual Studio をインストールする。
1-2. Visual Studio Installer を起動する。
スタート > すべて > の V から Visual Studio Installer を起動する。1-3. .NET デスクトップ環境 が組み込まれていることを確認する。
「インストール済み」タブの ボタンをクリックする。
⇓
「ワークロード」タブの「.NET デスクトップ開発 ✅」にチェックがあることを確認する。
(VB でデスクトップアプリを作成するには .NET が必須なのに、なぜかオプションの扱いになっている)
2. Python をインストール
注意
- • Microsoft Store 版の Python では動作しません
- • ファイルエクスプローラから PowerShell を起動すると動作しません
• 必ず公式版 Python だけをインストールしてください。
Microsoft Store 版の Python は、COM が登録できても DLL がリンクできずにエラーとなります。
もしも Microsoft Store 版の Python が残っていたら pip を含め、すべてアンインストールする必要があります。
• フォルダ構成が深いとファイルエクスプローラから PowerShell (または cmd) を起動したくなりますが、これをすると
環境変数がおかしな設定になり異常動作をするため、必ず田 (スタート) から「ターミナル」を選択してください。
2-1. 公式サイトからインストーラをダウンロードする。
公式サイトをブラウザで開く。2-2. インストーラを実行する。
Stable Releases の Windows installer (64-bit) をクリックしてインストーラをダウンロードする。
python-x.xx.x-amd64.exe (今回は python-3.13.5-amd64.exe だった)
Windows11 は 32bit 版が無いので、あえて 32bit 版の Python を選択する必要はない。
python-3.13.5-amd64.exe を実行する。2-3. Python のバージョンを確認する。
✅ Add python.exe to PATH にチェックを入れて
「→ Install Now」をクリックする。
Add python.exe.to PATH にチェックを入れない場合は、
後述の python, pip コマンドをフルパスで実行する必要がある。
python コマンドの格納フォルダーは Install Now のすぐ下に表示されている。
⇓
待つ。
⇓
ボタンをクリックする。
2-4. pip のバージョンを最新にする。
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # Python のバージョンを確認する PS C:\> python --version⏎ Python 3.13.5 PS C:\> # Python のビット数を確認する('P' はポインタのバイト数の意味) PS C:\> python -c "import struct; print(struct.calcsize('P')*8)"⏎ 64 PS C:\> exit ⏎
2-5. pywin32 をインストールする。
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # pip のバージョンを最新にする PS C:\> python -m pip install --upgrade pip⏎ PS C:\> exit ⏎
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # pywin32 をインストールする PS C:\> pip install pywin32⏎ PS C:\> pip show pywin32 | Select-String "Location:"⏎ Location: C:\Users\who\AppData\Local\Programs\Python\Python313\Lib\site-packages PS C:\> exit ⏎
3. COM オブジェクトを作成
3-1. GUID を生成する。
GUID は巨大なランダム値なので登録のたびに生成しても構わないが、(他の GUID と重複することがほぼないとされている)3-2. Python のプログラムを作成する。
自動的に消える仕組みは存在せず、不要になったら手動で削除する必要がある。
人為的ミスで削除を怠ったせいでレジストリが肥大化することがあり、これを避けるために固定化する。
(Windows は人為的ミスを防止できるシステムになっていない)
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # GUID を生成する PS C:\> python -c "import uuid; print(str(uuid.uuid4()).upper())"⏎ 00000000-1111-2222-3333-444444444444 ← これを Python のプログラムに張り付ける。 PS C:\> exit ⏎
ファイル名: hello_com.py (ファイル名は登録とは無関係。覚えやすい名前にする)3-3. COM オブジェクトとして登録する。
from win32com.server.policy import DesignatedWrapPolicy # <- 必須 class Win32ComSample(DesignatedWrapPolicy): # クラス名は何でも良い _reg_progid_ = 'hello.pywin32' # 公開する COM オブジェクト名 _reg_clsid_ = '{00000000-1111-2222-3333-444444444444}' # 上記 3-1 で生成した GUID _public_methods_ = ['Init','Hello','Add','Sum'] # 公開する関数名 def __init__(self): # COM は CreateObject() で引数を渡せない。 self._wrap_(self) # <- DesignatedWrapPolicy では必須 (公開関数のディスパッチャを準備) self.init = False # 初期化の例 def Init(self, arg): self.init = True # 文字列を返す例 def Hello(self): return 'Hello, pywin32' # 2 つの数値の和を返す例 def Add(self, a, b): return a + b # 可変個数の総和を返す例 def Sum(self, *args): return sum(args) if __name__ == '__main__': import win32com.server.register win32com.server.register.UseCommandLine(Win32ComSample)
ここで確認するのはレジストリの登録だけ。
実はレジストリに登録されただけでは動作しない。自動的に DLL とリンクされる。
ファイルエクスプローラから PowerShell を起動すると、DLL のリンクが失敗するため動作しない。
*6登録を解除する場合は python hello_com.py --unregister を実行する。
− □ × >_ Windows PowerShell × + | ∨
Windows PowerShell Copyright (C) Microsoft Corporation. All rights reserved. 新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows PS C:\> # COM として登録する*6 PS C:\> python hello_com.py --register⏎ここで UAC が表示される。
ボタンをクリックする
(当該ターミナルを管理者で起動した場合は UAC が表示されない)
PS C:\> # レジストリに登録されたか確認する (1) PS C:\> Get-ItemProperty -Path "Registry::HKEY_CLASSES_ROOT\hello.pywin32\CLSID" | Select-Object "(default)"⏎ ↑上記 3-2 で指定した COM オブジェクト名 (default) --------- {00000000-1111-2222-3333-444444444444} ← 指定した GUID
PS C:\> # レジストリに登録されたか確認する (2) PS C:\> Get-ItemProperty -Path "Registry::HKEY_CLASSES_ROOT\CLSID\{00000000-1111-2222-3333-444444444444}" ` | Select-Object "(default)"⏎ ↑ 上記 3-1 で作成した GUID (default) --------- hello.pywin32 ← 指定した COM オブジェクト名 PS C:\> exit ⏎
4. VB のプロジェクトを作成
4-1. Visual Studio を起動し、プロジェクトを作成する。
「新しいプロジェクトの作成(N)」をクリックする。
⇓
下記条件でテンプレートを絞り込み、
「Windows フォーム アプリケーション (.NET Framework) を選択し、
ボタンをクリックする。
言語 プラットフォーム プロジェクトの種類
⇓
下記条件を記入し ボタンをクリックする。
プロジェクト名(J): WindowsApp1 場所(L): C:\Users\who\source\repos ソリューション名(M): WindowsApp1 フレームワーク(F):
5. 呼び出し部の作成
5-1. VB のプログラムを記述する。
フォームに作成したボタン のクリックイベントから hello.pywin32 の各関数を呼び出す例。
注意: pywin32 は Visual Studio 向けのライブラリ情報を持たないので、補完機能や文法チェックは使えない。
Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim obj As Object obj = CreateObject("hello.pywin32") '登録した COM オブジェクト名 obj.Init('') Dim hello As String hello = obj.Hello() Dim answer As Integer answer = obj.Add(1, 2) MessageBox.Show("1 + 2 = " & answer.ToString(), hello) Dim summary As Integer summary = obj.Sum(1, 2, 3, 4, 5, 6, 7, 8) MessageBox.Show("1 ~ 8 の合計は " & summary.ToString(), hello)
End Sub End Class