2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

複数ファイルを生成AIのチャットで貼り付ける作業を補助するツール

Last updated at Posted at 2025-10-31

長ったらしい記事名になってしまいましたが、こういう風に言うしかないツールです。
毎度ですが、需要無視です。

(11/3)いまだ不具合が治ってないので、だんだん総合的便利ツールになりつつあります。

新機能追加(2025/11/03)

クリップボード内容へのフェンス追加機能

メインウィンドウに「クリップボードにフェンス追加」ボタンを追加しました。

この機能により、以下の2種類のクリップボード内容をMarkdownコードフェンス(```)で囲めるようになりました:

  1. テキスト: どこかからコピーした短いコードスニペットやテキスト
  2. ファイル: エクスプローラーでコピーしたテキストファイル(既存機能の拡張)

使い方

  • テキストまたはファイルをコピー(Ctrl+C)
  • メインウィンドウの「クリップボードにフェンス追加」ボタンをクリック
  • フェンスで囲まれた状態でクリップボードに再登録される
  • Claudeなどのチャットツールに直接ペースト可能

設定ウィンドウを開く必要がなく、クリップボードにある内容を直接処理できるため、短いコードを素早くフェンス付きにしたい場合に便利です。


:warning: 重要な更新(2025/11/02)

バグ修正のお知らせ

公開直後にバグが発見され、修正しました。既にダウンロードされた方は、お手数ですが最新版への更新をお願いします。

修正内容:ファイル削除・移動時の配列処理エラー

複数ファイルが登録されているグループで、以下の操作を行うとパスが連結されてしまうバグがありました:

  1. 「選択ファイルを削除」で1つずつファイルを削除
  2. 最後の1ファイルになるまで削除
  3. 新しいファイルを追加
  4. 2つ目以降のファイルパスが1つ目のパスに連結される

例:

正常:C:\test\file1.txt, C:\test\file2.txt
異常:C:\test\file1.txtC:\test\file2.txt

原因:PowerShellの配列の既知の挙動問題

PowerShellでは、Where-Objectで要素をフィルタリングした結果が1つだけになった場合、配列ではなく文字列(スカラー値)に自動変換されてしまいます。その状態で+=演算子を使うと、配列への追加ではなく文字列結合として動作します。

# 問題の流れ
$files = @("C:\file1.txt", "C:\file2.txt")
$files = $files | Where-Object { $_ -ne "C:\file1.txt" }  # まだ配列
$files = $files | Where-Object { $_ -ne "C:\file2.txt" }  # 文字列に変換される!
$files += "C:\file3.txt"  # 文字列結合になってしまう
# 結果: "C:\file2.txtC:\file3.txt"

修正方法:@()配列サブ式演算子の使用

# 修正前
$script:config.groups[$groupIndex].files =
    $script:config.groups[$groupIndex].files | Where-Object { $_ -ne $selectedFilePath }

# 修正後
$script:config.groups[$groupIndex].files = @(
    $script:config.groups[$groupIndex].files | Where-Object { $_ -ne $selectedFilePath }
)

@()で囲むことで、結果が1要素でも0要素でも必ず配列型として維持されます。

修正箇所:

  • 選択ファイル削除処理(521-523行目)
  • ファイル移動処理(309-311行目)

GitHubの最新版では修正済みです。


ツール作成背景

あらためて、Claudeのような生成AIのチャットでコードをアップロードする際のサポートツールです。
Claude CodeのようなAIコーディングエージェントの性能も上がってきてますから、チャットでコードのやりとりをする機会は少なくなっていると思います。ですがチャットスレッドでも、画像のアップロードでAIと検証したり、結合前のモジュール開発したり、トークンの節約、などなどでまだ使う機会も多いと思います。
その際に、既存のコードファイルを複数個、スレッドにコピペするときもあるでしょう。その作業を補助するツールです。

※補足

2025/10/31時点でのClaudeの障害に対応

チャットにコードなどのテキストコンテンツのファイルをドラッグアンドドロップで登録すると『ファイルのプレビューを読み込めませんでした』となりアップロードされない問題

テキストデータをファイルでアップロードするとClaude側で認識されない障害が出てるようです。15KBぐらいまでは大丈夫なようですが、それを超えると、コピペやドラッグアンドドロップ、ファイル選択いずれもClaudeが認識しません。
ですが、markdownのフェンス(```)で囲って入力すると認識されます。
その状況へ対応するために個人的に作って使用していた「実態ファイルのクリップボード登録ツール」を拡張しました。
個人的に推測すると、新たに追加された『メモリー機能』の実装時にバグフィックスから漏れてるのでしょう。
その前では平気でしたので。

File Clipboard Managerの特徴

