如何从dataPackageView.GetDataAsync()获取字符串

时间:2016-06-17 00:08:11

标签: c# uwp com-interop

我尝试使用DataPackageView.GetDataAsync从剪贴板中获取非标准格式的数据。我很难将返回的system.__ComObject转换为字符串。

以下是代码:

var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();

if (dataPackageView.Contains("FileName"))
{
  var data = await dataPackageView.GetDataAsync("FileName");
  // How to convert data to string?

}

我正在寻找适用于任何非标准剪贴板格式的解决方案。 "文件名"是一种易于测试的格式,因为您可以通过在Windows资源管理器中复制文件将其放在剪贴板上。

C++/Win32中,我可以按如下方式获取剪贴板数据:

OpenClipboard(nullptr);
UINT clipboarFormat = RegisterClipboardFormat(L"FileName");
HANDLE hData = GetClipboardData(clipboarFormat);
char * pszText = static_cast<char*>(GlobalLock(hData));
GlobalUnlock(hData);
CloseClipboard();

C++中,剪贴板数据只是一个字节数组。必须可以在C#中获得相同的字节数组,但我不知道解包/转换system.__ComObject

编辑:改述问题:

如何从系统中获取字符串或数组数组.__由DataPackageView.GetDataAsync(someFormat)返回的ComObject,其中someFormat是由另一个应用程序创建的任意剪贴板格式?

我很清楚如何获取数据。困难的部分是使用返回的数据。

接受的答案必须说明如何从&#34;数据&#34;创建一个字符串或字节数组。

返回
var data = await dataPackageView.GetDataAsync(someFormat);

2 个答案:

答案 0 :(得分:3)

如果你知道它的文件,你可以使用以下代码

var content = Clipboard.GetContent();

IReadOnlyList<IStorageItem> files = await content.GetStorageItemsAsync();
var file = files.First() as StorageFile;    

来自MSDN article on StandardDataFormats

  

DataPackage类支持许多旧版格式,用于Windows应用商店应用和桌面应用之间的互操作性。要检索这些格式,请将以下字符串之一传递给DataPackageView.GetDataAsync方法,而不是StandardDataFormats类中的值。

例如

var content = Clipboard.GetContent();
var data = await content.GetDataAsync("PenData"); //Stream for HGLOBAL corresponding to CF_PENDATA        

答案 1 :(得分:3)

本文介绍了如何实现自定义dataPackage对象。

http://www.minddriven.de/index.php/technology/dot-net/c-sharp/winrt-datapackage-custom-objects

关键是将dataPackageView.GetAsync()的返回值强制转换为 IRandomAccessStream

这是有用的:

var dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();

if (dataPackageView.Contains("FileName"))
{
  var data = await dataPackageView.GetDataAsync("FileName");
  // convert data to string
  var data = await dataPackageView.GetDataAsync("FileName");
  var dataObj = data as IRandomAccessStream;
  var stream = dataObj.GetInputStreamAt(0);
  IBuffer buff = new Windows.Storage.Streams.Buffer((uint)dataObj.Size);
  await stream.ReadAsync(buff, (uint)dataObj.Size, InputStreamOptions.None);
  var filePath = Encoding.ASCII.GetString(buff.ToArray());
  filePath = filePath.Replace("\0","");//get rid of null characters
}

这适用于任何自定义数据格式,而不仅仅是&#34; FileName&#34;。如果您不需要字符串,则可以使用IRandomAccessStream中可用的字节。