UWP App剪贴板访问:如何防止多次处理相同的项目

问题描述

从UWP应用访问Win10剪贴板时,该应用只能在焦点对准时检查剪贴板。 因此,该应用程序不知道睡觉时发生了什么。 聚焦后,它可以再次检查内容

现在是一个问题:如何确定DataPackageView中的Clipboard.GetContents()一个全新的软件包,而不是已经查看过的软件包? DataPackageView.Properties中似乎没有ID或任何其他可用于区分的ID。

我曾经希望DataPackageView.GetHashCode()是答案,但不得不发现DataPackageView似乎在每次进行GetContents()调用时都被重新实例化,所以没有运气。 / p>

有什么想法吗?

解决方法

UWP App剪贴板访问:如何防止多次处理同一项目

cross-validation包含用于获取Clipboard的{​​{1}}方法。您可以致电GetHistoryItemsAsync以获得ClipboardHistoryItemsResult。 ClipboardHistoryItem具有id属性以通知差异。

ClipboardHistoryItemsResult.Items

如果最后一个项目的ID未更改,则意味着没有新项目插入剪贴板。请注意,它不能用于验证DataPackageView的内容是否相同。

如果您想验证ClipboardHistoryItem,请获取最后两项并分别进行比较。

,

对,没有足够快的速度。遗憾的是,有关 ClipboardHistory 的建议是静音的,因为可以禁用(并且应该是IMHO)...

我正在使用位图内容,因此将剪贴板内容存储到文件中,然后对文件进行哈希处理失败,因为生成的文件可能会被标记为元标记,因此即使位图也会产生不同的哈希值完全相同。

某种程度上确保未看到位图本身的唯一方法是对像素数组进行哈希处理...仍然可能给您带来相同的哈希结果,但这是我愿意承担的风险。关于内存有一些抱怨,但是如果我想显示位图,我最好有内存来加载它。美国国家航空航天局(NASA),这对您不可用...

因此,我决定进行艰难的尝试,并对位图本身进行哈希处理。

public async Task<String> GetBitmapHashAsync(StorageFile sourceFile)
{
    string result = null;

    // load the bitmap file into a bitmap-decoder and run a Hash algo on the actual pixels
    try
    {
        using (IRandomAccessStream fileStream = await sourceFile.OpenAsync(Windows.Storage.FileAccessMode.Read))
        {
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
            PixelDataProvider pixelData = await decoder.GetPixelDataAsync();

            // Get the pixel data
            byte[] sourcePixels = pixelData.DetachPixelData();

            SHA512 sha512Hasher = SHA512.Create();

            // and feed it to the Hasher
            byte[] data = sha512Hasher.ComputeHash(sourcePixels);

            // And now enjoy the result as a HEX string
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }
            result = sBuilder.ToString();
        }
    }
    catch (Exception)
    {
        result = null;
    }
    return result;
}