Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tutorial se muestra cómo crear una extensión para los proyectos de SharePoint. Puede utilizar una extensión de proyecto para responder a los eventos de nivel de proyecto, como cuando se agrega o se elimina un proyecto, o se le cambia de nombre. También puede agregar propiedades personalizadas o responder cuando cambia un valor de propiedad. A diferencia de las extensiones de elemento de proyecto, las extensiones de proyecto no pueden estar asociadas a un tipo de proyecto de SharePoint determinado. Cuando crea una extensión de proyecto, se carga cuando se abre cualquier tipo de proyecto de SharePoint en Visual Studio.
En este tutorial, creará una propiedad booleana personalizada que se agrega a cualquier proyecto de SharePoint creado en Visual Studio. Cuando se establece en True, la nueva propiedad agrega o asigna una carpeta de recursos Images al proyecto. Cuando se establece en False, se quita la carpeta Images, si existe. Para obtener más información, vea Cómo: Agregar y quitar carpetas asignadas.
En este tutorial se muestran las siguientes tareas:
Crear una extensión Visual Studio para los proyectos SharePoint que hace lo siguiente:
Agrega una propiedad de proyecto personalizada a la ventana Propiedades. La propiedad se aplica a cualquier proyecto de SharePoint.
Utiliza el modelo de objetos de proyecto de SharePoint para agregar una carpeta asignada a un proyecto.
Usa el modelo de objetos de automatización (DTE) de Visual Studio para eliminar una carpeta asignada del proyecto.
Compilar un paquete de extensión (VSIX) de Visual Studio para implementar el ensamblado de la extensión de propiedad de proyecto.
Depurar y probar la propiedad de proyecto.
Requisitos previos
Necesitará los componentes siguientes en el equipo de desarrollo para completar este tutorial:
Ediciones compatibles de Microsoft Windows, SharePoint y Visual Studio. Para obtener más información, vea Requisitos para desarrollar soluciones de SharePoint.
Visual Studio 2010 SDK. En este tutorial se utiliza la plantilla Proyecto VSIX del SDK para crear un paquete VSIX para implementar la extensión de propiedad de proyecto. Para obtener más información, vea Extender la Herramientas de SharePoint en Visual Studio.
Crear los proyectos
Para completar este tutorial, debe crear dos proyectos:
Un proyecto VSIX para crear el paquete VSIX e implementar la extensión de proyecto.
Un proyecto de biblioteca de clases que implemente la extensión de proyecto.
Comience el tutorial creando ambos proyectos.
Para crear el proyecto de VSIX
Inicie Visual Studio.
En el menú Archivo, elija Nuevo y haga clic en Proyecto.
En el cuadro de diálogo Nuevo proyecto, expanda el nodo Visual Basic o Visual C# y, a continuación, haga clic en el nodo Extensibilidad.
Nota
El nodo Extensibilidad solo está disponible si instala Visual Studio 2010 SDK. Para obtener más información, vea la sección Requisitos previos, anteriormente en este tutorial.
En el cuadro combinado de la parte superior del cuadro de diálogo, seleccione .NET Framework 4. Las extensiones de herramientas de SharePoint requieren características de .NET Framework.
Haga clic en la plantilla Proyecto VSIX.
En el cuadro Nombre, escriba ProjectExtensionPackage.
Haga clic en Aceptar.
Visual Studio agrega el proyecto ProjectExtensionPackage al Explorador de soluciones.
Para crear la extensión de proyecto
En el Explorador de soluciones, haga clic con el botón secundario en el nodo de la solución, después haga clic en Agregar y, a continuación, en Nuevo proyecto.
Nota
En los proyectos de Visual Basic, el nodo de la solución aparece en el Explorador de soluciones solo cuando se activa la casilla Mostrar solución siempre en General, Proyectos y soluciones, Opciones (Cuadro de diálogo).
En el cuadro de diálogo Nuevo proyecto, expanda Visual C# o Visual Basic y, a continuación, haga clic en Windows.
En el cuadro combinado de la parte superior del cuadro de diálogo, seleccione .NET Framework 4.
Seleccione la plantilla de proyecto Biblioteca de clases.
En el cuadro Nombre, escriba ProjectExtension.
Haga clic en Aceptar.
Visual Studio agrega el proyecto ProjectExtension a la solución y abre el archivo de código predeterminado Class1.
Elimine el archivo de código Class1 del proyecto.
Configurar el proyecto
Antes de escribir el código que crea la extensión del elemento de proyecto, tiene que agregar los archivos de código y las referencias de ensamblado al proyecto de extensión.
Para configurar el proyecto
Agregue un nuevo archivo de código denominado CustomProperty al proyecto ProjectExtension.
Haga clic en la opción Agregar referencia del menú Proyecto.
En la pestaña .NET, presione CTRL y haga clic en los ensamblados siguientes; a continuación, haga clic en Aceptar:
Microsoft.VisualStudio.SharePoint
System.ComponentModel.Composition
System.Windows.Forms
EnvDTE
En el Explorador de soluciones, en la carpeta Referencias del proyecto ProjectExtension, haga clic en EnvDTE.
En la ventana Propiedades, cambie el valor de Incrustar tipos de interoperabilidad a False.
Definir la nueva propiedad de proyecto de SharePoint
Cree una clase que defina la extensión de proyecto y el comportamiento de la nueva propiedad. Para definir la nueva extensión de proyecto, la clase implementa la interfaz ISharePointProjectExtension. Implemente esta interfaz siempre que desee definir una extensión para un proyecto de SharePoint. También agregue ExportAttribute a la clase. Este atributo permite que Visual Studio detecte y cargue la implementación de ISharePointProjectExtension. Pase el tipo ISharePointProjectExtension al constructor del atributo.
Para definir la nueva propiedad de proyecto de SharePoint
Haga doble clic en el archivo de código CustomProperty para modificarlo, si no está abierto.
Pegue el código siguiente en el archivo.
Imports System Imports System.Linq Imports System.ComponentModel Imports System.ComponentModel.Composition Imports System.Windows.Forms Imports Microsoft.VisualStudio.SharePoint Imports EnvDTE Namespace Contoso.SharePointProjectExtensions.MapImagesFolder ' Export attribute: Enables Visual Studio to discover and load this extension. ' MapImagesFolderProjectExtension class: Adds a new Map Images Folder property to any SharePoint project. <Export(GetType(ISharePointProjectExtension))> _ Public Class MapImagesFolderProjectExtension Implements ISharePointProjectExtension Public Sub Initialize(ByVal projectService As ISharePointProjectService) Implements ISharePointProjectExtension.Initialize AddHandler projectService.ProjectPropertiesRequested, AddressOf Me.projectService_ProjectPropertiesRequested End Sub Private Sub projectService_ProjectPropertiesRequested(ByVal sender As Object, ByVal e As SharePointProjectPropertiesRequestedEventArgs) Dim propertiesObject As CustomProjectProperties = Nothing ' If the properties object already exists, get it from the project's annotations. If False = e.Project.Annotations.TryGetValue(propertiesObject) Then ' Otherwise, create a new properties object and add it to the annotations. propertiesObject = New CustomProjectProperties(e.Project) e.Project.Annotations.Add(propertiesObject) End If e.PropertySources.Add(propertiesObject) End Sub End Class Public Class CustomProjectProperties Private sharePointProject As ISharePointProject = Nothing Private Const MapImagesFolderPropertyDefaultValue As Boolean = False Private Const MapImagesFolderPropertyId = "ContosoMapImagesFolderProperty" Public Sub New(ByVal myProject As ISharePointProject) sharePointProject = myProject End Sub ' Represents the new boolean property MapImagesFolder. ' True = Map an Images folder to the project if one does not already exist; otherwise, do nothing. ' False = Remove the Images folder from the project, if one exists; otherwise, do nothing. <DisplayName("Map Images Folder")> _ <DescriptionAttribute("Specifies whether an Images folder is mapped to the SharePoint project.")> _ <DefaultValue(MapImagesFolderPropertyDefaultValue)> _ Public Property MapImagesFolder As Boolean Get Dim propertyStringValue As String = String.Empty ' Try to get the current value from the .user file; if it does not yet exist, return a default value. If Not sharePointProject.ProjectUserFileData.TryGetValue(MapImagesFolderPropertyId, propertyStringValue) Then Return MapImagesFolderPropertyDefaultValue Else Return CBool(propertyStringValue) End If End Get Set(ByVal value As Boolean) If value Then If Not ImagesMappedFolderInProjectExists(sharePointProject) Then ' An Images folder is not mapped to the project, so map one. Dim mappedFolder As IMappedFolder = sharePointProject.MappedFolders.Add(MappedFolderType.Images) sharePointProject.ProjectService.Logger.WriteLine( _ mappedFolder.Name & " mapped folder added to the project.", LogCategory.Status) End If ElseIf (ImagesMappedFolderInProjectExists(sharePointProject) AndAlso UserSaysDeleteFile()) Then ' An Images folder is mapped to the project and the user wants to remove it. DeleteFolder() End If sharePointProject.ProjectUserFileData(MapImagesFolderPropertyId) = value.ToString() End Set End Property Private Function ImagesMappedFolderInProjectExists(ByVal sharePointProject As ISharePointProject) As Boolean Dim returnValue As Boolean = False For Each folder As IMappedFolder In sharePointProject.MappedFolders ' Check to see if an Images folder is already mapped. If (folder.FolderType = MappedFolderType.Images) Then returnValue = True End If Next Return returnValue End Function Private Function UserSaysDeleteFile() As Boolean ' Ask the user whether they want to delete the Images folder. Dim returnValue As Boolean = False If (MessageBox.Show("Do you want to delete the Images folder from the project?", _ "Delete the Images folder?", MessageBoxButtons.YesNo) = DialogResult.Yes) Then returnValue = True End If Return returnValue End Function Private Sub DeleteFolder() ' The Visual Studio DTE object model is required to delete the mapped folder. Dim dteProject As EnvDTE.Project = _ sharePointProject.ProjectService.Convert(Of ISharePointProject, EnvDTE.Project)(sharePointProject) Dim targetFolderName As String = _ sharePointProject.MappedFolders.First(Function(mf) mf.FolderType = MappedFolderType.Images).Name Dim mappedFolderItem As EnvDTE.ProjectItem = dteProject.ProjectItems.Item(targetFolderName) mappedFolderItem.Delete() sharePointProject.ProjectService.Logger.WriteLine("Mapped Folder " & _ targetFolderName & " deleted", LogCategory.Status) End Sub End Class End Namespaceusing System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.ComponentModel.Composition; using System.Windows.Forms; using Microsoft.VisualStudio.SharePoint; using EnvDTE; // Adds a new property called MapImagesFolder to any SharePoint project. // When MapImagesFolder is set to true, the Image folder is mapped to the project. // When MapImagesFolder is set to false, the Image folder is deleted from the project. namespace SP_Project_Extension { // Export attribute: Enables Visual Studio to discover and load this extension. [Export(typeof(ISharePointProjectExtension))] // Defines a new custom project property that applies to any SharePoint project. public class SPProjectExtension : ISharePointProjectExtension { // Implements ISharePointProjectService.Initialize, which determines the behavior of the new property. public void Initialize(ISharePointProjectService projectService) { // Handle events for when a project property is changed. projectService.ProjectPropertiesRequested += new EventHandler<SharePointProjectPropertiesRequestedEventArgs>(projectService_ProjectPropertiesRequested); } void projectService_ProjectPropertiesRequested(object sender, SharePointProjectPropertiesRequestedEventArgs e) { // Add a new property to the SharePoint project. e.PropertySources.Add((object)new ImagesMappedFolderProperty(e.Project)); } } public class ImagesMappedFolderProperty { ISharePointProject sharePointProject = null; public ImagesMappedFolderProperty(ISharePointProject myProject) { sharePointProject = myProject; } static bool MapFolderSetting = false; [DisplayName("Map Images Folder")] [DescriptionAttribute("Specifies whether an Images folder is mapped to the SharePoint project.")] public bool MapImagesFolder // Represents the new boolean property MapImagesFolder. // True = Map an Images folder to the project if one does not already exist; otherwise, do nothing. // False = Remove the Images folder from the project, if one exists; otherwise, do nothing. { get { // Get the current property value. return MapFolderSetting; } set { if (value) { if (!ImagesMappedFolderInProjectExists(sharePointProject)) { // An Images folder is not mapped to the project, so map one. IMappedFolder mappedFolder1 = sharePointProject.MappedFolders.Add(MappedFolderType.Images); // Add a note to the logger that a mapped folder was added. sharePointProject.ProjectService.Logger.WriteLine("Mapped Folder added:" + mappedFolder1.Name, LogCategory.Status); } } else { if (ImagesMappedFolderInProjectExists(sharePointProject) && UserSaysDeleteFile()) { // An Images folder is mapped to the project and the user wants to remove it. // The Visual Studio DTE object model is required to delete the mapped folder. // Reference the Visual Studio DTE model, get handles for the SharePoint project and project items. EnvDTE.Project dteProject = sharePointProject.ProjectService.Convert<ISharePointProject, EnvDTE.Project>(sharePointProject); string targetFolderName = sharePointProject.MappedFolders.First(mf => mf.FolderType == MappedFolderType.Images).Name; EnvDTE.ProjectItem mappedFolderItem = dteProject.ProjectItems.Item(targetFolderName); mappedFolderItem.Delete(); sharePointProject.ProjectService.Logger.WriteLine("Mapped Folder " + targetFolderName + " deleted", LogCategory.Status); } } MapFolderSetting = value; } } private bool ImagesMappedFolderInProjectExists(ISharePointProject sharePointProject) { bool retVal = false; foreach (IMappedFolder folder in sharePointProject.MappedFolders) { // Check to see if an Images folder is already mapped. if (folder.FolderType == MappedFolderType.Images) retVal = true; } return retVal; } private bool UserSaysDeleteFile() { // Prompt the user whether they want to delete the Images folder. bool retVal = false; if (MessageBox.Show("Do you want to delete the Images folder from the project?", "Delete the Images folder?", MessageBoxButtons.YesNo) == DialogResult.Yes) { retVal = true; } return retVal; } } }
Compilar la solución
A continuación, compile la solución para asegurarse de que se compila sin errores.
Para compilar la solución
- En el menú Generar, haga clic en Generar solución.
Crear un paquete VSIX para implementar la extensión de propiedad de proyecto
Para implementar la extensión de proyecto, utilice el proyecto VSIX en la solución para crear un paquete VSIX. Primero, configure el paquete VSIX modificando el archivo source.extension.vsixmanifest incluido en el proyecto VSIX. A continuación, cree el paquete VSIX compilando la solución.
Para crear y configurar el paquete VSIX
En el Explorador de soluciones, haga doble clic en el archivo source.extension.vsixmanifest.
Visual Studio abre el archivo en el editor de manifiestos. Este editor proporciona una UI que puede utilizar para modificar el XML del manifiesto. Esta información se muestra más adelante en el Administrador de extensiones. Todos los paquetes VSIX requieren el archivo extension.vsixmanifest. Para obtener más información sobre este archivo, vea VSIX Extension Schema Reference.
En el cuadro Nombre de producto, escriba Custom Project Property.
En el cuadro Autor, escriba Contoso.
En el cuadro Descripción, escriba Una propiedad de proyecto de SharePoint personalizada que alterna la asignación de la carpeta de recurso Images al proyecto.
En la sección Contenido del editor, haga clic en el botón Agregar contenido.
Seleccione MEF Component en el cuadro desplegable Seleccione un tipo de contenido.
Nota
Este valor corresponde al elemento MEFComponent del archivo extension.vsixmanifest. Este elemento especifica el nombre de un ensamblado de extensión en el paquete VSIX. Para obtener más información, vea MEFComponent Element (VSX Schema).
En la sección Seleccionar un origen, haga clic en la opción Proyecto y, a continuación, seleccione ProjextExtension en el cuadro desplegable.
Este valor identifica el nombre del ensamblado que está compilando en el proyecto.
Cuando termine, haga clic en Aceptar para cerrar el cuadro de diálogo Agregar contenido.
Cuando haya finalizado, haga clic en Guardar todo en el menú Archivo y, a continuación, cierre el diseñador del manifiesto.
En el menú Generar, haga clic en Generar solución. Asegúrese de que el proyecto se compila sin errores.
Haga clic en el proyecto ProjectExtensionPackage en el Explorador de soluciones, haga clic en el botón Mostrar todos los archivos y, a continuación, abra la carpeta de resultado de compilación de ProjectExtensionPackage. Esta carpeta debería contener un archivo ProjectExtensionPackage.vsix.
De forma predeterminada, la carpeta de resultado de compilación es .. \bin\Debug, que se encuentra bajo la carpeta que contiene el archivo de proyecto.
Probar la propiedad de proyecto
Ya puede probar la propiedad de proyecto personalizada. Es más fácil depurar y probar la nueva extensión de propiedad de proyecto en una instancia experimental de Visual Studio. Esta es la instancia de Visual Studio que se crea al ejecutar un VSIX u otro proyecto de extensibilidad. Una vez depurado el proyecto, puede instalar la extensión en su sistema y seguir depurándola y probándola en una instancia normal de Visual Studio.
Para depurar y probar la extensión en una instancia experimental de Visual Studio
Reinicie Visual Studio con credenciales administrativas y abra la solución ProjectExtensionPackage.
Presione F5 para iniciar una compilación de depuración del proyecto.
Visual Studio instala la extensión en %UserProfile%\AppData\Local\Microsoft\VisualStudio\10.0Exp\Extensions\Contoso\Custom Project Property\1 .0 e inicia una instancia experimental de Visual Studio.
En la instancia experimental de Visual Studio, cree nuevo proyecto de SharePoint de una solución de granja de servidores, como un Módulo. Use los valores predeterminados en los demás valores del asistente.
Haga clic en el nodo del proyecto en el Explorador de soluciones.
Una nueva propiedad Map Images Folder personalizado aparece en la ventana Propiedades con un valor predeterminado de False.
Cambie Map Images Folder a True.
Se agrega una carpeta de recurso Images al proyecto SharePoint.
Cambie Map Images Folder a False.
La carpeta de recurso Images se elimina del proyecto SharePoint.
Cierre la instancia experimental de Visual Studio.
Vea también
Otros recursos
Extender los proyectos de SharePoint
Cómo: Agregar una propiedad a proyectos de SharePoint
Guardar datos asociados en extensiones del sistema de proyectos de SharePoint
Asociar datos personalizados con extensiones de herramientas de SharePoint