Para ver el artículo en inglés, active la casilla Inglés. También puede ver el texto en inglés en una ventana emergente si pasa el puntero del mouse por el texto.
Traducción
Inglés

Solución de problemas de extensibilidad en Visual Basic y Visual C#

En esta sección se explican técnicas para solucionar algunos de los problemas de extensibilidad más comunes que se pueden producir al desarrollar aplicaciones de extensibilidad en un proyecto de Visual Basic o de Visual C#.

Si un problema específico no aparece en esta lista, vea el sitio de MSDN Online Support en http://support.microsoft.com para obtener más información.

Los métodos Add y Remove de las distintas clases del objeto CodeModel2 no se admiten en los proyectos de Visual Basic. Si se intenta llamar a uno de estos métodos, se producirá un error "Sin implementar". Los métodos no admitidos son los siguientes:

AddAttribute

AddBase

AddClass

AddDelegate

AddEnum

AddFunction

AddImplementedInterface

AddInterface

AddNameSpace

AddParameter

AddProperty

AddStruct

AddVariable

RemoveInterface

RemoveMember

RemoveMethod

RemoveParameter

 

Para agregar elementos de código a la aplicación a través de una macro, utilice las características de edición de texto del modelo de extensibilidad. Para obtener información más detallada, vea Cómo: Utilizar una macro para agregar texto a un editor de código de Visual Basic o C#, donde encontrará un ejemplo sobre cómo agregar código a un archivo de código fuente. El modelo de extensibilidad general de Visual Studio contiene varios objetos útiles para leer y modificar código fuente. Entre ellos se incluyen los objetos Document, TextDocument, EditPoint, TextPoint y VirtualPoint.

La mayoría de las propiedades de CodeModel2 se implementan como campos de solo lectura en los proyectos de Visual Basic. Si se intenta establecer una propiedad en tiempo de ejecución, se producirá un error "No implementado". Entre las propiedades de sólo lectura se incluyen las siguientes:

Access

CanOverride

Comment

DocComment

Getter

InitExpression

IsAbstract

IsConstant

IsShared

MustImplement

Setter

 

Para cambiar el valor de una propiedad del objeto CodeModel2, cambie la definición del elemento de código en el archivo de código fuente. Esto se puede realizar de dos formas:

Las llamadas a un objeto CodeModel2 producen errores cuando el proyecto cambia después de crear una referencia a CodeModel2. Por ejemplo, si se ejecuta una aplicación de extensibilidad en un entorno de desarrollo y ésta recupera una instancia del objeto CodeModel2 para una de las clases definidas en el proyecto y, a continuación, un usuario elimina la clase en el entorno de desarrollo, las llamadas posteriores al objeto CodeModel2 de esa clase producirán errores, debido a que la clase ya no existe en el proyecto.

No existe ninguna propiedad que se pueda probar para determinar si una referencia es aún válida. Se pueden eludir estos problemas utilizando métodos de programación sólidos.

Puede haber ocasiones en que se precise editar un archivo de macros en un editor de texto. Para guardar el archivo de macros como texto sin formato, en el menú Archivo, haga clic en el comando Exportar. Cuando aparezca el cuadro de diálogo Exportar archivo, escriba el nombre del archivo de exportación que desea crear y este se guardará como un archivo de código fuente de Visual Basic con la extensión .vb.

El comando Agregar elemento existente del menú Archivo permite agregar un archivo de código fuente de Visual Basic al proyecto de macros.

Para obtener más información, vea Cómo: Administrar macros.

Un objeto puede mostrar una serie de mensajes de error si la estructura del proyecto cambia mientras el código mantiene una referencia a uno de los objetos de extensibilidad. Esto puede ocurrir cuando:

  • Se cierra un proyecto en el entorno de desarrollo. En este caso, la referencia Project a dicho proyecto no será válida, como no lo será ningún otro objeto en él contenido. Si se utiliza la referencia Project, tal vez para agregar un archivo al proyecto, el método producirá un error. Por ejemplo, la macro siguiente devuelve "Proyecto no disponible" cuando se intenta obtener acceso a proj.Name:

    ' Macro editor
    Public Sub AccessAClosedProject()
       Dim proj As Project = DTE.Solution.Projects.Item(1)
       DTE.Solution.Close()
       MsgBox(proj.Name)
    End Sub
    
  • Se elimina un archivo del proyecto. Por ejemplo, la macro siguiente devuelve "ProjectItem no disponible" cuando se intenta obtener acceso a 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
    
  • Se elimina una referencia del proyecto. Por ejemplo, la macro siguiente devuelve "El servidor produjo una excepción" cuando se intenta obtener acceso a 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
    
  • Los cambios en el control de código fuente hacen que se vuelva a cargar el proyecto, en cuyo caso, los objetos antiguos dejan de ser válidos. Por ejemplo, el proyecto volverá a cargarse si se desprotege el archivo del proyecto y existe una nueva versión en la base de datos de control de código fuente. Asimismo, se producirá una nueva carga si se protege el archivo del proyecto y éste debe combinarse con los archivos del control de código fuente.

  • Un elemento del proyecto se guarda mediante el comando Guardar como. Esto crea un nuevo objeto ProjectItem para el archivo. El objeto original deja de ser válido.

  • Ocurre cualquier cosa que hace que el proyecto se vuelva a cargar.

