3

我想創建一個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); 
    } 
} 

(我已經裁剪掉代碼中保存列表中的值的部分)

它的作用是捕獲和重放按鍵,但是af通常(並非總是)使Visual Studio崩潰,並且崩潰發生在本機代碼中,所以我沒有太多有關錯誤的數據。

我從來沒有寫過任何VS擴展之前,肯定我在做什麼,充其量是粗略...

(我也許應該釋放與AllocCoTaskMem()分配的內存 - 我已經嘗試過了,但它仍然崩潰和我認爲在這一點上它不會傷害不釋放它)。

希望有任何想法。

回答

2

得到從MSDN forums答案:

用於VARIANT正確大小是16個字節,而不是4:

Marshal.AllocCoTaskMem(16);