PowerShellを使用して、現在のクリップボード履歴を取得したい。
Q&A
Closed
解決したいこと
Windows11のPowerShellを使用して、現在のクリップボード履歴の数(最大25)を取得する方法はありますか?
自分で試したこと
(参考)
https://devblogs.microsoft.com/oldnewthing/20230303-00/?p=107894
上記のブログを参考にしてみましたが、"$result = ~"の部分でうまくいきませんでした。
Q&A
Closed
Windows11のPowerShellを使用して、現在のクリップボード履歴の数(最大25)を取得する方法はありますか?
(参考)
https://devblogs.microsoft.com/oldnewthing/20230303-00/?p=107894
上記のブログを参考にしてみましたが、"$result = ~"の部分でうまくいきませんでした。
もうやり方は解決済みかもしれませんが、一番簡単にできる方法を一応載せておきます。
前提としてですが、Powershellで動かす場合は、クリップボードの履歴はwindows の実装に依存しているものを使うため、powershell 5.1系列でしか動作しません。
さらにクリップボードの履歴はwindows 10の後半のバージョンから実装されたもののため、.net frameworkにはdllとしてライブラリは提供されていません。
また、windowsシステムにも共有ライブラリ、csharpのライブラリとしてあらかじめインストールされているわけではなく、ms公式のnugetパッケージからソースコードをビルドしてdllを作成して、それをpowershell 5.1から読み込むという作りになります。
このms公式のnugetパッケージもcsharp7.3まで対応しているnetstandard2.0で提供されています(netstandard2.0しか対応していない)が、IEnumeratorはpowershell5.1で動作しないため、非同期処理はcsharp 7.2までの文法で実装することになります。
もし、これをpowershell core系でも使いたいなら、powershell 5.1で実行したスクリプトの戻り値をpowershell coreで取得するという構成になります。
よって、かなり制限がきつく、アーキテクトの仕様を理解する必要がある割には運用含めて難しくペイしないと考えられるので、よほど特別な理由がない限りpowershellでクリップボードの履歴を扱うことはお勧めしません。
もしどうしてもやってみたいなら下のように環境構築実装することになります。
これはwindows11 23H2で動作確認済みです。
プロジェクトの作成からリリースまでdotnet コマンドを使ったほうが楽なので、dotnet コマンドを使って、プロジェクト、ソリューションを作ります。
winget install Microsoft.DotNet.SDK
dotnet new sln -o clipboard_history
cd clipboard_history
dotnet new classlib --framework netstandard2.0 -o clipboard_history
# ソリューションをプロジェクトに追加
dotnet sln add clipboard_history/
# プロジェクトフォルダに移動して
dotnet add package Microsoft.Windows.SDK.Contracts --version 10.0.22621.2428
下記のようなソースコードを書いてください。
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Windows.ApplicationModel.DataTransfer;
namespace clipboard_history
{
public class Class1
{
public async static Task<List<string>> GetClipboardHistoryItem()
{
var result = await Clipboard.GetHistoryItemsAsync();
List<string> resultsItems = new List<string>(result.Items.Count);
foreach (var val in result.Items) {
resultsItems.Add(await val.Content.GetTextAsync());
}
return resultsItems;
}
}
}
# プロジェクトフォルダに移動して
dotnet build
powershell 5.1から下記のようにバイナリのロードを行ってから静的メソッドを呼び出すことにより取得します。
Add-Type -path .\bin\Debug\netstandard2.0\clipboard_history.dll
$val = [clipboard_history.Class1]::GetClipboardHistoryItem()
# 1行ずつ(クリップボードごと)処理
$val.Result | %{$_}
# 履歴の件数
$val.Result.Count
ここからさらに仕事でやる場合は、仕様としてクリップボードの履歴が有効になっているかをどう処理するか?もロジックとして追加する必要があります。
shellなので、エラーになっても動くため、仕様とするのもよいです。
エラー処理をする場合はgithubにあるPowershellのGetClipboardCommand classのエラー処理を参考に書くのがいいと思います。
@i-1902
Questioner
回答ありがとうございます。
ちょうどDLL部分を作って、PowrShellで実行する部分悩んでいました。
詳細な内容で大変参考になり無事やりたいことができました。
(実現した内容)
画像をクリップボード(スクリーンショット)に保存し、クリップボード内分の画像をExcelファイルに順番に貼り付けを行う。
C#でクリップボードの履歴の数を取得し実行。
PowerShellスクリプトでDLL,API(キー操作)の読込を記述し、SendKeyで貼り付け処理(Winキー+V)を履歴の数だけ実行。
対象pcにてクリップボード履歴をonにして
先ずは最新の取得を確認
上記のキーワードでchatGTPに聞いて下さい。
頑張っている方もいます。
@i-1902
Questioner
回答ありがとうございます。
PowerShellだけで完結しようとしていました。C#アプリを作成して併用することでやりたいことができるかもしれないのでいろいろ試してみます。