.NET 4.0 - AccessViolationException和WndProc

8

我有这段代码:

internal class MTool : NativeWindow
{
    private const int WM_LBUTTONDOWN = 0x0201;
    public event TipDeactivateEventHandler Deactivate;

    protected override void WndProc(ref System.Windows.Forms.Message m)
    {           
        if( m.Msg == WM_LBUTTONDOWN )
        {
            if( this.Deactivate != null)
            {
                this.Deactivate();
            }
        }

        base.WndProc(ref m);
    }
}

当我运行我的程序时,在base.WndProc(ref m);这行抛出了AccessViolationException错误,我不知道为什么。
显然,这个程序从.NET 2.0移植到4.0,我的理论是现在可能有一种替代的方法来覆盖WndProc。是这种情况吗?如果不是,为什么会抛出这个异常?

你能提供一个更完整的示例吗?至少展示一下你是如何创建MTool窗口并显示它的?我想确保我的复现接近于你的。 - Tim
那么你实际上并没有在任何特定的地方显示它,只是创建了对象?难道不需要调用CreateHandle或类似的方法才能让NativeWindow有用吗? - Tim
你尝试在base.WndProc上设置断点,看看当异常被触发时m的值是多少了吗?同时,它是否对某些m有效或者第一次调用时就抛出异常? - Amit Mittal
你是如何实际使用MTool的? - Amit Mittal
3个回答

7

我通过在方法上方添加此属性来解决了这个问题:

[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions]

将发生异常的代码块用try/catch包围起来。我在这里找到了相关信息(链接)


3
找出导致异常的原因并尝试修复,这样不是更好吗? - MikeKulls

2
< p>关于WndProc的文档显示需要完全信任。你尝试过这样做吗?例如:

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
internal class MTool : NativeWindow
{
    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    protected override void WndProc(ref Message m)
    {
//...

尝试过了,仍然得到相同的异常。 - Kyle V.

0

我怀疑你的代码中有更大的问题。基于你提供的片段,我建议尝试以下几点:

  1. 注释掉WndProc重写,这样是否仍会在其他地方崩溃?
  2. 让WndProc只调用“base.WndProc(ref msg)”。你是否仍然会收到相同的错误?调用堆栈是什么?堆栈深处是否还有你的代码?
  3. 使用当前片段时,这种情况只发生在WM_LBUTTONDOWN时吗?当抛出异常时,与Deactivate处理程序连接的内容是什么?

如果这些方法不可行,你可能需要更新片段以更好地解释你想要做什么。


2
我强烈建议不要使用HPCSEAttribute来解决这个问题。可能发生的情况是您的托管代码抛出了异常,或者存在一个封送异常(您如何构建ptrStruct?)。当您的代码在本地代码中穿梭时,它会失去原始异常的上下文,并最终表现为CLR认为无法捕获的异常。您标记为正确答案的属性可能是为什么以前可以工作的区别,但是存在一个更深层次的问题被隐藏了。您真的应该更多地调试这个问题。 - Joe Castro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接