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

VSCode拡張機能からPowerShellでクリップボード画像を取得する

1
Posted at

背景

VSCodeの拡張機能API自体にはクリップボード画像を直接取得する手段がありません。TypeScriptマクロでクリップボード画像をMarkdown挿入する機能を実装する際、PowerShell経由でのアクセスが必要でした。

1. Node.jsのchild_processからPowerShellを呼ぶ

import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

child_process.execpromisifyしてasync/awaitで扱えるようにするのが、VSCode拡張機能から外部コマンドを呼ぶ際の定石です。

2. PowerShellのSystem.Windows.Forms.Clipboardで画像取得

const psScript = `
    Add-Type -AssemblyName System.Windows.Forms;
    Add-Type -AssemblyName System.Drawing;
    $img = [System.Windows.Forms.Clipboard]::GetImage();
    if ($img) {
        $img.Save('${outputPath.replace(/\\/g, '\\\\')}', [System.Drawing.Imaging.ImageFormat]::Jpeg);
        exit 0;
    } else {
        exit 1;
    }
`;

System.Windows.Forms.ClipboardSystem.Drawingの2アセンブリをAdd-Typeで読み込むことで、.NETのクリップボードAPIをPowerShell経由で呼び出せます。画像がクリップボードにない場合はexit 1で異常終了させ、TypeScript側でtry/catchによりエラーメッセージを表示します。

3. パスのバックスラッシュエスケープに注意

$img.Save('${outputPath.replace(/\\/g, '\\\\')}', ...)

Windowsパスの\はPowerShell文字列内でもエスケープが必要なため、replace(/\\/g, '\\\\')で二重化してから埋め込みます。これを忘れると、パスの区切りが正しく解釈されずファイル保存に失敗します。

4. VSCode API側の処理はシンプル

const currentDir = path.dirname(editor.document.uri.fsPath);
const imagesDir = path.join(currentDir, 'images');
if (!fs.existsSync(imagesDir)) {
    fs.mkdirSync(imagesDir, { recursive: true });
}

imagesDirの自動作成にはrecursive: trueを指定するだけで、親フォルダも含めて一括作成されます。画像取得さえPowerShellで解決してしまえば、あとは通常のVSCode拡張機能開発の範囲で完結します。

まとめ

VSCode拡張機能単体では手が届かないクリップボード画像アクセスも、child_process経由でPowerShellのSystem.Windows.Formsを叩けば解決できます。バックスラッシュのエスケープ忘れがハマりどころでした。ショートカットキー登録を含む完全なコードは元記事にまとめています。

クリップボード画像をMarkdown化するTypeScriptマクロ(ブログ)

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