・複数のファイルをグループ管理してクリップボードに一括登録
・ファイル内容をmarkdownのコードフェンスで囲んでテキスト化
・BOM付きUTF-8への変換機能(Claudeでの文字化け対策)
・WindowsパスとWSL2パスの両方に対応
・Claude AIのファイルアップロード制限に対応(1チャット最大20ファイル、合計最大30MB)

ソースコード

GitHub
https://github.com/ya-ma-n-1972/powershell_tool_report/tree/main/File-Clipboard-Manager

スクリーンショット
スクリーンショット 2025-10-31 164441.png

使用方法

動作環境

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

起動方法

管理者権限不要で実行

.\File-Clipboard-Manager.ps1

基本操作フロー

1. ファイルの登録

メインウィンドウから対象グループの「設定」ボタンをクリックすると、設定ウィンドウが開きます。

登録方法は2つあります:

ファイル選択ダイアログから追加
「ファイル追加」ボタンをクリックして、ファイル選択ダイアログから対象ファイルを選択します。

ドラッグ&ドロップで追加
エクスプローラーからファイルをリストボックスに直接ドラッグ&ドロップできます。複数ファイルの同時追加も可能です。

登録後は「OK」ボタンで保存してください。保存すると、次回起動時も同じファイルリストが自動で読み込まれます。

2. グループの活用

4つのグループを使い分けることで、用途別にファイルを管理できます。


(例)

グループ 推奨用途 説明
グループ1 メインコード プロジェクトの主要なソースファイル
グループ2 テストコード ユニットテストや統合テスト
グループ3 設定ファイル 設定ファイルや環境変数定義
グループ4 ドキュメント README、仕様書など

グループ名はカスタマイズ可能です。設定ウィンドウの上部テキストボックスで変更できます。

Claude AIのファイルアップロード制限への対応

各グループは最大20ファイルまで登録可能です。これはClaude AIの制限(1チャットあたり最大20ファイル)に合わせた設計です。また、各グループにはファイルサイズの合計が表示されます。Claude AIの合計サイズ制限(最大30MB)を超えないよう、この表示を参考にしてください。

3. クリップボードへの登録

このツールの核となる機能です。2つの登録方式があります。

方式1:ファイルパスとして登録
メインウィンドウの「クリップボードへ」ボタンをクリックすると、選択したグループ内の全ファイルがFileDropList形式でクリップボードに登録されます。

エクスプローラーやVS Codeなどに直接Ctrl+Vで貼り付けられます。
Claudeのチャット欄にもCtrl+Vでファイルとして貼り付け可能です。

