在 Microsoft Windows 7 中我可以在哪里查看剪贴板当前保存的内容的大小(以字节为单位)?

在 Microsoft Windows 7 中我可以在哪里查看剪贴板当前保存的内容的大小(以字节为单位)?

在 Microsoft Windows 7 中我可以在哪里查看剪贴板当前保存的内容的大小(以字节为单位)?

答案1

您可以在 Python 中使用win32clipboard模块,并使用 Windows 剪贴板中的数据执行许多功能。
您必须从头开始创建它,但可以创建一个函数,将数据的副本读入 VM 并检查其大小。

答案2

在 .NET 框架中,剪贴板由Windows.Forms.剪贴板在 Windows.Forms 或Windows 剪贴板在 PresentationCore 中

由于 PowerShell 可以与任何.NET 组件,您可以使用它直接处理剪贴板内容,而无需任何第三方软件。将以下代码片段保存为 *.ps1 脚本,例如clipboardsize.ps1,然后运行。您可以尝试将其用于任何内容,例如资源管理器中的复制文件列表或 Word 对象。

function printClipboard($obj)
{
    if ($obj.Length -ne $null) {
        echo "length: $($obj.Length)"
    } elseif ($obj.Size -ne $null) {
        echo "size: $($obj.Size)"
    }
}

Add-Type -AssemblyName PresentationCore
$dataObject = [Windows.Clipboard]::GetDataObject()
# or
# Add-Type -AssemblyName System.Windows.Forms
# $dataObject = [Windows.Forms.Clipboard]::GetDataObject()

foreach ($format in $dataObject.GetFormats()) {
    try {
        $obj = $dataObject.GetData($format);
        Write-Host -NoNewLine `
            "Format '$format', type $($obj.GetType().ToString())"
        
        # If data is a list then print length of each element
        if ($obj -is [System.Array])
        {
            echo " [$($obj.Length)]"
            foreach ($o in $obj) {
                Write-Host -NoNewLine "    "
                printClipboard($o)
            }
        } else {
            Write-Host -NoNewLine ", "
            printClipboard($obj)
        }
    } catch {
        echo "Format '$format' - failed to obtain data"
    }
}

以下是从网站复制的一段文本的示例输出

PS C:\Users> .\clipboardsize.ps1
Format 'text/html', type System.IO.MemoryStream, length: 9040
Format 'HTML Format', type System.String, length: 4793
Format 'text/_moz_htmlcontext', type System.IO.MemoryStream, length: 766
Format 'text/_moz_htmlinfo', type System.IO.MemoryStream, length: 8
Format 'Text', type System.String, length: 642
Format 'UnicodeText', type System.String, length: 642
Format 'System.String', type System.String, length: 642
Format 'text/x-moz-url-priv', type System.IO.MemoryStream, length: 192

下面是我在 Firefox 中右键单击图像并选择“复制图像”时的示例输出

Format 'text/html', type System.IO.MemoryStream, length: 672
Format 'HTML Format', type System.String, length: 502
Format 'text/_moz_htmlinfo', type System.IO.MemoryStream, length: 8
Format 'text/_moz_htmlcontext', type System.IO.MemoryStream, length: 2
Format 'application/x-moz-file-promise-url', type System.IO.MemoryStream, length: 130
Format 'application/x-moz-file-promise-dest-filename', type System.IO.MemoryStream, length: 48
Format 'FileDrop', type System.String[] [1]
    length: 57
Format 'FileNameW', type System.String[] [1]
    length: 57
Format 'FileName', type System.String[] [1]
    length: 57
Format 'Preferred DropEffect', type System.IO.MemoryStream, length: 4
Format 'application/x-moz-nativeimage' - failed to obtain data
Format 'Format17', type System.IO.MemoryStream, length: 1350124
Format 'DeviceIndependentBitmap', type System.IO.MemoryStream, length: 1350040

如您所见,剪贴板不是简单的数据流,而是源程序放入的各种内容的集合。例如,如果您复制 Excel 中的一系列单元格,则许多格式都将放入剪贴板:文本(原始 Unicode、原始 ANSI、RTF、HTML、XML、CSV...)、图像(EMF、WMF、BMP...)、工作表(BIFF5、BIFF8、BIFF12...)...

.NET 中的字符串实际上是用 UTF-16 编码的,因此必须将其长度乘以 2 才能得到字符串的大小(不包括元数据大小)。流是基于字节的,因此长度是实际内容的字节大小

VBA 中的类似问题:如何在 MS Access VBA 中获取 MSForms.DataObject 内容的大小


现在你看到上面不一定是剪贴板里的内容,因此检查大小可能无法反映实际持有的内容。原因有很多:

  • 程序可以使用惰性渲染以避免在将来不会使用的内容上浪费内存和渲染时间。这通常用于 Excel 电子表格等大型对象。因此有时即使您在剪贴板中看到数据,它也不会消耗任何内存

  • 如果可能,Windows 将自动在数据格式之间进行转换。例如在图像格式或文本编码之间进行转换。源程序在放入剪贴板之前也可能在格式之间进行转换(如上所示),并且您正在运行的运行时也可能这样做(.NET 将原始文本转换为System.String,将图像转换为System.Drawing.Imaging.Metafile,,System.Drawing.Bitmap... System.Windows.Media.Imaging.BitmapSource

    如果您复制 Unicode 文本,Windows 会在您请求 ANSI 版本时将其转换为 ANSI 文本,反之亦然。复制位图时也会发生同样的事情。这意味着您永远不会知道文本是以 Unicode 还是 ANSI 格式放入剪贴板的,或者图像是 BMP、PNG 还是 EMF。请注意上面的“文本”和“Unicode 文本”格式。由于 .NET 字符串的性质,.NET 框架会将它们都转换为 Unicode,但如果您从 C++ 获取内容,您将看到 2 个大小不同的字符串。

相关内容