Winform应用程序随机崩溃

时间:2013-12-20 09:42:59

标签: c# winforms

我开发了一个捕获所有剪贴板文本的应用程序:

protected override void WndProc(ref Message m)
{
    try
    {
        switch (m.Msg)
        {
            case WM_DRAWCLIPBOARD:
            {
                if (Clipboard.GetText() != string.Empty)
                    //I analyze the data then 
                    if (ClipboardObject.CheckNewData(Clipboard.GetText()))
                        ClipboardObject.UpdateClipboardData(Clipboard.GetText());

                SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
                break;
            }
            case WM_CHANGECBCHAIN:
                if (m.WParam == nextClipboardViewer)
                    nextClipboardViewer = m.LParam;
                else
                    SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
                break;

            default:
                base.WndProc(ref m);
                break;
        }
    }
    catch (Exception ex)
    {
    }
}

当事件上升时,我将数据填入一个共享给我整个应用程序的对象中,然后在每半秒钟的计时器中填充,我会继续检查此对象中是否有新数据。

在我安装此应用程序的每台电脑上,即使我的应用程序没有运行,奇怪的事情也会开始发生在Windows上:

  • Windows随机崩溃
  • 在某些电脑的窗户上发生了迷你冻结(每次都发生在我身上)
  • 只要我在任何文件夹或文件上单击鼠标右键,某些时候窗口就会崩溃

我长期以来一直在努力解决这些问题,我真的无法找到解决问题的方法,感谢任何帮助。

1 个答案:

答案 0 :(得分:3)

“接收WM_DRAWCLIPBOARD消息的每个窗口都必须调用SendMessage函数将消息传递到剪贴板查看器链中的下一个窗口。” 你确定总是吗?你应该尝试一下... finally块(事实上,如果数据不是文本的话,GetText可能会抛出)。

WM_CHANGECBCHAIN也可能非常棘手 - 您是否在申请退出后自行清理?你必须使用ChangeClipboardChain再次移除自己,否则你会在剪贴板链中留下一个悬空指针!

基本上,当你的表单正在关闭时(它的句柄被处理掉了 - 但在真正处理之前),你需要调用这样的东西:

ChangeClipboardChain(this.Handle, nextClipboardViewer);

剪贴板更改非常脆弱 - 崩溃的应用程序可能会让您丢失剪贴板。在.NET中,至少尝试使用终结器来处理它(即便如此,它会变得棘手) - 事实上,将剪贴板绑定到其他东西而不是实际窗口可能并不是一个坏主意(所以你可以正确实现dispose-finalize模式),但这取决于你。另外,请看这个问题: Can aborting a process without resetting the clipboard chain cause trouble?

请注意,即便如此,有人也可以直接处理您的应用程序(这是任务管理器警告您不要终止进程的原因之一 - 在这种情况下,它确实使您的应用程序不稳定)。三重检查所有内容以确保在每种可能的情况下都处理CB链(除了不可避免的进程终止之外 - 有一些方法可以在某种程度上解决这个问题,但是嘿,如果用户在屁股中,请让他) ,否则你会让你的电脑非常不稳定。