ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C# WPF 访问剪切板报错

2022-08-16 15:01:42  阅读:202  来源: 互联网

标签:C# image 应用程序 static void 剪切板 报错 WPF public


如果剪贴板操作失败(例如 HRESULT 0x800401D0 (CLIPBRD_E_CANT_OPEN) 错误),则会引发相应的 ExternalException (,这是一种 ExternalException) 。

由于 Win32 OpenClipboard API 全局运行,因此编写良好的应用程序应在完成剪贴板操作后立即调用相应的 CloseClipboard API。 否则,在同一会话中运行的其他应用程序将无法访问剪贴板函数。

在 WPF 中,通常以无提示方式忽略对剪贴板的访问。 However, applications can opt to receive an ExternalException upon failure by setting the ShouldThrowOnCopyOrCutFailure flag to true. 但是,选择接收异常还要求应用程序通过 a CommandBinding处理Cut和 Copy RoutedUICommands,然后将该绑定应用到应用程序中的所有 TextBoxBase 控件 (TextBoxRichTextBox) 。 应用程序应确保处理 CommandBinding 执行处理程序中复制和剪切操作产生的 ExternalException。

以上来自微软官方解释

代码:

[DllImport("user32.dll")]
private static extern IntPtr CloseClipboard();

注:调用此方法时,最好做个1秒的等待,因为调用之后真正的释放是有时间的,或者做一个Retry

 

    /// <summary>
    /// 
    /// </summary>
    public static class ClipboardHelper
    {
        [DllImport("user32.dll")]
        private static extern IntPtr CloseClipboard();

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr GetOpenClipboardWindow();

        [DllImport("user32.dll", SetLastError = true)]
        static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

        /// <summary>
        /// 获取进程信息
        /// </summary>
        /// <returns></returns>
        public static Process GetProcessLockingClipboard()
        {
            int processId;
            GetWindowThreadProcessId(GetOpenClipboardWindow(), out processId);
            return Process.GetProcessById(processId);
        }

        /// <summary>
        /// 清理剪切板,避免异常
        /// </summary>
        public static void ClearClipboard()
        {
            try
            {
                CloseClipboardMethod();
            }
            catch (Exception ex)
            {
                //记录日志

                try
                {
                    CloseClipboardMethod();
                }
                catch (Exception ex2)
                {
                    //忽略
                }
            }
        }

        public static void CloseClipboardMethod()
        {
            CloseClipboard();
            System.Windows.Clipboard.Clear();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static void SetImage(BitmapSource image)
        {
            try
            {
                SetImageMethod(image);
            }
            catch (Exception ex)
            {
                //记录日志
                try
                {
                    var process = GetProcessLockingClipboard();
                    if (process != null)
                    {
                       var msg =$"占用剪切板的进程:{process.Id}、{process.ProcessName}";
                       //记录占用剪切板的进程信息
                    }
                    SetImageMethod(image);
                }
                catch (Exception ex1)
                {
                    //忽略
                }
            }
        }

        /// <summary>
        /// 复制逻辑
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        private static void SetImageMethod(BitmapSource image)
        {
               ClearClipboard();
            //结束之后等待一下,等进程真正的结束再继续下一步
            Thread.Sleep(1000);
            //将图片放入到剪切板
            System.Windows.Clipboard.SetImage(image);
        }
    }                                  

 


 

标签:C#,image,应用程序,static,void,剪切板,报错,WPF,public
来源: https://www.cnblogs.com/JqkAman/p/16591540.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有