No existe ninguna propiedad que se pueda probar para determinar si una referencia a un proyecto o elemento de proyecto es aún válida. Los errores importantes devueltos por algunas de las propiedades y los métodos de un objeto indicarán que ya no son válidos. Se pueden eludir estos problemas utilizando métodos de programación sólidos.

Si se utiliza el método AddFromFile y se producen errores al crear el proyecto, aparecerán diversos cuadros de diálogo. El método LaunchWizard se puede utilizar para crear nuevos proyectos y eliminar la interfaz de usuario. Cuando se llama a LaunchWizard para crear un nuevo proyecto a partir de un proyecto de extensibilidad, el comportamiento predeterminado es que los errores se muestren en cuadros de mensajes.

El método LaunchWizard adopta dos argumentos al ejecutar un asistente para un nuevo proyecto. El primer argumento es el nombre del archivo del asistente (archivo .vsz). El segundo argumento es una matriz de valores que se pasa al asistente cuando éste se ejecuta. Si se establece el séptimo elemento de la matriz en true, se puede forzar a los errores para que produzcan excepciones que puedan interceptarse en una estructura Try...Catch. El asistente para una nueva aplicación para Windows espera los siguientes valores en la matriz:

Índice de matriz

Valor

0

WizardType: GUID que indica el tipo de asistente. En el caso de un asistente para nuevo proyecto, el identificador GUID es "{0F90E1D0-4999-11D1-B6D1-00A0C90F2744}".

1

ProjectName: cadena para el nombre del nuevo proyecto.

2

Local directory: cadena que contiene la ruta de acceso completa a la carpeta en la que se creará el nuevo proyecto.

3

Installation directory: cadena que contiene la carpeta en la que está instalado Visual Studio.

4

Exclusive: valor booleano que indica si se debería cerrar cualquier solución existente que se encuentre abierta.

5

Solution name: nombre de cadena para el archivo de la solución, sin ruta de acceso ni extensión.

6

Silent: valor booleano que indica si el asistente tiene que ejecutarse sin interfaz de usuario.

La macro siguiente muestra cómo se usa el marcador Silent cuando se llama al asistente. Si ejecuta esta macro una vez, se ejecutará sin errores, siempre y cuando el directorio y el proyecto no existan con anterioridad. Si ejecuta esta macro una segunda vez, se producirá un error ya que, al estar el marcador Silent establecido en true, el bloque Try...Catch detectará una excepción.

' 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

Este error se puede producir al manipular los objetos CodeModel2 de archivos de código fuente de Visual Basic.

Cuando escriba código que mantenga referencias a objetos CodeElement2, tenga en cuenta que el código fuente subyacente puede cambiar mientras se conserva la referencia. Puede que el elemento de código se elimine, cambie de nombre o sufra un error de compilación. Cuando esto sucede, cualquier llamada al objeto CodeElement2 devolverá el mensaje de error "Excepción de HRESULT: 0x80047E2C".

Una vez que la referencia se invalida de este modo, no se puede recuperar. Para corregir el problema, será necesario corregir los errores que haya en el código fuente y recuperar una nueva referencia del objeto CodeModel2.

En las macros siguientes se muestra cómo podría producirse este error. Agregue una clase denominada LostClass al proyecto. Haga esta clase del nivel superior, no la incluya en un espacio de nombres ni en otra clase. Ejecute la macro SetElement, elimine la clase y, a continuación, ejecute la macro GetElement. Al ejecutar GetElement, la clase ya no existe y la referencia a lostClass no es válida y devuelve el error.

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

Adiciones de comunidad

AGREGAR
Mostrar: