Hi, I have been trying to get the clipboard work on UWP platform. I'm running on Windows desktop configuration with IL2CPP. 2019.3.13f1 editor. The problem is that neither the old user32.dll SetClipboardData() through windowsapp.lib or by using the new Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage) is working. The user32.dll SetClipboardData() seems not to be available in desktop mode. I tried the Windows.ApplicationModel.DataTransfer.Clipboard.SetContent(dataPackage) with the following code inside C# plugin dll: Code (CSharp): public static void UWPPngBytesToClipboard(byte[] png) { var dataPackage = new DataPackage(); using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream()) { using (DataWriter writer = new DataWriter(ms.GetOutputStreamAt(0))) { writer.WriteBytes(png); } dataPackage.SetBitmap(RandomAccessStreamReference.CreateFromStream(ms)); dataPackage.RequestedOperation = DataPackageOperation.Copy; } Clipboard.Clear(); Clipboard.SetContent(dataPackage); } Clipboard.Clear() or Clipboard.SetContent() just give System.Exception. Any ideas what to try next or is this more or less not supported?
Which thread are you accessing Windows.ApplicationModel.DataTransfer.Clipboard from? I believe you need to run that code on the UI thread (not the main Unity thread).
Running on UI thread fixed that exception. However, I haven't found a way to get image to paste anywhere.
Got it working by writing into a temporary file. No matter what I tried with the InMemoryRandomAccessStream and png bytes, it just won't work. Note, in the following file must be available as long as the data in on clipboard. Code (CSharp): UnityEngine.WSA.Application.InvokeOnUIThread( async () => { DataPackage dataPackage = new DataPackage(); StorageFolder temporaryFolder = ApplicationData.Current.TemporaryFolder; StorageFile tempFile = await temporaryFolder.CreateFileAsync("clipboard.png", CreationCollisionOption.ReplaceExisting); await FileIO.WriteBytesAsync(tempFile, data); dataPackage.SetBitmap(RandomAccessStreamReference.CreateFromFile(tempFile)); Clipboard.SetContent(dataPackage); }, false);
Finally, found some magic dust that works. Code (CSharp): public static void UWPPngToClipboard(byte[] data) { UnityEngine.WSA.Application.InvokeOnUIThread(async () => { MemoryStream ms = new MemoryStream(data); var imageDecoder = await BitmapDecoder.CreateAsync(ms.AsRandomAccessStream()); var inMemoryStream = new InMemoryRandomAccessStream(); var imageEncoder = await BitmapEncoder.CreateForTranscodingAsync(inMemoryStream, imageDecoder); await imageEncoder.FlushAsync(); DataPackage dataPackage = new DataPackage(); dataPackage.RequestedOperation = DataPackageOperation.Copy; dataPackage.SetBitmap(RandomAccessStreamReference.CreateFromStream(inMemoryStream)); Clipboard.SetContent(dataPackage); }, false); }