Visual Basic 和 Visual C# 擴充性疑難排解

在開發 Visual Basic 或 Visual C# 專案的擴充性應用程式時,您可能會遇到擴充性的問題,以下將針對一些比較常見的擴充性問題提出解決技術。

如果您所遇到的問題未列在此清單中,請參閱位於 https://support.microsoft.com 的 MSDN Online Support 網站以取得詳細資訊。

CodeModel 中的 Add 和 Remove 方法無法運作。

CodeModel2 物件之各種類別的 Add 和 Remove 方法在 Visual Basic 專案中並不支援。 如果您呼叫這些方法,您就會收到「未實作」錯誤。 下列是不受支援的方法:

AddAttribute

AddBase

AddClass

AddDelegate

AddEnum

AddFunction

AddImplementedInterface

AddInterface

AddNameSpace

AddParameter

AddProperty

AddStruct

AddVariable

RemoveInterface

RemoveMember

RemoveMethod

RemoveParameter

 

若要透過巨集將程式碼項目加入至應用程式,可以使用擴充性模型的文字編輯功能。 如需詳細資訊,請參閱HOW TO:使用巨集在 Visual Basic 或 C# 程式碼編輯器中加入文字,其中包含如何將程式碼加入至原始程式檔的範例。 Visual Studio 的一般擴充性模型包含幾個適合用來讀取和修改原始程式碼的物件, 包括 Document 物件、TextDocument 物件、EditPoint 物件、TextPoint 物件和 VirtualPoint 物件。

我無法變更 CodeModel 物件的屬性。

CodeModel2 物件中的大多數屬性都是實作為 Visual Basic 專案的唯讀欄位。 如果您嘗試在執行階段設定屬性,您會收到「未實作」錯誤。 唯讀屬性包含:

Access

CanOverride

Comment

DocComment

Getter

InitExpression

IsAbstract

IsConstant

IsShared

MustImplement

Setter

 

若要變更 CodeModel2 物件的屬性值,請在原始程式檔中變更程式碼項目的定義。 執行這項作業的方法有兩種:

對 CodeElement 物件的呼叫失敗。

如果專案在您建立 CodeModel2 物件的參考之後變更,對 CodeModel2 物件的呼叫就會失敗。 例如,您可能有個在開發環境中執行的擴充性應用程式。 這個應用程式可能已經為專案中定義的某一個類別擷取了 CodeModel2 執行個體。 接著使用者可能會在開發環境中刪除這個類別。 那麼後續對這個類別的 CodeModel2 發出的呼叫就會失敗,因為專案中已經沒有這個類別了。

您無法使用屬性來進行測試以判斷參考是否仍然有效。 您可以採用強固的程式設計方法來防止這些問題發生。

我要在文字編輯器中編輯我的巨集程式碼。

在一些情況下,您會需要在文字編輯器中編輯您的巨集檔。 若要以純文字格式儲存巨集檔案,請按一下 [檔案] 功能表上的 [匯出] 命令。 當 [匯出檔案] 對話方塊出現時,請輸入您要建立之匯出檔案的名稱。 該檔案將會儲存為副檔名為 .vb 的 Visual Basic 原始程式檔。

[檔案] 功能表上的 [加入現有項目] 命令可以讓您將 Visual Basic 原始程式檔加入至巨集專案中。

如需詳細資訊,請參閱 HOW TO:管理巨集

我收到無法使用項目的訊息。

如果專案結構變更而您的程式碼這時還使用任一擴充性物件的參考,則物件可能會顯示各種錯誤訊息。 這可能會發生在以下情況:

  • 專案在開發環境中關閉。 在這種情況下,它的 Project 參考就會變成無效,包含在專案中的任何物件也會變成無效。 如果您使用這個 Project 參考將檔案加入至專案或進行其他動作,方法就會失敗。 例如,以下巨集在嘗試存取 proj.Name 時會傳回「專案無法使用」:

    ' Macro editor
    Public Sub AccessAClosedProject()
       Dim proj As Project = DTE.Solution.Projects.Item(1)
       DTE.Solution.Close()
       MsgBox(proj.Name)
    End Sub
    
  • 檔案從專案中刪除。 例如,以下巨集在嘗試存取 projItem.Name 時會傳回「專案項目無法使用」:

    ' Macro editor
    Public Sub AccessADeletedFile()
       Dim proj As Project = DTE.Solution.Projects.Item(1)
       Dim projItem As ProjectItem = proj.ProjectItems.Item(1)
       proj.ProjectItems.Item(1).Delete()
       MsgBox(projItem.Name)
    End Sub
    
  • 參考從專案中刪除。 例如,以下巨集在嘗試存取 ref.Name 時會傳回「伺服器發生例外狀況」:

    ' Macro editor
    Public Sub AccessARemovedReference()
       Dim vsproj As VSProject = _
          CType(DTE.Solution.Projects.Item(1).Object, VSProject)
       Dim ref As Reference = vsproj.References.Item(1)
       vsproj.References.Item(1).Remove()
       MsgBox(ref.Name)
    End Sub
    
  • 原始檔控制變更造成專案重新載入。 在這種情況下,舊物件就變成無效。 例如,如果您簽出專案檔案而原始檔控制資料庫中有新版本,就會發生重新載入。 另一個範例就是,當您簽入專案檔而且它必須與原始檔控制中的檔案合併時,也會發生重新載入。

  • 專案項目是使用 [另存新檔] 命令來儲存。 這時會為檔案建立新的 ProjectItem 物件。 原始物件就變成無效。

  • 任何造成專案重新載入的情況。