方式2:フェンス付きテキストとして登録
ファイルの内容をmarkdownのコードフェンス(```)で囲んでテキスト化します。

グループ全体をテキスト化
メインウィンドウの「フェンス付きでクリップボード」ボタンで、グループ内の全ファイルを一度にテキスト化します。

個別ファイルをテキスト化
設定ウィンドウでファイルを選択して「フェンス追加」ボタンをクリックすると、選択したファイルだけがテキスト化されます。

出力形式の例:

# main.py
def hello_world():
    print("Hello, World!")
// app.js
console.log("Hello, World!");

拡張子から言語を自動判定してシンタックスハイライト用の言語指定を付けます。
対応言語はpython、javascript、typescript、csharp、java、go、rust、php、ruby、swift、kotlin、powershell、bash、markdown、json、yaml、xml、html、css、sql、その他多数です。

4. その他の便利機能

BOM付きUTF-8への変換
設定ウィンドウの「BOM変換」ボタンで、選択したファイルをBOM付きUTF-8に変換できます。これは以前の記事で触れた、Claudeでのファイルアップロード時の文字化け対策です。

記事:Claudeでファイルアップロードすると日本語が文字化けする問題と回避策
https://qiita.com/ya-man-kys/items/0f3a27edf39c41a5e9b7

注意:元ファイルが直接上書きされます。バックアップは作成されませんので、重要なファイルは事前にバックアップしてください。

ファイルの削除
設定ウィンドウで選択したファイルを削除できます。「選択ファイルを削除」で個別削除、「全て削除」でグループ内の全ファイルを削除します。

グループ間の移動
設定ウィンドウの「別グループへ移動」ボタンで、ファイルを別のグループに移動できます。例えば、開発中のファイルをグループ1からグループ2のテストファイル用に移動するといった使い方ができます。

WSL2パス使用時の注意点

事前準備(重要)

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

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

wsl

または、エクスプローラーで以下にアクセス

\\wsl.localhost\

対応パス形式

以下の形式のパスに対応しています:

\\wsl.localhost\Ubuntu-22.04\home\user\project\main.py
\\wsl$\Ubuntu\home\user\project\utils.py

制限事項

ディストリビューションのルート(例:\\wsl.localhost\Ubuntu-22.04)は指定できません。必ず具体的なファイルパスを指定してください。
エクスプローラー経由で指定すればほぼ問題ないです。

トラブルシューティング

症状 原因 対処法
スクリプトが起動しない 実行ポリシー制限 Get-ExecutionPolicy で確認後、Set-ExecutionPolicy RemoteSigned -Scope CurrentUser で許可
WSLパスでエラー発生 WSL2が未起動 wsl コマンドで起動、または wsl --list --running で状態確認
ファイルが見つからない パスが無効 ネットワークドライブやUSBドライブの接続を確認
クリップボードに登録されない 他のアプリが使用中 他のアプリを閉じるか、Windowsを再起動
文字化けが発生 エンコーディング問題 BOM変換機能を使用、または元ファイルをUTF-8で保存し直す

効果的な使い方のコツ

プロジェクト別にグループを使い分ける
複数のプロジェクトを同時進行している場合、グループごとにプロジェクトを分けると便利です。切り替えも素早くできます。

定型ファイルセットを登録しておく
よく使うファイルの組み合わせ(例:メイン処理+ユーティリティ+設定ファイル)をグループに登録しておけば、毎回選択する手間が省けます。

フェンス付きテキスト方式の活用
今の障害(上記を参照)が続行中では、ファイルサイズが15KBを超える場合はコピペしてもClaudeのチャットに読み込ませられませんので、その場合この機能を使ってください。複数ファイルの内容でも、まとめてテキストデータにしてチャットにペースト出来ます。
AIに見せたい場合は、フェンス付きテキスト方式が便利です。ただし、合計サイズが30MBを超えないように注意してください。

グループ名でタスクを管理
グループ名を「レビュー待ち」「修正中」「完了」のようなステータスにすることで、簡易的なタスク管理としても使えます。

File Clipboard Managerの技術的特徴

1. 2種類のクリップボード操作の実装

本ツールの特徴は、用途に応じて2つの異なるクリップボード登録方式を実装している点です。

ファイルパス方式(エクスプローラー貼り付け用)

function Set-ClipboardFiles($groupIndex) {
    $fileCollection = New-Object System.Collections.Specialized.StringCollection
    foreach ($filePath in $group.files) {
        if (Test-Path $filePath) {
            [void]$fileCollection.Add($filePath)
        }
    }
    [System.Windows.Forms.Clipboard]::SetFileDropList($fileCollection)
}

SetFileDropList()メソッドを使用することで、エクスプローラーでCtrl+Cでファイルをコピーしたときと同じ形式でクリップボードに登録されます。これにより、エクスプローラーや他のアプリケーションに直接ファイルを貼り付けることが可能になります。

フェンス付きテキスト方式(AI対話用)

function Set-ClipboardGroupTextWithFence($groupIndex) {
    $allText = ""
    foreach ($filePath in $group.files) {
        $content = Get-Content $filePath -Raw -Encoding UTF8
        $fileName = [System.IO.Path]::GetFileName($filePath)
        $fence = '```'
        $allText += $fileName + "`n" + $fence + "`n" + $content + "`n" + $fence + "`n`n"
    }
    [System.Windows.Forms.Clipboard]::SetText($allText)
}

Claude AIなどのチャットボットとの対話では、Markdownのコードフェンスで囲まれたテキストが最も読みやすい形式です。このメソッドは複数ファイルを一度に連結し、各ファイル名を明示して貼り付けることができます。

2. スクリプトスコープ変数による状態管理

PowerShellにおけるスコープ管理は重要な課題です。本ツールでは$script:プレフィックスを活用して、適切なスコープ管理を実現しています。

# グローバル変数の定義
$script:config = $null
$script:configPath = Join-Path $PSScriptRoot "config.json"
$script:messageLabel = $null

# 関数内からの参照
function Show-Message($message) {
    if ($script:messageLabel) {
        $script:messageLabel.Text = $message
        $script:messageLabel.Refresh()
    }
}

$script:スコープを使用することで、関数間で共有すべきデータと、関数内でのみ使用するローカル変数を明確に分離しています。これにより、複雑なGUIアプリケーションでも変数の競合を防ぎ、保守性の高いコードを実現しています。

3. BOM付きUTF-8変換の実装

一部のアプリケーションではBOM(Byte Order Mark)付きUTF-8が必要な場合があります。PowerShellの標準機能では対応が困難なため、.NETクラスを直接利用しています。

