在我的Visual Studio扩展程序中,我将阅读导航栏中的文本。因此我会监听窗口创建的事件,并从IVsCodeWindow对象中获取IVsDropdownBar以获取下拉栏中的当前选择。这很好用。然后,我使用以下代码段来提取当前选择的文本:
string text;
barClient.GetEntryText(MembersDropdown, curSelection, out text);
if (hr == VSConstants.S_OK)
{
Debug.WriteLine("Text: " + text);
} else {
Debug.WriteLine("No text found!");
}
然而,这不起作用。我的扩展程序在代码段的第二行中以未处理的异常崩溃。我阅读了文档,可以找到以下注释:
ppszText中返回的文本缓冲区通常由 IVsDropdownBarClient对象和缓冲区必须持续生命 IVsDropdownBarClient对象。如果你正在实施这个 托管代码中的接口,您需要处理该字符串 通过调用者,实现IVsCoTaskMemFreeMyStrings接口 IVsDropdownBarClient接口。
我认为这是我的问题的一部分,但我无法理解我的代码中需要更改的内容才能使其正常工作。任何提示?
答案 0 :(得分:0)
我现在很确定Visual Studio SDK Interop DLL有IVsDropDownbarClient.GetEntryText
的错误编组信息,并且无法使用该接口调用该方法。
到目前为止,我找到的最佳解决方法是:
使用tlbimp
工具为textmgr生成备用Interop DLL。 (您可以放心地忽略几十个警告,包括关于GetTextEntry的警告。)
tlbimp" c:\ Program Files(x86)\ Microsoft Visual Studio 11.0 \ VSSDK \ VisualStudioIntegration \ Common \ Inc \ textmgr.tlb"
(可选)如果您正在使用源代码管理,那么您可能希望将生成的文件(TextManagerInternal.dll)复制到扩展项目的子目录中,并将其作为外部项目进行检查依赖性。
在Visual Studio扩展项目中,添加对文件的引用(TextManagerInternal.dll)。
添加以下应正确处理字符串编组的方法。
static public string HackHackGetEntryText(IVsDropdownBarClient client, int iCombo, int iIndex)
{
TextManagerInternal.IVsDropdownBarClient hackHackClient = (TextManagerInternal.IVsDropdownBarClient) client;
string szText = null;
IntPtr ppszText = IntPtr.Zero;
try
{
ppszText = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr)));
if(ppszText == IntPtr.Zero)
throw new Exception("Unable to allocate memory for IVsDropDownBarClient.GetTextEntry string marshalling.");
hackHackClient.GetEntryText(iCombo, iIndex, ppszText);
IntPtr pszText = Marshal.ReadIntPtr(ppszText);
szText = Marshal.PtrToStringUni(pszText);
}
finally
{
if(ppszText != IntPtr.Zero)
Marshal.FreeCoTaskMem(ppszText);
}
return szText;
}
}