使用命令过滤器在Visual Studio扩展中随机崩溃

时间:2012-10-25 12:32:49

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

我正在尝试创建一个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崩溃,并且在本机代码中发生崩溃,因此我没有太多关于错误的数据。 / p>

我之前从未写过任何VS扩展,当然我所做的事情至多是粗略的......

(我应该释放用AllocCoTaskMem()分配的内存 - 我已经尝试了但它仍然崩溃了,我认为在这一点上它不会伤害不释放它。)

会感激任何想法。

1 个答案:

答案 0 :(得分:2)

MSDN forums获得答案:

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

Marshal.AllocCoTaskMem(16);