【Windows】WinForms程序调用WinRT的API清空剪切板
首先这是.NET Framework 4.6项目才用的方法,高版本直接安装Microsoft.Windows.SDK.Contracts包来使用就行了。
此代码实现了手动调用API获取WinRT的剪切板对象,并通过虚函数指针调用ClearHistory方法清空剪切板历史记录(Win+V)。
1 using System; 2 using System.Runtime.CompilerServices; 3 using System.Runtime.InteropServices; 4 5 namespace Win10ClipboardApiTest 6 { 7 public static class Clipboard 8 { 9 private enum RO_INIT_TYPE 10 { 11 RO_INIT_SINGLETHREADED = 0, 12 RO_INIT_MULTITHREADED = 1, 13 } 14 15 [DllImport("api-ms-win-core-winrt-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)] 16 private static extern IntPtr RoInitialize(RO_INIT_TYPE initType); 17 18 [DllImport("api-ms-win-core-winrt-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)] 19 private static extern IntPtr RoUninitialize(); 20 21 [DllImport("api-ms-win-core-winrt-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)] 22 private static extern IntPtr RoGetActivationFactory(IntPtr activatableClassId, byte[] iid, out IntPtr factory); 23 24 [DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)] 25 private static extern IntPtr WindowsCreateString([MarshalAs(UnmanagedType.LPWStr)] string sourceString, int length, out IntPtr hstring); 26 27 [DllImport("api-ms-win-core-winrt-string-l1-1-0.dll", CallingConvention = CallingConvention.StdCall)] 28 private static extern IntPtr WindowsDeleteString(IntPtr hstring); 29 30 [MethodImpl(MethodImplOptions.AggressiveInlining)] 31 private static bool IsSucceeded(IntPtr result) => (long)result >= 0L; 32 33 // Class Windows.ApplicationModel.DataTransfer.Clipboard 34 private static readonly string RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard = "Windows.ApplicationModel.DataTransfer.Clipboard"; 35 36 // Interface is a part of the implementation of type Windows.ApplicationModel.DataTransfer.Clipboard 37 private static readonly byte[] IID_IClipboardStatics2 = Guid.Parse("D2AC1B6A-D29F-554B-B303-F0452345FE02").ToByteArray(); 38 39 // IClipboardStatics2::ClearHistory 40 [UnmanagedFunctionPointer(CallingConvention.StdCall)] 41 private delegate IntPtr IClipboardStatics2ClearHistoryDelegate(IntPtr instance, out byte result); 42 43 // A helper to read the virtual function pointer from virtual table of the instance. 44 private static T GetVirtualMethodPointer<T>(IntPtr instance, int index) 45 { 46 var table = Marshal.ReadIntPtr(instance); 47 var pointer = Marshal.ReadIntPtr(table, index * IntPtr.Size); 48 return Marshal.GetDelegateForFunctionPointer<T>(pointer); 49 } 50 51 public static void ClearHistory() 52 { 53 if (IsSucceeded(RoInitialize(RO_INIT_TYPE.RO_INIT_SINGLETHREADED))) 54 { 55 if (IsSucceeded(WindowsCreateString(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard, RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard.Length, out IntPtr classId))) 56 { 57 if (IsSucceeded(RoGetActivationFactory(classId, IID_IClipboardStatics2, out IntPtr instance))) 58 { 59 var method = GetVirtualMethodPointer<IClipboardStatics2ClearHistoryDelegate>(instance, 7); 60 method.Invoke(instance, out byte result); 61 Marshal.Release(instance); 62 } 63 64 WindowsDeleteString(classId); 65 } 66 67 RoUninitialize(); 68 } 69 } 70 } 71 }