Random crashes in Visual Studio extension with command filters
-
14-07-2021 - |
Domanda
I am trying to create a Visual Studio extension that can record key presses in a text editor and replay them.
I have a IVsTextViewCreationListener
that calls AddCommandFilter()
to add a command filter to any new text editor being created:
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;
}
}
The command filter looks like this:
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);
}
}
(I have clipped out the portion of the code that holds the values in a list)
It works in the sense that it captures and replays the key presses, however after replaying it often (not always) crashes Visual Studio, and the crash occurs in native code so I don't have much data about the error.
I have never written any VS extension before and surely what I am doing is sketchy at best...
(I should probably release the memory allocated with AllocCoTaskMem()
- I have tried it but it was still crashing and I thought at this point it can't harm not releasing it).
Would appreciate any ideas.
Soluzione
Got the answer from the MSDN forums:
The correct size for a VARIANT is 16 bytes, not 4:
Marshal.AllocCoTaskMem(16);