function Convert-ToBomUtf8($groupIndex) {
    $textExtensions = @('.txt', '.ps1', '.psm1', '.md', '.json', '.xml', 
                        '.csv', '.log', '.ini', '.cfg', '.conf')
    
    foreach ($filePath in $group.files) {
        $ext = [System.IO.Path]::GetExtension($filePath).ToLower()
        if ($textExtensions -notcontains $ext) {
            continue
        }
        
        # BOM付きUTF-8エンコーディングオブジェクトを作成
        $content = Get-Content $filePath -Raw -Encoding UTF8
        $utf8WithBom = New-Object System.Text.UTF8Encoding $true
        [System.IO.File]::WriteAllText($filePath, $content, $utf8WithBom)
    }
}

System.Text.UTF8Encodingクラスのコンストラクタに$trueを渡すことで、BOM付きのエンコーディングオブジェクトを生成します。これは、Get-Content/Set-ContentのEncodingパラメータでは実現できない機能であり、.NETクラスの直接利用の利点を示しています。

4. WSLファイルパスの透過的な処理

WSL環境のファイルも通常のWindowsファイルと同様に扱えるよう、特別な処理は実装していません。これはWindows 10 バージョン1903以降で導入された9P protocol serverによるものです。

# WSLパスも通常のWindowsパスと同様に処理可能
$wslPath = "\\wsl.localhost\Ubuntu-22.04\home\user\project\main.py"
if (Test-Path $wslPath) {
    $content = Get-Content $wslPath -Raw -Encoding UTF8
    # 通常のファイルと同様に処理
}

PowerShellの標準コマンドレットがWSLパスを自動的に解釈するため、追加の実装なしにクロスプラットフォーム対応が実現できています。ただし、パフォーマンスを考慮し、大量のWSLファイルを扱う場合は注意が必要です。

5. Tagプロパティによる動的イベント処理

本ツールには4つのグループがあり、各グループに「設定」「クリップボードへ」「フェンス付きでクリップボード」の3種類のボタンが配置されています。つまり、合計12個のボタンが存在します。通常の実装では、各ボタンごとに個別のイベントハンドラを作成する必要があり、コードが冗長になってしまいます。

# メインウィンドウでの実装例
for ($i = 0; $i -lt 4; $i++) {
    # 各グループのボタンを作成
    $btnConfig = New-Object System.Windows.Forms.Button
    $btnConfig.Text = "設定"
    $btnConfig.Tag = $i  # このボタンがどのグループに属するかを記憶
    
    $btnConfig.Add_Click({
        # $thisはクリックされたボタン自身を指す
        $idx = $this.Tag  # Tagからグループ番号を取得
        Show-ConfigWindow $idx $form  # 該当グループの設定画面を開く
    })
    
    # 同様に「クリップボードへ」ボタンも作成
    $btnClipboard = New-Object System.Windows.Forms.Button
    $btnClipboard.Tag = $i
    $btnClipboard.Add_Click({
        Set-ClipboardFiles $this.Tag  # 該当グループのファイルをクリップボードへ
    })
}

この実装により、以下のメリットが得られます:

コードの重複削除
12個のボタンそれぞれに個別の処理を書く代わりに、ループ内で動的に生成できます。ボタンがクリックされた際、$this.Tagを参照することで「どのグループのボタンがクリックされたか」を特定できます。

保守性の向上
例えば、グループ数を4から6に増やしたい場合、ループの条件を変更するだけで対応できます。個別のイベントハンドラを書いていた場合、6個の新しいハンドラを追加する必要があります。

メモリ効率
PowerShellのスクリプトブロックは、実行時に**$this**コンテキストを動的に解決します。これにより、各ボタンが自身のTagプロパティを参照して適切な処理を行うことができ、グループごとに異なるスクリプトブロックを保持する必要がありません。

実装上の工夫点

非同期処理の回避
PowerShellのGUIアプリケーションでは、非同期処理の実装が複雑になりがちです。本ツールでは、ファイル操作を高速に保つことで同期処理でも快適な操作性を実現しています。

エラーハンドリングの統一
全ての主要な処理にtry-catchブロックを配置し、エラー時はShow-Message関数で統一的にユーザーへフィードバックします。これにより、予期しないエラーでアプリケーションがクラッシュすることを防いでいます。

メモリ効率の考慮
大量のファイルを扱う場合を考慮し、ファイルの内容は必要時のみ読み込む設計としています。通常の操作では、ファイルパスのみをメモリに保持することで、メモリ使用量を最小限に抑えています。

まとめ

情けない話ですが、私はAIの補助無しではコーディングができません。
正確にい言えばめちゃくちゃ時間を掛ければできますが、現実的ではないです。

松葉杖ついている障害者が、かたくなに車椅子や自動車に乗ろうとしない事と同じ事になります。

Claude Codeのようなコーディングエージェントを使いながらでもAIのチャットはまだまだ活用します。
そうした私の現状を少しでもサポートさせるツールとして開発しました。
もし活用して頂けるなら幸いです。

(作成日:2025/10/31)

ライセンス

MIT License

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?