【问题标题】:Random crashes in Visual Studio extension with command filters带有命令筛选器的 Visual Studio 扩展中的随机崩溃
【发布时间】:2012-10-25 12:32:49
【问题描述】:

我正在尝试创建一个可以在文本编辑器中记录按键并重播的 Visual Studio 扩展。

我有一个IVsTextViewCreationListener,它调用AddCommandFilter() 向正在创建的任何新文本编辑器添加命令过滤器:

public class VsTextViewCreationListener : IVsTextViewCreationListener
{
    public void VsTextViewCreated(IVsTextView textViewAdapter)
    {
        var filter = new MyCommandFilter();

        IOleCommandTarget next;
        if (ErrorHandler.Succeeded(textViewAdapter.AddCommandFilter(filter, out next)))
            filter.Next = next;
    }
}

命令过滤器如下所示:

public class MyCommandFilter : IOleCommandTarget
{
    public IOleCommandTarget Next { get; set; }

    public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
    {
        if (nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
        {
            // Save values of pguidCmdGroup, nCmdID, nCmdexecopt and GetTypedChar(pvaIn)
            // ...
        }

        return Next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
    }

    public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
    {
        return Next.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
    }

    public void Playback()
    {
        // Resend the values
        var pvaIn = Marshal.AllocCoTaskMem(4);
        Marshal.GetNativeVariantForObject((ushort)savedChar, pvaIn);
        Next.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, IntPtr.Zero);
    }

    private static char GetTypedChar(IntPtr pvaIn)
    {
        return (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
    }
}

(我已经剪掉了将值保存在列表中的代码部分)

它的工作原理是它捕获并重放按键,但是在重放后经常(并非总是)崩溃 Visual Studio,并且崩溃发生在本机代码中,所以我没有太多关于错误的数据。

我以前从未写过任何 VS 扩展,而且我所做的肯定是粗略的......

(我可能应该释放使用AllocCoTaskMem() 分配的内存 - 我已经尝试过,但它仍然崩溃,我认为此时不释放它也无妨)。

希望有任何想法。

【问题讨论】:

    标签: c# .net visual-studio-2012 visual-studio-extensions vs-extensibility


    【解决方案1】:

    MSDN forums得到答案:

    VARIANT 的正确大小是 16 个字节,而不是 4 个:

    Marshal.AllocCoTaskMem(16);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-20
      • 1970-01-01
      相关资源
      最近更新 更多