2015-02-11 63 views
1

在我的Visual Studio擴展中,我將讀取導航欄中的文本。因此,我聽窗口創建的事件,並從IVsCodeWindow對象,我得到IVsDropdownBar獲取下拉欄中的當前選擇。這工作正常。然後,我使用以下代碼片段來提取當前選擇的文本:IVsDropdownBarClient和GetEntryText:文本緩衝區問題

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對象的生命 。如果您在託管代碼中實現此接口,並且您需要調用者將字符串丟棄到 ,請在 IVsDropdownBarClient接口上實現IVsCoTaskMemFreeMyStrings接口。

我認爲這是我的問題的一部分,但我不能真正理解我必須在我的代碼中更改以使其工作。任何提示?

回答

0

我很確定現在Visual Studio SDK Interop DLL有錯誤的編組信息IVsDropDownbarClient.GetEntryText,並且沒有辦法使用該接口調用該方法。

到目前爲止,我已經找到了最好的解決方法是:

  1. 使用tlbimp工具生成textmgr備用互操作DLL。 (您可以放心地忽略了幾十個警告,包括一個約GetTextEntry)

    TLBIMP 「C:\ Program Files文件(x86)的\微軟的Visual Studio 11.0 \ VSSDK \ VisualStudioIntegration \ COMMON \公司\ textmgr.tlb」

  2. (可選)如果您使用源代碼管理,您可能需要將生成的文件(TextManagerInternal.dll)複製到擴展項目的子目錄中,並將其作爲外部依賴項檢入。

  3. 在您的Visual Studio擴展項目中,添加對該文件(TextManagerInternal.dll)的引用。

  4. 添加以下方法,應該正確處理字符串編組。

    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; 
    } 
    

    }