4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

フォルダツリー生成GUIツールを作成してみました。

4
Last updated at Posted at 2025-09-11

Windows/WSL2対応のフォルダツリー生成GUIツールをPowerShellで作ってみました。
ファイル(ディレクトリ)構成を簡単に作成できます。
いつもの需要無視です。

更新情報(2025-11-15)

**v2.0をリリースしました。**主な改善点:

  • コメントスタイル選択機能:ツリー生成時にコメント記号(//#、コメントなし)を選択可能になりました
  • WSL複数ディストリビューション対応:UNCパス(\\wsl.localhost\Ubuntu-22.04\...)から自動的に正しいディストリビューションを判定し、意図した環境で確実に実行されるようになりました
  • 安全性の向上:ジャンクションやシンボリックリンクを自動除外し、循環参照による無限ループや予期しない巨大ツリー展開を防止
  • 安定性の向上:ディレクトリ・ファイルの列挙順序をアルファベット順に統一し、実行ごとに結果が変わる問題を解消
  • 内部品質の改善:スコープ管理の最適化により、メモリ効率と保守性が向上

詳細な変更内容はGitHubリポジトリリファクタリング記録.mdをご覧ください。


ツール作成背景

私はプログラム開発と学習において、生成AIとの対話を通じてコーディングを進めています。
生成AIを開発に活用している方なら、同じようにAIとのチャットを重ねているのではないでしょうか?

よくある課題

Claude等のチャットAIサービスでプロジェクトを立ち上げ、複数のコードファイルを登録する際、ファイル構成を説明するために以下のようなテキストツリーをチャットに貼り付ける必要があります:

MyProject/                        // プロジェクトルート
├── docs/                         // ドキュメント関連
│   ├── manual.pdf                // 操作マニュアル
│   └── readme.txt                // 簡易説明書
├── src/                          // ソースコード
│   ├── main.js                   // メインプログラム
│   └── style.css                 // スタイルシート
├── tests/                        // テストコード
│   └── test_main.js              // メインのテスト
├── .gitignore                    // Git除外設定
├── package.json                  // npm設定ファイル
└── README.md                     // プロジェクト説明

既存手法の問題点

通常はtreeコマンド等で生成しますが、以下の問題があります:

  • 不要なフォルダやファイルまで出力される(node_modules等)
  • 出力結果の加工に手間がかかる
  • コメントを追加するのが面倒
  • Windows/WSL2間の切り替えが煩雑

このツールの解決策

本ツールは、これらの課題を解決するために開発しました:

  • GUIで直感的に操作できる
  • 必要な項目だけを選択してツリー生成
  • コメント用の「//」を自動整列
  • Windows/WSL2両対応でシームレスに切り替え可能

ツールの概要

ソースコード
https://github.com/ya-ma-n-1972/powershell_tool_report/tree/main/Get-PathTree

スクリーンショット
スクリーンショット 2025-09-11 094806.png

使用方法

動作環境

  • Windows 10/11
  • PowerShell 5.1以降
  • WSL2(WSL機能使用時のみ)
  • .NET Framework(Windows標準搭載)

起動方法

# 管理者権限不要で実行
.\Get-PathTree.ps1

基本操作フロー

1. パスの入力

対象フォルダのパスを入力、または「参照」ボタンで選択します。

Windows環境の例:

C:\Users\Documents
D:\Projects\MyProject

WSL2環境の例:

# Linux形式
/home/user/projects

# Windows UNC形式
\\wsl.localhost\Ubuntu-22.04\home\user
\\wsl$\Ubuntu\home\user

2. 深度の設定

探索する階層の深さを設定します。

環境 推奨値 最大値 備考
Windows 3-5 10 深い階層も比較的高速
WSL2 2-3 10 深度4以上は処理が大幅に遅延

3. フォルダ構造の読み込み

「読み込み」ボタンをクリックして、フォルダ構造を取得します。

4. 出力項目の選択

ツリービューに表示されたフォルダ/ファイルから、出力したい項目にチェックを入れます。

ポイント:

  • 「全選択」「全解除」ボタンで一括操作可能
  • 折りたたまれたノードの子要素は出力されないため、必要な項目は展開してから選択

5. ツリーの生成

「ツリー生成」ボタンをクリックすると、以下のような形式で出力されます:

MyProject/                            //
├── docs/                             //
│   ├── manual.pdf                    //
│   └── readme.txt                    //
├── src/                              //
│   ├── main.js                       //
│   └── style.css                     //
└── README.md                         //

6. 編集とコピー

  • 生成されたツリーは編集エリアで直接修正可能
  • 「クリップボードにコピー」ボタンで結果をコピー

WSL2使用時の注意点

事前準備(重要)

PC起動後、初めてWSL2のパスを扱う場合は、事前にWSL2を起動する必要があります:

# PowerShellまたはコマンドプロンプトで実行
wsl

# または、エクスプローラーで以下にアクセス
\\wsl.localhost\

制限事項

  • ディストリビューションのルート不可\\wsl.localhost\Ubuntu-22.04 のようなルートパスは選択できません
  • 深度制限:WSL2環境では深度2-3を推奨(4以上は大幅に処理時間が増加)

トラブルシューティング

症状 原因 対処法
WSLパスでエラー発生 WSL2が未起動 wsl --list --runningで確認後、wslコマンドで起動
WSL2で応答なし・処理が遅い 深度が深すぎる 深度を2-3に下げて再実行
ツリーに一部項目が表示されない ノードが折りたたまれている ツリービューで該当項目を展開してから生成
コメント位置がずれる 全角文字を含むフォルダ名 生成後に編集エリアで手動調整

パフォーマンス最適化のコツ

WSL2環境での高速化

  1. 具体的なパスから開始/home/user/specific_project のように深い階層を指定
  2. ファイルを除外:「ファイルを含む」のチェックを外してディレクトリのみ取得
  3. 段階的な探索:まず深度2で全体確認、必要箇所のみ深度を上げる

大規模プロジェクトの場合

  • ウィンドウを最大化して作業エリアを確保
  • 不要なフォルダ(node_modules等)は事前にチェックを外す
  • 深度を適切に制限(Windows: 3-5、WSL2: 2-3)

表示互換性について

生成されたツリーの表示は環境により異なる場合があります:

正常表示される環境 調整が必要な環境
GitHub(README.md) 一部のWebエディタ
Notepad(メモ帳) VSCode Copilot Chat
テキストファイル プロジェクトへの直接入力
Markdownコードブロック 一部のリッチテキストエディタ

Get-PathTreeの技術的特徴

1. PowerShell WinFormsでのモダンGUI実装

PowerShellは通常CLIツールとして使われますが、.NET Frameworkの全機能にアクセスできるため、本格的なGUIアプリケーションも作成可能です。

# フォームの基本設定とレスポンシブ対応
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object System.Windows.Forms.Form
$form.ClientSize = '800,600'

# アンカリングでウィンドウサイズ変更に対応
$treeView.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor 
                   [System.Windows.Forms.AnchorStyles]::Bottom -bor 
                   [System.Windows.Forms.AnchorStyles]::Left

PowerShellを使うことでコンパイル不要でスクリプトファイル単体で動作します。C#でWinFormsアプリを作る場合と異なり、配布も実行も.ps1ファイル1つで完結します。イベントハンドラもPowerShellのスクリプトブロックで記述でき、GUIとロジックがシームレスに統合されています。
この規模ならC#を使わずともインタープリタで大丈夫でしょう。

2. クロスプラットフォームコマンド実行

WSL2環境へのアクセスは、PowerShellからWSLコマンド経由でbashを呼び出す二段階構造で実現しています。

# WSLパスの存在確認 - インジェクション対策でシングルクォート使用
$normalizedPath = $path -replace '\\', '/'
$checkCommand = "test -e '$normalizedPath' && echo 'exists'"
$exists = wsl bash -c $checkCommand 2>$null

# ディレクトリ構造の取得
$findCommand = "find '$normalizedPath' -maxdepth $Depth -printf '%y|%P\n' 2>/dev/null | sort"
$output = wsl bash -c $findCommand

重要なのは、PowerShellの変数展開を利用しつつ、bashコマンドインジェクションを防ぐためシングルクォートで囲んでいる点です。また、2>$nullでエラー出力を抑制し、WSL未起動時も適切にハンドリングしています。

3. TreeViewの再帰的チェック状態管理

親ノードのチェック時に全子要素を連動させ、逆に子ノードの変更時は親の状態を自動更新します。さらに、TreeViewで折りたたまれたノードは子要素を出力せず、フォルダ名のみを生成する仕様により、必要な階層だけを選択的に出力できる直感的な操作を実現しています。

4. 文字幅計算アルゴリズム

日本語などの全角文字(Unicode範囲 0x3000-0x9FFF)は幅2、半角文字は幅1として計算し、最大幅に合わせてスペースを動的に挿入。これによりコメント記号 // の位置を自動整列させています。

なぜPython版ではなくPowerShell版を採用したのか

最初の試み:Python版での実装と課題

当初はPySide6を使用してGUIツールを作成しました。Windows側のパスは問題なく処理できましたが、WSL2のパス処理で以下の問題に直面しました。

1. ディストリビューション検出の不安定性

# Python版:エンコーディングが環境依存で不安定
result = subprocess.run(
    ['wsl', '-l', '-v'], 
    capture_output=True, 
    text=True, 
    encoding='utf-16le'  # UTF-16LE、CP932など環境によって異なる
)

2. WSLファイルシステムへの非効率なアクセス

# Python版:各ファイルごとに9P protocolを経由
path = Path("\\\\wsl.localhost\\Ubuntu\\home\\user")
for item in path.iterdir():  # ファイルごとに境界を越える
    # → パフォーマンス低下とエラー発生

問題点:

  • Windows APIを通じてLinuxファイルシステムにアクセスするため、ファイルごとに9P protocolを経由
  • パーミッションやシンボリックリンクの情報が正確に取得できない
  • 大量のファイルがある場合、著しくパフォーマンスが低下

PowerShell版での解決策

PowerShellでは、WSL内でLinuxコマンドを直接実行し、結果のみをWindowsに返す設計を採用しました。

# PowerShell版:WSL内でfindコマンドを実行(境界を1回だけ越える)
$findCommand = "cd '$wslPath' && find . -maxdepth $MaxDepth -type d"
$directories = @(wsl bash -c $findCommand)

アーキテクチャレベルの違い

PowerShell版の動作フロー:
Windows → WSL → [Linux内でfind実行] → 文字列結果 → Windows
         ↑                        ↑
     境界を1回だけ            Linux内で完結

Python版の動作フロー:
Windows → WSL境界 → ファイル1 → Windows
        → WSL境界 → ファイル2 → Windows  
        → WSL境界 → ファイル3 → Windows
        (ファイル数だけ境界を越える)

本質的な違い:言語設計思想

観点 PowerShell Python
WSL統合 ネイティブサポート subprocess経由
コマンド実行 wsl command で直接実行 リスト形式での構築が必要
エラー処理 暗黙的 明示的な例外処理が必要
パイプライン 組み込み 手動実装
認知負荷 低(見た目通りに動く) 高(APIの理解が必要)

PowerShellのアプローチ:
「WSL内でLinuxコマンドを実行し、結果だけをWindowsに持ってくる」
→ リモートサーバーにSSHしてコマンド実行するイメージ

Pythonのアプローチ:
「WindowsからWSLファイルシステムをマウントして直接アクセス」
→ ネットワークドライブを1ファイルずつ読むイメージ

この根本的な違いにより、PowerShell版の方が高速で安定した動作を実現できました。

まとめ

類似のツールがないかClaudeのレポート機能で探してみましたが、以下の要件をすべて満たすツールが見つからなかったため自作しました:

  • WindowsとWSL2環境の両方へ対応
  • チェックで生成/不生成の切り替え
  • フォルダ名のみの機能(配下のファイル等を生成させない)
  • コメントのためのスペース付与
  • GUI

従来、ツリー生成はGitHubのREADMEへの記載程度しか必要ありませんでしたが、AIプログラミングが普及し始め、会話ベースでプログラム構造を説明するシーンが増えてきています。そのような場面で、このツールが役立つのではないでしょうか。

理想を言えば、ツリーの各行へのコメントをあらかじめ登録し、生成時にそれを含めたツリーを生成する機能があればより便利でしょう。しかし、機能がリッチすぎてコードの規模も大きくなるため、今回は実装を見送りました。

もし実装したい方がいらっしゃるなら、ベースとしてこのコードを使っていただいて構いません。

(作成日:2025/09/11)

ライセンス

MIT License

4
5
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
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?