문서를 영문으로 보려면 영문 확인란을 선택하세요. 마우스 포인터를 텍스트 위로 이동시켜 팝업 창에서 영문 텍스트를 표시할 수도 있습니다.
번역
영문
Visual Studio 2017을 사용하는 것이 좋습니다.

Visual Basic 및 Visual C# 확장성 문제 해결

이 문서에서는 Visual Basic 또는 Visual C# 프로젝트를 위한 확장성 응용 프로그램을 개발할 때 발생하는 일반적인 확장성 문제를 해결하는 방법에 대해 설명합니다.

해당 문제점이 위 목록에 없는 경우 MSDN 온라인 지원 사이트(http://support.microsoft.com)에서 자세한 내용을 참조하십시오.

Visual Basic 프로젝트에서는 CodeModel2 개체에 있는 다양한 클래스의 Add 및 Remove 메서드를 지원하지 않습니다. 이러한 메서드 중 하나를 호출하면 "구현되지 않았습니다"라는 오류가 발생합니다. 다음은 지원되지 않는 메서드입니다.

AddAttribute

AddBase

AddClass

AddDelegate

AddEnum

AddFunction

AddImplementedInterface

AddInterface

AddNameSpace

AddParameter

AddProperty

AddStruct

AddVariable

RemoveInterface

RemoveMember

RemoveMethod

RemoveParameter

 

매크로를 통해 코드 요소를 응용 프로그램에 추가하려면 확장성 모델의 텍스트 편집 기능을 사용해야 합니다. 자세한 내용은 소스 파일에 코드를 추가하는 방법의 예제를 제공하는 방법: 매크로를 사용하여 Visual Basic 또는 C# 코드 편집기에서 텍스트 추가를 참조하십시오. Visual Studio 일반 확장성 모델에는 소스 코드를 읽고 수정하는 데 도움이 되는 여러 개체가 있습니다. Document 개체, TextDocument 개체, EditPoint 개체, TextPoint 개체 및 VirtualPoint 개체가 여기에 포함됩니다.

CodeModel2의 속성은 대부분 Visual Basic 프로젝트의 읽기 전용 필드로 구현됩니다. 런타임에 속성을 설정할 경우 "구현되지 않았습니다"라는 오류가 발생합니다. 다음은 읽기 전용 속성입니다.

액세스

CanOverride

주석

DocComment

Getter

InitExpression

IsAbstract

IsConstant

IsShared

MustImplement

Setter

 

CodeModel2 개체의 속성 값을 변경하려면 소스 파일에서 코드 요소의 정의를 변경합니다. 다음 두 가지 방법을 사용하여 이를 수행할 수 있습니다.

CodeModel2에 대한 참조를 만든 후 프로젝트를 변경하면 CodeModel2 개체 호출이 실패합니다. 예를 들어, 개발 환경에서 확장성 응용 프로그램을 실행하는 경우, 응용 프로그램에서 프로젝트에 정의된 클래스 중 하나에 대해 CodeModel2 인스턴스를 검색했다고 가정합니다. 그리고는 사용자가 개발 환경에서 클래스를 삭제합니다. 그러면 이 클래스가 프로젝트에 더 이상 존재하지 않으므로 이후로는 이 클래스에 대해 CodeModel2를 호출하면 호출이 실패합니다.

참조가 여전히 유효한지 여부를 테스트하는 데 사용할 수 있는 속성은 없습니다. 강력한 프로그래밍 방법을 사용하면 이러한 문제를 방지할 수 있습니다.

매크로 파일을 텍스트 편집기에서 편집해야 할 경우가 있습니다. 일반 텍스트로 된 매크로 파일을 저장하려면 파일 메뉴에서 내보내기 명령을 클릭합니다. 파일 내보내기 대화 상자가 표시되면 작성할 내보내기 파일의 이름을 입력합니다. 그러면 확장명이 .vb인 Visual Basic 소스 파일로 파일이 저장됩니다.

파일 메뉴의 기존 항목 추가 명령을 사용하면 Visual Basic 소스 파일을 매크로 프로젝트에 추가할 수 있습니다.

자세한 내용은 Managing Macros를 참조하십시오.

확장성 개체 중 하나에 대한 참조가 코드에 포함되어 있을 때 프로젝트의 구조가 변경되면 개체에서 다양한 오류 메시지가 나타날 수 있습니다. 다음과 같은 경우에 이런 상황이 발생할 수 있습니다.

  • 개발 환경에서 프로젝트가 닫혀 있습니다. 이 경우 이 프로젝트에 대한 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에 액세스하면 "The server threw an exception"라는 오류가 반환됩니다.

    ' 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로 설정하면 오류가 발생할 때 예외를 throw하고 Try...Catch 구문에서 예외를 catch하도록 할 수 있습니다. 새 Windows 응용 프로그램 마법사는 배열에서 다음과 같은 값을 요구합니다.

배열 인덱스

0

WizardType. 마법사 형식을 나타내는 GUID입니다. 새 프로젝트 마법사에 대한 GUID는 "{0F90E1D0-4999-11D1-B6D1-00A0C90F2744}"입니다.

1

ProjectName. 새 프로젝트의 이름에 사용할 문자열입니다.

2

로컬 디렉터리. 새 프로젝트를 만들 폴더에 대한 전체 경로가 포함된 문자열입니다.

3

설치 디렉터리. Visual Studio를 설치할 폴더가 포함된 문자열입니다.

4

Exclusive. 기존에 열려 있는 솔루션을 닫을지 여부를 나타내는 부울 값입니다.

5

솔루션 이름. 경로나 확장명 없이 솔루션 파일에 대한 문자열 이름입니다.

6

Silent. 마법사를 자동으로 실행할지 여부를 나타내는 부울 값입니다.

다음 매크로에서는 마법사를 호출할 때 Silent 플래그를 사용하는 방법을 보여 줍니다. 이 매크로는 처음 실행할 때 디렉터리와 프로젝트가 이미 존재하지 않으면 오류 없이 실행되지만, 두 번째 실행할 때는 오류가 발생합니다. Silent 플래그를 true로 설정했으므로 Try...Catch 블록에서 예외가 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

이 오류는 Visual Basic 소스 파일에서 CodeModel2 개체를 조작할 때 발생할 수 있습니다.

CodeElement2 개체를 참조하는 코드를 작성할 때는 참조를 하는 동안 내부 소스 코드가 변경될 수 있다는 것을 명심해야 합니다. 코드 요소가 삭제되거나 이름이 변경되거나 컴파일러 오류가 발생할 수 있습니다. 이 경우 CodeElement2 개체를 호출하면 "HRESULT에서 오류가 발생했습니다. 0x80047E2C"라는 오류 메시지가 반환됩니다.

이러한 방법으로 참조가 잘못되면 복구할 수 없습니다. 이 문제를 수정하려면 소스 코드의 오류를 수정하고 CodeModel2 개체에서 새 참조를 복원해야 합니다.

다음 매크로는 이 오류가 발생할 수 있는 상황을 보여 줍니다. LostClass라는 클래스를 프로젝트에 추가합니다. 이 클래스를 네임스페이스나 클래스 내부가 아닌 최상위 수준 클래스로 만듭니다. 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
표시: