【完全版】InDesignが落ちる・戻れない!を1クリックで直す「最強の救急箱ツール」をPythonで作った話(コード公開)
- 2026.01.30
- Indesign_Doctor
こんにちは、DTPの現場で戦う皆さん。
「締め切り前なのにInDesignが落ちた!」
「再起動しても、特定のファイルを開くとまた落ちる(無限ループ)」
「なぜか『取り消し(Ctrl+Z)』が3〜4回しかできない…」
こんな絶望的な経験、ありませんか?
InDesignは高機能ゆえに、長く使っているとどうしても「見えないゴミ」が溜まり、動作が不安定になります。
ネットで検索すると「環境設定をリセットせよ」と出てきますが、ショートカットキー(Ctrl+Alt+Shift)の同時押しはタイミングが難しいし、せっかく作ったワークスペースやショートカット設定まで消えてしまうのが怖くて、なかなか踏み切れないですよね。
そこで今回、「InDesignの不調を安全かつ確実に直すための救急箱ツール」 をPythonで自作しました。
今回は、そのツールの機能解説と、誰でも使えるように全ソースコードを公開します。
特に**「軽いデータなのに数回しかUndo(取り消し)できない」**という謎のバグに悩んでいる方は必見です。
目次
-
なぜInDesignは不安定になるのか?
-
自作ツール「InDesign救急箱 (Ultimate V2)」の機能
-
① 壊れたフォントの精密検査&隔離
-
② キャッシュ削除(表示バグ対策)
-
③ 環境設定リセット(設定保護機能付き!)
-
④ 復元データの強制削除(クラッシュループ脱出)
-
-
【コード公開】Pythonで作るInDesign救急箱
-
使い方とexe化の手順
-
まとめ
1. なぜInDesignは不安定になるのか?
PCのスペックは足りているはずなのに、なぜInDesignは重くなったり落ちたりするのでしょうか?
主な原因は以下の3つに集約されます。
A. 「SavedData」の肥大化・破損
InDesignは、操作の履歴(Undo情報)やウィンドウ位置などをInDesign SavedDataという一時ファイルに記録しています。
これが長年の使用で壊れると、**「メモリはあるのに履歴を書き込めない」**という状態になります。
「軽いデータなのに5回しか戻れない」という症状は、十中八九これが犯人です。
B. フォントの破損・競合
フリーフォントや古いフォントの中には、データ構造が微妙に壊れているものがあります。InDesignはフォントの描画にシビアなので、そういった「爆弾フォント」を読み込んだ瞬間にクラッシュします。
C. 復元データの破損
作業中に落ちた際、InDesignは「復元データ」を作ります。しかし、落ちた原因そのものが復元データに含まれている場合、次回起動時にそれを読み込んでまた落ちる…という「無限クラッシュループ」が発生します。
これらを手動でメンテナンスするのは非常に面倒です。そこで、これらを自動で解決するツールを作りました。
2. 自作ツール「InDesign救急箱 (Ultimate V2)」の機能
今回作成したツールは、GUI(画面)で操作できるWindows/Mac両対応のアプリです。
主な機能は以下の4つです。
① 壊れたフォントの精密検査&隔離
指定したフォントフォルダをスキャンし、以下の2段階でチェックします。
-
構造チェック: ファイルとして壊れていないか?
-
描画負荷テスト: 実際にメモリ上で「Testあ亜!?」のような文字を描画できるか?
特に2番目が重要です。「ファイルとしては開けるけど、日本語データが壊れている」といった隠れ危険フォントも見つけ出します。
さらに、TTC(TrueType Collection)形式の全フォントチェックにも対応。
検知された危険なフォントは、ボタン一つで「ゴミ箱」へ移動できます(完全削除ではないので安心です)。
② キャッシュ削除(表示バグ対策)
PC内のAdobe関連フォルダから、トラブルの元凶となりやすいAdobeFnt*.lst(フォントリストキャッシュ)を一括検索して削除します。
「文字が化ける」「フォントメニューがおかしい」といった軽微なトラブルはこれで直ります。
③ 環境設定リセット(設定保護機能付き!)
これが今回の目玉機能です。
InDesignの挙動がおかしい時、公式推奨の対処法は「環境設定のリセット」ですが、これをやるとワークスペースやショートカットが初期化されてしまいます。
このツールでは、リセットを行う前に**「Workspaces」と「Shortcut Sets」フォルダを自動でバックアップ**します。
その後、不具合の原因であるInDesign DefaultsとInDesign SavedDataだけをリネーム(.old化)して無効化します。
つまり、「不具合は直るけど、俺の使いやすい設定は守られる(またはすぐに戻せる)」 という、いいとこ取りのリセットが可能です。
もちろん、インストールされている全バージョンのInDesignを自動検知して、特定のバージョンだけをリセットできます。
④ 復元データの強制削除(クラッシュループ脱出)
InDesignが起動すらしなくなった時のための「最終奥義」です。
InDesign Recoveryフォルダの中身を強制的に空にします。
これにより、壊れた復元データを読み込もうとして落ちるループから脱出できます。
3. 【コード公開】Pythonで作るInDesign救急箱
では、実際のPythonコードを公開します。
GUIライブラリのtkinterを使い、ファイル操作やフォント解析を行っています。
必要なライブラリ:
事前に以下のコマンドでライブラリをインストールしてください。
Bash
pip install fonttools pillow send2trash
ソースコード (indesign_doctor.py):
Python
import os
import threading
import tkinter as tk
import platform
import fnmatch
import datetime
import shutil
import subprocess ### <<< 変更: プロセスチェックのために追加
from tkinter import ttk, filedialog, scrolledtext, messagebox
# ゴミ箱ライブラリ
try:
from send2trash import send2trash
except ImportError:
def send2trash(path):
os.remove(path)
from fontTools.ttLib import TTFont, TTCollection
from PIL import Image, ImageFont, ImageDraw
class FontCheckerApp:
def __init__(self, root):
self.root = root
self.root.title("InDesign救急箱 (Ultimate V2)")
self.root.geometry("500x620") # UI要素が増えたので縦長に
style = ttk.Style()
style.configure("Bold.TButton", font=("Meiryo UI", 9, "bold"))
style.configure("Danger.TButton", foreground="red", font=("Meiryo UI", 9, "bold"))
style.configure("Blue.TButton", foreground="blue", font=("Meiryo UI", 9, "bold"))
# =========================================
# ① フォント検査エリア
# =========================================
frame_check = ttk.LabelFrame(root, text="① フォントファイルの健康診断", padding=10)
frame_check.pack(fill=tk.X, padx=10, pady=5)
frame_path = ttk.Frame(frame_check)
frame_path.pack(fill=tk.X)
ttk.Label(frame_path, text="対象フォルダ:").pack(side=tk.LEFT)
self.entry_path = ttk.Entry(frame_path)
self.entry_path.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
self.entry_path.insert(0, self.get_system_font_folder())
ttk.Button(frame_path, text="参照...", command=self.select_folder).pack(side=tk.LEFT)
self.btn_start = ttk.Button(frame_check, text="フォント検査を実行", command=self.start_check_thread, style="Bold.TButton")
self.btn_start.pack(fill=tk.X, pady=5)
self.btn_delete = ttk.Button(frame_check, text="検知されたファイルをゴミ箱へ移動", command=self.confirm_trash_files, style="Danger.TButton", state='disabled')
self.btn_delete.pack(fill=tk.X, pady=5)
self.progress = ttk.Progressbar(frame_check, orient=tk.HORIZONTAL, mode='determinate')
self.progress.pack(fill=tk.X)
self.lbl_status = ttk.Label(frame_check, text="待機中...")
self.lbl_status.pack()
# =========================================
# ② キャッシュ削除エリア
# =========================================
frame_cache = ttk.LabelFrame(root, text="② おかしくなったらまずコレ (キャッシュ削除)", padding=10)
frame_cache.pack(fill=tk.X, padx=10, pady=5)
ttk.Label(frame_cache, text="※「AdobeFnt*.lst」を削除します。表示がおかしい時に有効。", foreground="#555").pack(anchor=tk.W)
self.btn_cache = ttk.Button(frame_cache, text="フォントキャッシュを削除", command=self.confirm_delete_cache)
self.btn_cache.pack(fill=tk.X, pady=2)
# =========================================
# ③ 環境設定 & 復元データ (バージョン指定)
# =========================================
frame_reset = ttk.LabelFrame(root, text="③ 起動しない・すぐ落ちる時はコレ", padding=10)
frame_reset.pack(fill=tk.X, padx=10, pady=5)
# バージョン選択
frame_ver = ttk.Frame(frame_reset)
frame_ver.pack(fill=tk.X, pady=5)
ttk.Label(frame_ver, text="対象バージョン:").pack(side=tk.LEFT)
self.combo_ver = ttk.Combobox(frame_ver, state="readonly", width=30)
self.combo_ver.pack(side=tk.LEFT, padx=5)
versions = self.scan_indesign_versions()
self.combo_ver['values'] = versions
if versions: self.combo_ver.current(0)
else: self.combo_ver.set("InDesignが見つかりません")
# ----------------------------------------------------
# A. 環境設定リセット (保護機能付き)
# ----------------------------------------------------
ttk.Label(frame_reset, text="A. 環境設定をリセット (バックアップ付)", foreground="#333", font=("Meiryo UI", 9, "bold")).pack(anchor=tk.W, pady=(10,0))
# ★追加機能:設定維持チェックボックス
self.var_keep_settings = tk.BooleanVar(value=True)
self.chk_keep = ttk.Checkbutton(frame_reset, text="ワークスペースとキーボードショートカットを保護(バックアップ)する", variable=self.var_keep_settings)
self.chk_keep.pack(anchor=tk.W, padx=10)
self.btn_reset = ttk.Button(frame_reset, text="環境設定をリセットする", command=self.confirm_reset_prefs, style="Blue.TButton")
self.btn_reset.pack(fill=tk.X, pady=2)
# ----------------------------------------------------
# B. 復元データ削除
# ----------------------------------------------------
ttk.Label(frame_reset, text="B. クラッシュループ脱出 (復元データを削除)", foreground="#333", font=("Meiryo UI", 9, "bold")).pack(anchor=tk.W, pady=(15,0))
self.btn_recovery = ttk.Button(frame_reset, text="復元データ(Recovery Data)を空にする", command=self.confirm_delete_recovery)
self.btn_recovery.pack(fill=tk.X, pady=2)
# =========================================
# ログエリア
# =========================================
frame_log = ttk.Frame(root, padding=10)
frame_log.pack(fill=tk.BOTH, expand=True)
ttk.Label(frame_log, text="実行ログ:").pack(anchor=tk.W)
self.txt_log = scrolledtext.ScrolledText(frame_log, state='disabled', height=10)
self.txt_log.pack(fill=tk.BOTH, expand=True)
self.txt_log.tag_config("ERROR", foreground="red")
self.txt_log.tag_config("WARNING", foreground="#D35400")
self.txt_log.tag_config("SAFE", foreground="green")
self.txt_log.tag_config("INFO", foreground="black")
self.txt_log.tag_config("CACHE", foreground="blue")
self.txt_log.tag_config("TRASH", foreground="purple")
self.txt_log.tag_config("RESET", foreground="#008080")
self.txt_log.tag_config("BACKUP", foreground="#800080") # Purple for backup
self.is_running = False
self.detected_files = []
### <<< 変更: InDesignが起動中かチェックする関数を追加
def is_indesign_running(self):
"""InDesignが起動中かチェックする"""
system = platform.system()
try:
if system == "Windows":
# tasklistの出力をチェック
output = subprocess.check_output(['tasklist'], universal_newlines=True, creationflags=0x08000000) # コンソールウィンドウを非表示に
return 'indesign.exe' in output.lower()
elif system == "Darwin": # macOS
# ps -ax の出力をチェック
output = subprocess.check_output(['ps', '-ax'], universal_newlines=True)
# "Adobe InDesign" がプロセス名に含まれているかで判定
return 'adobe indesign' in output.lower()
except (subprocess.CalledProcessError, FileNotFoundError):
# コマンドが存在しない、またはエラーが発生した場合
self.log("プロセスの確認に失敗しました。", "WARNING")
return False # 安全のためにFalseを返す
return False
def get_system_font_folder(self):
system = platform.system()
if system == "Windows": return r"C:\Windows\Fonts"
elif system == "Darwin": return os.path.expanduser("~/Library/Fonts")
return ""
def scan_indesign_versions(self):
found_versions = ["全バージョン一括 (All)"]
search_path = ""
user_home = os.path.expanduser("~")
system = platform.system()
if system == "Windows":
search_path = os.path.join(user_home, "AppData", "Roaming", "Adobe", "InDesign")
elif system == "Darwin":
search_path = os.path.join(user_home, "Library", "Preferences", "Adobe InDesign")
if os.path.exists(search_path):
try:
dirs = [d for d in os.listdir(search_path) if os.path.isdir(os.path.join(search_path, d)) and "Version" in d]
dirs.sort(reverse=True)
found_versions.extend(dirs)
except: pass
return found_versions
def select_folder(self):
folder = filedialog.askdirectory(initialdir=self.entry_path.get())
if folder:
self.entry_path.delete(0, tk.END)
self.entry_path.insert(0, folder)
def log(self, message, tag="INFO"):
self.txt_log.configure(state='normal')
self.txt_log.insert(tk.END, message + "\n", tag)
self.txt_log.see(tk.END)
self.txt_log.configure(state='disabled')
def set_buttons_state(self, state):
self.btn_start.config(state=state)
self.btn_cache.config(state=state)
self.btn_reset.config(state=state)
self.btn_recovery.config(state=state)
if state == 'normal' and not self.detected_files:
self.btn_delete.config(state='disabled')
elif state == 'disabled':
self.btn_delete.config(state='disabled')
# =========================================
# ③ 環境設定リセット機能 (保護機能付き)
# =========================================
def confirm_reset_prefs(self):
if self.is_running: return
### <<< 変更: InDesignの起動チェックを追加 if self.is_indesign_running(): messagebox.showwarning("確認", "InDesignが起動しています。\nアプリケーションを完全に終了してから再度実行してください。") return target_ver = self.combo_ver.get() if "InDesignが見つかりません" in target_ver: return keep_msg = "\n★ワークスペースとショートカットは保護されます" if self.var_keep_settings.get() else "" res = messagebox.askyesno( "環境設定リセット", f"【{target_ver}】の環境設定をリセットしますか?\n\n" "「InDesign Defaults」と「SavedData」を初期化します。\n" "(戻る回数制限バグなどに有効です)\n" f"{keep_msg}\n\n" "※必ずInDesignを終了してから実行してください。" ) if res: self.start_reset_thread(target_ver) def start_reset_thread(self, target_ver): self.is_running = True self.set_buttons_state('disabled') self.txt_log.configure(state='normal') self.txt_log.delete(1.0, tk.END) self.txt_log.configure(state='disabled') thread = threading.Thread(target=self.run_reset_prefs, args=(target_ver,), daemon=True) thread.start() def run_reset_prefs(self, target_ver): self.log(f"--- 環境設定リセット: {target_ver} ---", "RESET") # リセット対象ファイル target_files = ["InDesign Defaults", "InDesign SavedData"] # 保護対象フォルダ protected_folders = ["Workspaces", "InDesign Shortcut Sets"] user_home = os.path.expanduser("~") system = platform.system() paths_to_check = [] if system == "Windows": paths_to_check.append(os.path.join(user_home, "AppData", "Roaming", "Adobe", "InDesign")) paths_to_check.append(os.path.join(user_home, "AppData", "Local", "Adobe", "InDesign")) elif system == "Darwin": paths_to_check.append(os.path.join(user_home, "Library", "Preferences", "Adobe InDesign")) paths_to_check.append(os.path.join(user_home, "Library", "Caches", "Adobe InDesign")) reset_count = 0 backup_count = 0 timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") is_all = "All" in target_ver do_keep = self.var_keep_settings.get() for root_base in paths_to_check: if not os.path.exists(root_base): continue for dirpath, dirnames, filenames in os.walk(root_base): # ターゲットバージョンか判定 if is_all or (target_ver in dirpath): # ---------------------------------------- # ★ ワークスペース等のバックアップ処理 # ---------------------------------------- if do_keep and "Roaming" in dirpath or "Preferences" in dirpath: # 設定フォルダのルート(ja_JPなど)にいるか確認 for p_folder in protected_folders: if p_folder in dirnames: src_path = os.path.join(dirpath, p_folder) # バックアップ先(同じ階層に _Backup_日付 を作る) backup_folder_name = f"{p_folder}_Backup_{timestamp}" dst_path = os.path.join(dirpath, backup_folder_name) try: if os.path.exists(dst_path): shutil.rmtree(dst_path) # 念のため既存なら消す shutil.copytree(src_path, dst_path) self.log(f"保護(Backup): {p_folder} -> {backup_folder_name}", "BACKUP")
backup_count += 1
except Exception as e:
self.log(f"保護失敗: {p_folder} ({e})", "WARNING")
# ----------------------------------------
# ★ 設定ファイルのリセット(リネーム)
# ----------------------------------------
for target in target_files:
if target in filenames:
file_path = os.path.join(dirpath, target)
backup_name = f"{target}.old_{timestamp}"
try:
os.rename(file_path, os.path.join(dirpath, backup_name))
reset_count += 1
self.log(f"リセット: {target}", "RESET")
except: pass
self.log("-" * 30)
# 結果メッセージの作成
result_msg = ""
if reset_count > 0:
result_msg += f"・設定ファイル {reset_count} 個をリセットしました。\n"
if backup_count > 0:
result_msg += f"・ワークスペース/ショートカットを {backup_count} 箇所バックアップしました。\n"
if result_msg:
self.log("完了しました。InDesignを起動してください。", "SAFE")
if do_keep:
self.log("※もし設定が消えていても、作成された「_Backup」フォルダから\n中身を戻せば復元可能です。", "INFO")
messagebox.showinfo("完了", f"処理が完了しました。\n\n{result_msg}")
else:
self.log("対象の設定ファイルが見つかりませんでした。", "WARNING")
messagebox.showwarning("結果", "リセット対象が見つかりませんでした。")
self.finish_task_common()
# =========================================
# ④ 復元データ削除
# =========================================
def confirm_delete_recovery(self):
if self.is_running: return
### <<< 変更: InDesignの起動チェックを追加 if self.is_indesign_running(): messagebox.showwarning("確認", "InDesignが起動しています。\nアプリケーションを完全に終了してから再度実行してください。") return target_ver = self.combo_ver.get() if "InDesignが見つかりません" in target_ver: return res = messagebox.askyesno("確認", f"【{target_ver}】の自動復元データを削除しますか?\n保存されていない作業データは消えます。") if res: self.start_recovery_thread(target_ver) def start_recovery_thread(self, target_ver): self.is_running = True self.set_buttons_state('disabled') self.txt_log.configure(state='normal') self.txt_log.delete(1.0, tk.END) self.txt_log.configure(state='disabled') thread = threading.Thread(target=self.run_delete_recovery, args=(target_ver,), daemon=True) thread.start() def run_delete_recovery(self, target_ver): self.log(f"--- 復元データ削除: {target_ver} ---", "RESET") target_folder_name = "InDesign Recovery" user_home = os.path.expanduser("~") system = platform.system() paths_to_check = [] if system == "Windows": paths_to_check.append(os.path.join(user_home, "AppData", "Local", "Adobe", "InDesign")) elif system == "Darwin": paths_to_check.append(os.path.join(user_home, "Library", "Caches", "Adobe InDesign")) deleted_count = 0 is_all = "All" in target_ver for root_base in paths_to_check: if not os.path.exists(root_base): continue for dirpath, dirnames, filenames in os.walk(root_base): if is_all or (target_ver in dirpath): if target_folder_name in dirnames: recovery_path = os.path.join(dirpath, target_folder_name) try: files = os.listdir(recovery_path) if not files: continue for f in files: f_path = os.path.join(recovery_path, f) if os.path.isfile(f_path): os.remove(f_path) elif os.path.isdir(f_path): shutil.rmtree(f_path) deleted_count += 1 self.log(f"削除: Recoveryフォルダ内", "RESET") except Exception as e: self.log(f"失敗: {e}", "WARNING") self.log("-" * 30) if deleted_count > 0:
self.log(f"完了: {deleted_count} 個削除しました。", "SAFE")
messagebox.showinfo("完了", "復元データを削除しました。")
else:
self.log("復元データは空でした。", "INFO")
messagebox.showinfo("結果", "復元データは空でした。")
self.finish_task_common()
# =========================================
# ② キャッシュ削除
# =========================================
def confirm_delete_cache(self):
if self.is_running: return
### <<< 変更: InDesignの起動チェックを追加
if self.is_indesign_running():
messagebox.showwarning("確認", "InDesignが起動しています。\nアプリケーションを完全に終了してから再度実行してください。")
return
res = messagebox.askyesno("確認", "フォントキャッシュ(AdobeFnt*.lst)を削除しますか?")
if res: self.start_cache_thread()
def start_cache_thread(self):
self.is_running = True
self.set_buttons_state('disabled')
self.txt_log.configure(state='normal')
self.txt_log.delete(1.0, tk.END)
self.txt_log.configure(state='disabled')
thread = threading.Thread(target=self.run_delete_cache, daemon=True)
thread.start()
def run_delete_cache(self):
self.log("--- キャッシュ削除開始 ---", "CACHE")
user_home = os.path.expanduser("~")
roots = []
if platform.system() == "Windows":
roots = [os.path.join(user_home, "AppData", "Local", "Adobe"),
os.path.join(user_home, "AppData", "Roaming", "Adobe")]
elif platform.system() == "Darwin":
roots = [os.path.join(user_home, "Library", "Caches", "Adobe InDesign"),
os.path.join(user_home, "Library", "Application Support", "Adobe")]
count = 0
for r in roots:
if os.path.exists(r):
for dp, dn, fn in os.walk(r):
for f in fnmatch.filter(fn, 'AdobeFnt*.lst'):
try:
os.remove(os.path.join(dp, f))
count += 1
except: pass
self.log(f"完了: {count} 個削除しました。", "SAFE")
self.finish_task_common()
# =========================================
# ① フォント検査
# =========================================
def confirm_trash_files(self):
if not self.detected_files: return
res = messagebox.askyesno("確認", f"{len(self.detected_files)} 個のファイルをゴミ箱へ移動しますか?")
if res: self.run_trash_files()
def run_trash_files(self):
self.log("--- 削除処理開始 ---", "TRASH")
success = 0
targets = list(set(self.detected_files))
for path in targets:
try:
send2trash(path)
self.log(f"ゴミ箱へ: {os.path.basename(path)}", "TRASH")
success += 1
except: pass
self.detected_files = []
self.btn_delete.config(state='disabled')
messagebox.showinfo("完了", f"{success} 個移動しました。")
def start_check_thread(self):
path = self.entry_path.get()
if not path or not os.path.exists(path): return
if self.is_running: return
self.is_running = True
self.detected_files = []
self.set_buttons_state('disabled')
self.txt_log.configure(state='normal')
self.txt_log.delete(1.0, tk.END)
self.txt_log.configure(state='disabled')
thread = threading.Thread(target=self.run_check, args=(path,), daemon=True)
thread.start()
def run_check(self, folder_path):
self.log("--- チェック開始 ---", "INFO")
valid_exts = ('.ttf', '.otf', '.ttc')
file_list = []
for root, dirs, files in os.walk(folder_path):
for filename in files:
if filename.lower().endswith(valid_exts):
file_list.append(os.path.join(root, filename))
total = len(file_list)
if total == 0:
self.log("ファイルなし", "WARNING")
self.finish_task_common()
return
self.root.after(0, lambda: self.progress.configure(maximum=total, value=0))
corrupt, warning = 0, 0
for idx, file_path in enumerate(file_list):
filename = os.path.basename(file_path)
self.root.after(0, lambda v=idx+1, t=f"確認中: {filename}": self.update_ui(v, t))
if os.path.getsize(file_path) == 0:
self.log(f"[× 破損] {filename}", "ERROR")
corrupt += 1
self.detected_files.append(file_path)
continue
font_indices = range(len(TTCollection(file_path))) if filename.lower().endswith('.ttc') else [0]
is_bad = False
for i in font_indices:
if is_bad: break
try:
font = TTFont(file_path, fontNumber=i)
for tbl in ['name', 'cmap']: _ = font[tbl]
font.close()
except:
self.log(f"[× 破損] {filename}", "ERROR")
corrupt += 1
is_bad = True
continue
try:
img_font = ImageFont.truetype(file_path, 40, index=i)
ImageDraw.Draw(Image.new("RGB",(1,1))).text((0,0), "Testあ亜", font=img_font)
except:
self.log(f"[! 危険] {filename}", "WARNING")
warning += 1
is_bad = True
if is_bad: self.detected_files.append(file_path)
self.log("-" * 30)
if corrupt == 0 and warning == 0:
self.log("★ 問題なし", "SAFE")
messagebox.showinfo("完了", "正常でした。")
else:
self.log(f"破損: {corrupt} / 危険: {warning}", "ERROR")
messagebox.showwarning("完了", "問題が見つかりました。")
self.btn_delete.config(state='normal')
self.finish_task_common()
def update_ui(self, value, text):
self.progress['value'] = value
self.lbl_status.config(text=text)
def finish_task_common(self):
self.root.after(0, self._reset_ui)
def _reset_ui(self):
self.progress['value'] = 0
self.lbl_status.config(text="待機中")
self.set_buttons_state('normal')
self.is_running = False
if __name__ == "__main__":
root = tk.Tk()
app = FontCheckerApp(root)
root.mainloop()
4. 使い方とexe化の手順
このコードを自分のPCで動かす、または同僚に配布するための.exeファイルを作る手順です。
手順①:Pythonのインストール
Python公式サイトからPythonをダウンロードしてインストールします。インストーラーの「Add Python to PATH」にチェックを入れるのを忘れずに。
手順②:ライブラリのインストール
コマンドプロンプト(またはターミナル)を開き、以下のコマンドを入力します。
Bash
pip install pyinstaller fonttools pillow send2trash
手順③:exeファイルの作成
上記のPythonコードをコピーして、indesign_doctor.py という名前で保存します。
保存したフォルダでコマンドプロンプトを開き、以下を実行します。
Bash
pyinstaller --onefile --noconsole --clean indesign_doctor.py
少し待つと、同じフォルダ内にdistというフォルダができ、その中にindesign_doctor.exeが完成しています!
これを実行するだけで、誰でもInDesignのメンテナンスが可能になります。
5. まとめ
InDesignのトラブルの9割は、このツールで解決できます。
-
戻る回数が少ない? → 環境設定リセット(SavedDataの初期化)で直ります。
-
特定のファイルで落ちる? → フォント検査で「危険」なフォントを探して捨ててください。
-
起動しない? → 復元データ削除でループから脱出できます。
「原因不明の不調」に怯えながら作業するのは精神衛生上よくありません。
ぜひこのツールをUSBメモリに入れて、「InDesign救急箱」として現場に常備してみてください。あなたの、そしてチームの貴重な時間を守れるはずです。
EXEのダウンロードはこちら(ちなみにアイコンは作ってませんのでご了承を)
2026/01/31 コードの変更。リセット時、indesignが落ちてるか確認処理を追加
2026/01/30 公開
-
前の記事
RecoveryFox AIを使ってみた【徹底的にレビュー】 2025.12.10
-
次の記事
記事がありません

コメントを書く