我正在尝试创建一个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()
分配的内存 - 我已经尝试了但它仍然崩溃了,我认为在这一点上它不会伤害不释放它。)
会感激任何想法。