您無法使用屬性來進行測試以判斷專案的參考或專案項目是否仍有效。 由物件的某些屬性和方法所傳回的相關錯誤會指出該物件已不再有效。 您可以採用強固的程式設計方法來防止這些問題發生。

我要建立新的專案,而且我不要任何錯誤訊息出現。

使用 AddFromFile 方法時,如果建立專案時發生錯誤,就會出現各種對話方塊。 LaunchWizard 方法可以用來建立新的專案並隱藏使用者介面。 當呼叫 LaunchWizard 方法從擴充性專案建立新的專案時,預設行為就是錯誤會顯示在訊息方塊中。

執行新的專案精靈時,LaunchWizard 方法會使用兩個引數。 第一個引數是精靈檔 (.vsz 檔) 的名稱。 第二個引數是精靈執行時傳遞至精靈的值陣列。 只要將陣列的第七個元素設定為 true,就可以強制錯誤擲回在 Try...Catch 結構中攔截到的例外狀況。 「新增 Windows 應用程式」精靈必須要有下列陣列值:

陣列索引

0

WizardType,指示精靈類型的 GUID。 如果是新的專案精靈,GUID 為 "{0F90E1D0-4999-11D1-B6D1-00A0C90F2744}"。

1

ProjectName,表示新專案名稱的字串。

2

本機目錄,字串中包含建立新專案所在資料夾的完整路徑。

3

安裝目錄,字串中包含安裝 Visual Studio 所在的資料夾。

4

獨佔模式,指示現有開啟方案是否應關閉的布林值 (Boolean)。

5

方案名稱,方案檔的字串名稱,不含路徑或副檔名。

6

無訊息,指示是否應無訊息地執行精靈的布林值。

以下巨集將顯示如何在呼叫精靈時使用 Silent 旗標。 如果您只執行巨集一次,則在目錄和專案都尚未存在的情況下,執行不會發生錯誤。 如果您再次執行巨集,就會引發錯誤。 由於 Silent 旗標設定為 true,因此 Try...Catch 區塊會攔截到例外狀況。

' Macro editor
Sub RunLaunchWizard()
   Dim params() As Object = New Object() { _
      "{0F90E1D0-4999-11D1-B6D1-00A0C90F2744}", _
      "NewProjectName", _
      "NewProjectPath", _
      "", _
      False, _
      "", _
      True}  ' -->  This is the "Silent" flag ... TRUE=No UI, FALSE=UI
   Dim res As EnvDTE.wizardResult
   Dim s As String = _
      DTE.Solution.TemplatePath(VSLangProj.PrjKind.prjKindVBProject)

   Try
      res = DTE.LaunchWizard(s & "WindowsApplication.vsz", params)
   Catch e1 As System.Exception
      MsgBox("Cannot create new project.")
   End Try
End Sub

何謂 HRESULT: 0x80047E2C?

這個錯誤可能發生在您管理 Visual Basic 原始程式檔的 CodeModel2 物件時。

當您撰寫保留 CodeElement2 物件之參考的程式碼時,應該要了解基礎原始程式碼可能會在您持用參考時發生變更。 程式碼項目可能會被刪除、重新命名或產生編譯器錯誤。 發生這種情況時,對 CodeElement2 物件發出的任何呼叫都會傳回「發生例外狀況於 HRESULT: 0x80047E2C」的錯誤訊息。

一旦參考因為這樣成為無效,便無法復原。 若要修正這個問題,必須修正原始程式碼中的所有錯誤,然後從 CodeModel2 物件中擷取新的參考。

以下的巨集展示這個錯誤可能發生的方式。 將名為 LostClass 的類別加入至專案中。 將此類別建立為最上層的類別,而不要在某個命名空間 (Namespace) 或類別內。 執行 SetElement 巨集,刪除該類別,然後再執行 GetElement 巨集。 當您執行 GetElement 時,由於該類別已經不存在,因此 lostClass 參考就會變成無效並傳回錯誤。

Public Module CreateLostClass
    Dim lostClass As CodeElement

    Sub SetElement()
        Dim proj As Project = DTE.Solution.Projects.Item(1)
        lostClass = proj.CodeModel.CodeElements.Item("LostClass")
        MsgBox(lostClass.Name)
    End Sub

    Sub GetElement()
        MsgBox(lostClass.Name)
    End Sub
End Module

請參閱

概念

專案擴充性簡介