使用C#调用winAPI SetClipboardData(CF_HDROP, ptr)的方法

本文介绍了一个使用C#实现将多个文件路径写入Windows剪贴板的方法,通过构造特定格式的数据并利用P/Invoke调用Windows API实现。

尝试了很多种方法 最后还是觉得这种靠谱一点 虽然也麻烦了点

但是可行 但是前提是文件路径没中文 欢迎大家来提意见 修改完善一下_(:з」∠)_

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

class Program
    {
        [DllImport("kernel32.dll")]
        static extern IntPtr GlobalLock(IntPtr hMem);
        [DllImport("kernel32.dll")]
        static extern IntPtr GlobalUnlock(IntPtr hMem);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool OpenClipboard(IntPtr hWndNewOwner);
        [DllImport("user32.dll")]
        static extern bool EmptyClipboard();
        [DllImport("user32.dll")]
        static extern IntPtr SetClipboardData(uint uFormat, IntPtr hData);
        [DllImport("user32.dll", SetLastError = true)]
        static extern bool CloseClipboard();
        
        [StructLayout(LayoutKind.Sequential)]
        struct DROPFILES
        {
            public uint pFiles;
            public int x;
            public int y;
            public int fNC;
            public int fWide;
        };
        
        public static byte[] StructureToByte<T>(T structure)
        {
            int size = Marshal.SizeOf(typeof(T));
            byte[] buffer = new byte[size];
            IntPtr bufferIntPtr = Marshal.AllocHGlobal(size);
            try
            {
                Marshal.StructureToPtr(structure, bufferIntPtr, true);
                Marshal.Copy(bufferIntPtr, buffer, 0, size);
            }
            finally
            {
                Marshal.FreeHGlobal(bufferIntPtr);
            }
            return buffer;
        }
        
        public static void SetClipboardData(List<string> pathList)
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < pathList.Count; i++)
            {
                builder.Append(pathList[i]);
                builder.Append('\0');
            }
            builder.Append('\0');
            string path = builder.ToString();
            OpenClipboard(IntPtr.Zero);
            int length = Marshal.SizeOf(typeof(DROPFILES));
            IntPtr bufferPtr = Marshal.AllocHGlobal(length + path.Length * sizeof(char) + 8);
            try
            {
                GlobalLock(bufferPtr);
                DROPFILES config = new DROPFILES();
                config.pFiles = (uint)length;
                config.fNC = 1;
                int seek = 0;
                byte[] configData = StructureToByte(config);
                for (int i = 0; i < configData.Length; i++)
                {
                    Marshal.WriteByte(bufferPtr, seek, configData[i]);
                    seek++;
                }
                for (int i = 0; i < path.Length; i++)
                {
                    Marshal.WriteInt16(bufferPtr, seek, path[i]);
                    seek++;
                }
                GlobalUnlock(bufferPtr);
                EmptyClipboard();
                SetClipboardData(15, bufferPtr);
            }
            catch (Exception e)
            {
                throw e;
            }
            finally
            {
                Marshal.FreeHGlobal(bufferPtr);
                CloseClipboard();
            }
        }

        static void Main(string[] args)
        {
            SetClipboardData(new List<string> { "D:\\666.txt", "D:\\333.txt" });
            Console.Read();
        }
    }


评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值