<PackageReference Include="System.Drawing.Common" Version="10.0.0-preview.6.25358.103" />

ClipboardCore<TOleServices>

static class ClipboardCore<TOleServices> where TOleServices : IOleServices
Contains platform-agnostic clipboard operations.
using System.Collections.Specialized; using System.Private.Windows.Core.Resources; using System.Runtime.CompilerServices; using System.Threading; using Windows.Win32; using Windows.Win32.Foundation; using Windows.Win32.System.Com; namespace System.Private.Windows.Ole { [NullableContext(1)] [Nullable(0)] internal static class ClipboardCore<[Nullable(0)] TOleServices> where TOleServices : IOleServices { private const int OleRetryCount = 10; private const int OleRetryDelay = 100; internal static HRESULT Clear(int retryTimes = 10, int retryDelay = 100) { ((IOleServices)).EnsureThreadState(); int num = retryTimes; HRESULT result; while (true) { HRESULT hRESULT = result = ((IOleServices)).OleSetClipboard(null); if (!hRESULT.Failed || --num < 0) break; Thread.Sleep(retryDelay); } return result; } internal static HRESULT Flush(int retryTimes = 10, int retryDelay = 100) { ((IOleServices)).EnsureThreadState(); int num = retryTimes; HRESULT result; while (true) { HRESULT hRESULT = result = ((IOleServices)).OleFlushClipboard(); if (!hRESULT.Failed || --num < 0) break; Thread.Sleep(retryDelay); } return result; } internal unsafe static HRESULT SetData(IComVisibleDataObject dataObject, bool copy, int retryTimes = 10, int retryDelay = 100) { ((IOleServices)).EnsureThreadState(); ArgumentOutOfRangeException.ThrowIfNegative<int>(retryTimes, "retryTimes"); ArgumentOutOfRangeException.ThrowIfNegative<int>(retryDelay, "retryDelay"); ComScope<IDataObject> scope = ComHelpers.GetComScope<IDataObject>((object)dataObject); try { int num = retryTimes; HRESULT hRESULT; HRESULT result; while (true) { IDataObject* dataObject2 = (IDataObject*)ref scope; hRESULT = (result = ((IOleServices)).OleSetClipboard(dataObject2)); if (!hRESULT.Failed) break; if (--num < 0) return result; Thread.Sleep(retryDelay); } if (copy) { num = retryTimes; while (true) { hRESULT = (result = ((IOleServices)).OleFlushClipboard()); if (!hRESULT.Failed) break; if (--num < 0) return result; Thread.Sleep(retryDelay); } } return result; } finally { scope.Dispose(); } } [NullableContext(0)] internal unsafe static HRESULT TryGetData(out ComScope<IDataObject> proxyDataObject, [Nullable(2)] out object originalObject, int retryTimes = 10, int retryDelay = 100) { ((IOleServices)).EnsureThreadState(); proxyDataObject = new ComScope<IDataObject>(null); originalObject = null; int num = retryTimes; HRESULT result; HRESULT hRESULT; while (true) { IDataObject** dataObject = (IDataObject**)ref proxyDataObject; result = (hRESULT = ((IOleServices)).OleGetClipboard(dataObject)); if (!result.Failed) break; if (--num < 0) return hRESULT; Thread.Sleep(retryDelay); } HRESULT hr; ComScope<IComCallableWrapper> comScope = proxyDataObject.TryQuery<IComCallableWrapper>(out hr); try { if (hr.Succeeded) ComHelpers.TryUnwrapComWrapperCCW<object>(comScope.AsUnknown, out originalObject); result = hRESULT; return result; } finally { comScope.Dispose(); } } internal static bool IsObjectOnClipboard(object object, int retryTimes = 10, int retryDelay = 100) { if (object != null) { ComScope<IDataObject> proxyDataObject; object originalObject; HRESULT hRESULT = TryGetData(out proxyDataObject, out originalObject, retryTimes, retryDelay); ComScope<IDataObject> comScope = proxyDataObject; try { return hRESULT.Succeeded && object == originalObject; } finally { comScope.Dispose(); } } return false; } internal unsafe static HRESULT GetDataObject<TDataObject, TIDataObject>([Nullable(2)] out TIDataObject dataObject, int retryTimes = 10, int retryDelay = 100) where TDataObject : class, IDataObjectInternal<TDataObject, TIDataObject>, TIDataObject where TIDataObject : class { dataObject = null; ComScope<IDataObject> proxyDataObject; object originalObject; HRESULT result = ClipboardCore<TOleServices>.TryGetData(out proxyDataObject, out originalObject, retryTimes, retryDelay); ComScope<IDataObject> comScope = proxyDataObject; try { if (!result.Failed) { TDataObject val = originalObject as TDataObject; if (val == null || !((IDataObjectInternal<TDataObject, TIDataObject>)val).TryUnwrapUserDataObject(out TIDataObject dataObject2)) { TIDataObject obj = (TIDataObject)((IDataObjectInternal<TDataObject, TIDataObject>)dataObject).Create(proxyDataObject.Value); *(TIDataObject*)(long)(IntPtr)(void*) = obj; return result; } dataObject = dataObject2; return result; } return result; } finally { comScope.Dispose(); } } internal static bool IsValidTypeForFormat(Type type, string format) { if (string.IsNullOrWhiteSpace(format)) return false; if (<IsValidTypeForFormat>g__IsValidPredefinedFormatTypeCombination|8_0(format, type)) return true; throw new NotSupportedException(string.Format(System.Private.Windows.Core.Resources.SR.ClipboardOrDragDrop_InvalidFormatTypeCombination, type.FullName, format)); } internal static void SetFileDropList(StringCollection filePaths) { IComVisibleDataObject dataObject = ((IOleServices)).CreateDataObject(); dataObject.SetFileDropList(filePaths); SetData(dataObject, true, 10, 100); } } }