Случайные сбои в расширении Visual Studio с фильтрами команд


Я пытаюсь создать расширение 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() - я пробовал это, но он все еще был сбой, и я думал, что в этот момент он не может повредить, не выпуская его).

Был бы признателен за любые идеи.

1 3

1 ответ:

Получил ответ от форумов MSDN:

Правильный размер для варианта-16 байт, а не 4:

Marshal.AllocCoTaskMem(16);