3

テキスト エディターでキーの押下を記録して再生できる 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()-試してみましたが、まだクラッシュしていました。この時点では、解放しなくても害はないと思いました)。

アイデアをいただければ幸いです。

4

1 に答える 1

2

MSDNフォーラムから回答を得ました:

VARIANTの正しいサイズは4ではなく16バイトです。

Marshal.AllocCoTaskMem(16);
于 2012-10-26T01:58:30.597 に答える