![[Python] 創作環境を整える ~Windows Terminal タブ管理~(startup.py 編)」](https://humanxai.info/images/uploads/python-startup-powershell.webp)
はじめに
ブログ作成をはじめて以降、git コマンドを日常的に叩くようになった事に踏まえ、アプリ開発で複数のプロジェクトを切り替えるのに、powershellやコマンドプロンプトを複数起動するのが日課になりました。
VScodeからもターミナルは起動できますが、コマンドプロンプト 及び powershellを起動時にまとめてタブ化する方法と、Pythonで普段よく使うアプリを一括起動するスタートアップスクリプトの紹介です。
課題と背景
1. プロジェクトごとに作業フォルダが異なる
コマンドでフォルダ移動するより、タブで切り替える方がウインドウに役割分担させ分かりやすい。
2. 起動後に毎回 cd や git status を叩くのが面倒
ターミナル起動時に一連のコマンドを毎回入力するのが面倒なので、その作業を楽にする。
3. フォルダやバッチを毎回手動でクリックしていた…
プログラミングや、ブログ記事作成、画像生成AI、動画生成AIなど、特定の作業をする際に立ち上げるアプリが決まっている為、 ショートカットをフォルダにまとめて手作業で起動してましたが、Pythonで一括起動できると、ワンクリックで完結
4. ウインドウを配置がバラバラ
特定のアプリは決まった場所に配置する事が多い為、ウインドウ座標を設定し、移動の手間を軽減。
5. まとめ
これらをスクリプトで一括管理する事で、PC起動・再起動時の負担を軽減。
AutoIT
昔、AutoITでスタートアップスクリプトを自作してました。
Windows7や10の頃に作ったもので、Windows11 環境や新しいアプリに対応できなくなった為、今回はPyhonで作り直します。
startup.py の導入
実は、以前にスタートアップスクリプトは作成済みです。
このスクリプトを配置したフォルダ内にある、ショートカットをすべて起動し、APPSで設定したウインドウに関しては、自動で移動とリサイズを行う仕組みです。 スクリプト自体を起動すると無限ループしてしまうので、拡張子をみて起動制御を行っています。(→valid_extensions)
その他詳細は、関数名やデバック用ログ出力などで、凡その処理内容は想像がつくと思います。
import os
import time
import win32gui
import win32con
# 移動対象のみ定義(起動対象はすべて自動で処理)
APPS = [
{"title": "Visual Studio Code", "x": 229, "y": 0, "width": 1371, "height": 1158},
{"title": " - Cursor", "x": -1313, "y": -1, "width": 1314, "height": 1158},
]
# オープン:ファイル・フォルダー・ターミナル
def open_all_files(folder):
valid_extensions = ('.bat', '.lnk', '.exe')
for file in os.listdir(folder):
full_path = os.path.join(folder, file)
if os.path.isfile(full_path) and file.lower().endswith(valid_extensions):
print(f"▶ 一括起動中: {file}")
try:
os.startfile(full_path)
time.sleep(0.5) # 連続起動防止
except Exception as e:
print(f"❌ 起動失敗: {e}")
# ウインドウ移動
def move_window(title, x, y, width, height):
def enum_handler(hwnd, _):
window_title = win32gui.GetWindowText(hwnd)
if title.lower() in window_title.lower():
print(f"✅ 移動対象: {window_title}")
win32gui.MoveWindow(hwnd, x, y, width, height, True)
win32gui.EnumWindows(enum_handler, None)
# 指定秒数待機し、特定アプリを移動・リサイズ
def wait_and_move(apps, delay=7):
print(f"⏳ アプリの起動を {delay} 秒待機中...")
time.sleep(delay)
for app in apps:
move_window(app["title"], app["x"], app["y"], app["width"], app["height"])
if __name__ == "__main__":
folder = os.path.dirname(os.path.abspath(__file__))
open_all_files(folder) # ← すべての起動対象を一括処理
wait_and_move(APPS, 7) # ← 移動対象は限定的に
機能追加
現状の startup.py の追加案・改良ポイントとして「PowerShell/コマンドプロンプト」を複数起動する際に、個別にウインドウを作成せず、 まとめてタブ分け対応し、尚且つ、PowerShellとコマンドプロンプトのタブを分けたい。
解決案
この点については、Windows Terminal のタブ管理機能を使えば、かなり柔軟な制御が可能です。
wt.exe でタブごとに分ける
Windows Terminal(wt)は以下のようにタブごとにアプリを分けて起動できます:
wt `
-w 0 nt -p "PowerShell" -d . powershell.exe ; `
nt -p "Command Prompt" -d . cmd.exe
Pythonでの起動例
以下のようなコマンドを os.system() で実行すると、最初から「PowerShellタブ」と「cmdタブ」に分けられます:
import os
# 複数のタブを同時に開く(PowerShellとCMDを分ける)
os.system(
'wt -w 0 nt -p "PowerShell" -d . powershell.exe ; '
'nt -p "Command Prompt" -d . cmd.exe'
)
応用:既存の startup.py に組み込む
以下のようにすれば、ショートカット類とは別に「PowerShellタブ」と「cmdタブ」を追加で開くことが可能。
def open_terminal_tabs():
try:
os.system(
'wt -w 0 nt -p "PowerShell" -d . powershell.exe ; '
'nt -p "Command Prompt" -d . cmd.exe'
)
print("✅ Windows Terminal タブ起動完了")
except Exception as e:
print(f"❌ Windows Terminal 起動失敗: {e}")
そして main 関数で:
if __name__ == "__main__":
folder = os.path.dirname(os.path.abspath(__file__))
open_all_files(folder)
open_terminal_tabs() # ← 新たにタブで端末を開く
wait_and_move(APPS, 7)
プロファイルの確認方法
プロファイル名 “PowerShell” や “Command Prompt” は環境によって異なる場合があるので、正確に知りたい場合は以下で確認可能です:
wt --list
🔚 まとめ
- wt コマンドでタブごとの起動が可能。
- Python から os.system() で柔軟に制御可能。
- 今後の拡張(Git Bash や WSL 起動など)にも対応しやすい。
- startup.py の一部として非常に自然に統合可能。
subprocess.Popen
os.system以外に、subprocess.Popenを使う方法
import subprocess
subprocess.Popen([
"wt",
# 🔸コマンドプロンプト(バッチ)
"nt", "--title", "FramePack", "-d", "C:\\AI\\framepack_cu126_torch26", "cmd", "/k", "run_endframe_ichi.bat",
";", "nt", "--title", "WebUI", "-d", "C:\\AI\\stable-diffusion-webui", "cmd", "/k", "webui-user.bat",
# 🔹PowerShell タブ
";", "nt", "--title", "my-blog", "-d", "C:\\Users\\user-name\\my-blog", "powershell",
";", "nt", "--title", "matching-game", "-d", "C:\\Users\\user-name\\matching-game", "powershell",
";", "nt", "--title", "project-stg01", "-d", "C:\\Users\\user-name\\my-blog\\cursor\\project-stg01", "powershell"
])
補足
- “cmd”, “/k”, “バッチ名.bat” の形式で記述しないと bat が無視されます。
- –title は表示用のタブ名で、実行内容に影響しません。
- wt コマンドは Windows Terminal が必要です
- wt は Windows Terminal の実行ファイル
- パスやファイル名に全角文字が混ざっていると失敗ケースがあるので注意
- 各タブで -d によって起動パスを指定しているため、バッチ実行やスクリプト編集にすぐ移れます
完成品
フォルダ内にbatファイル配置してまとめて起動->タブでグループ化を目指しましたが難しいようなので、今回は、スクリプト内にパスを設定る方法で回避しました。
まだ改良の余地があるので修正バージョンを再度公開するかもしれません。
import os
import time
import subprocess
import win32gui
import win32con
# ウィンドウの移動対象リスト
APPS = [
{"title": "Visual Studio Code", "x": 229, "y": 0, "width": 1371, "height": 1158},
{"title": " - Cursor", "x": -1313, "y": -1, "width": 1314, "height": 1158},
]
# ✅ Windows Terminal 一括タブ起動関数
def launch_terminal_tabs_fixed():
subprocess.Popen([
"wt",
# 🔸コマンドプロンプト(バッチ)
"nt", "--title", "FramePack", "-d", "C:\\AI\\framepack_cu126_torch26", "cmd", "/k", "run_endframe_ichi.bat",
";", "nt", "--title", "WebUI", "-d", "C:\\AI\\stable-diffusion-webui", "cmd", "/k", "webui-user.bat",
# 🔹PowerShell タブ
";", "nt", "--title", "my-blog", "-d", "C:\\Users\\fixjp\\my-blog", "powershell",
";", "nt", "--title", "matching-game", "-d", "C:\\Users\\fixjp\\matching-game", "powershell",
";", "nt", "--title", "project-stg01", "-d", "C:\\Users\\fixjp\\my-blog\\cursor\\project-stg01", "powershell"
])
def open_all_files(folder):
valid_extensions = ('.bat', '.lnk', '.exe')
for file in os.listdir(folder):
full_path = os.path.join(folder, file)
if os.path.isfile(full_path) and file.lower().endswith(valid_extensions):
print(f"▶ 一括起動中: {file}")
try:
os.startfile(full_path)
time.sleep(0.5) # 連続起動防止
except Exception as e:
print(f"❌ 起動失敗: {e}")
def move_window(title, x, y, width, height):
def enum_handler(hwnd, _):
window_title = win32gui.GetWindowText(hwnd)
if title.lower() in window_title.lower():
print(f"✅ 移動対象: {window_title}")
win32gui.MoveWindow(hwnd, x, y, width, height, True)
win32gui.EnumWindows(enum_handler, None)
def wait_and_move(apps, delay=7):
print(f"⏳ アプリの起動を {delay} 秒待機中...")
time.sleep(delay)
for app in apps:
move_window(app["title"], app["x"], app["y"], app["width"], app["height"])
if __name__ == "__main__":
folder = os.path.dirname(os.path.abspath(__file__))
launch_terminal_tabs_fixed() # ← PowerShell/CMD を一括タブ起動
open_all_files(folder) # ← .batや.exeなどを追加で起動(オプション)
wait_and_move(APPS, 7) # ← ウィンドウ位置を整理
免責
スクリプトの利用は、自由にしていただいて構いませんが、トラブルが発生された場合、責任は持てませんので自己責任でお願いいたします。
💬 コメント