Search code examples
powershellclipboard

Detect clipboard changes (Get-Clipboard -raw to variable for hashing?)


is there a way to get the clipboard data, whatever type contents it may contain, into a variable for hashing?

I've been able to do it for specific format type, e.g.

$data = Get-Clipboard -Format Image
$ms = New-Object System.IO.MemoryStream
$data.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png)
$mystream = [IO.MemoryStream]::new([byte[]][char[]]$ms.GetBuffer())
$hash = Get-FileHash -InputStream $mystream -Algorithm SHA1 | Select-Object -ExpandProperty Hash
write-host $hash

How can it be done with $data = Get-Clipboard -raw ?


Solution

  • If you just want to check if clipboard content has changed, you may query the clipboard sequence number.

    Here is a complete code sample to detect clipboard changes by comparing the current sequence number with the previous one in a loop.

    It also demonstrates how the increase in sequence numbers correlates with the number of formats currently stored in the clipboard.

    # Define the p/invoke signatures for using the WinAPI clipboard functions.
    Add-Type -NameSpace WinApi -Name ClipboardSeq -MemberDefinition '[DllImport("user32.dll")] public static extern uint GetClipboardSequenceNumber();'
    Add-Type -NameSpace WinApi -Name CountClipboardFmt -MemberDefinition '[DllImport("user32.dll")] public static extern int CountClipboardFormats();'
    
    # Get the current clipboard sequence number
    $lastSequenceNumber = [WinApi.ClipboardSeq]::GetClipboardSequenceNumber()
    
    # Loop to poll for clipboard changes
    while($true) {
       $newSequenceNumber = [WinApi.ClipboardSeq]::GetClipboardSequenceNumber()
       if( $lastSequenceNumber -ne $newSequenceNumber ) {
           $lastSequenceNumber = $newSequenceNumber
           "Clipboard has changed. New sequence number is: $newSequenceNumber"
    
           $numFormats = [WinApi.CountClipboardFmt]::CountClipboardFormats()
           "Number of formats in clipboard: $numFormats"
       }
       # Delay for one second to avoid CPU congestion.
       Start-Sleep 1
    }
    

    A typical output may look like this:

    Clipboard has changed. New sequence number is: 451
    Number of formats in clipboard: 4
    Clipboard has changed. New sequence number is: 456
    Number of formats in clipboard: 4
    Clipboard has changed. New sequence number is: 460
    Number of formats in clipboard: 3
    

    On the Win 10 system where I got this output the sequence number increment seems to be number of clipboard formats plus one. On another Win 10 system there was still a correlation, but a bigger difference (like 7 clipboard formats and an increase in sequence number of 13). I can't really explain these differences and there doesn't seem to exist a documentation. All that you can rely on is that the sequence number will increase if new data is put into the clipboard.