Condividi tramite


Procedura dettagliata: creazione di un'estensione di progetto SharePoint

Questa procedura dettagliata illustra come creare un'estensione per i progetti SharePoint. È possibile utilizzare un'estensione di progetto per rispondere ad eventi a livello di progetto, ad esempio quando si aggiunge o si elimina un progetto o quando se ne modifica il nome. È inoltre possibile aggiungere proprietà personalizzate o rispondere a un evento di modifica di un valore di proprietà. A differenza delle estensioni di elemento di progetto, le estensioni di progetto non possono essere associate a un particolare tipo di progetto SharePoint. Quando si crea un'estensione di progetto, questa viene caricata quando si apre in Visual Studio un qualsiasi tipo di progetto SharePoint.

In questa procedura dettagliata si creerà una proprietà booleana personalizzata che viene aggiunta a qualsiasi progetto SharePoint creato in Visual Studio. Quando impostata su True, la nuova proprietà aggiunge o associa al progetto una cartella di risorse denominata Images. Quando impostata su False, la cartella Images viene rimossa, se esiste. Per ulteriori informazioni, vedere Procedura: aggiungere e rimuovere cartelle mappate.

In questa procedura dettagliata vengono illustrate le attività seguenti:

  • Creazione di un'estensione di Visual Studio per progetti SharePoint che eseguono le operazioni seguenti:

    • Aggiunta di una proprietà di progetto personalizzata alla finestra Proprietà. La proprietà si applica a qualsiasi progetto SharePoint.

    • Utilizzo del modello a oggetti del progetto SharePoint per aggiungere a un progetto una cartella mappata.

    • Utilizzo del modello a oggetti di automazione di Visual Studio (DTE) per eliminare una cartella mappata dal progetto.

  • Compilazione di un pacchetto Visual Studio Extension (VSIX) per l'assembly dell'estensione della proprietà di progetto.

  • Debug e test della proprietà di progetto.

Prerequisiti

Per completare la procedura dettagliata, nel computer di sviluppo devono essere presenti i componenti elencati di seguito:

Creazione dei progetti

Per completare questa procedura dettagliata è necessario creare due progetti:

  • Un progetto VSIX per creare il pacchetto VSIX allo scopo di distribuire l'estensione di progetto.

  • Un progetto Libreria di classi che implementa l'estensione di progetto.

Iniziare la procedura dettagliata creando i progetti.

Per creare il progetto VSIX

  1. Avviare Visual Studio.

  2. Scegliere Nuovo dal menu File, quindi fare clic su Progetto.

  3. Nella finestra di dialogo Nuovo progetto espandere i nodi Visual C# o Visual Basic, quindi fare clic sul nodo Extensibility.

    Nota

    Il nodo Extensibility è disponibile solo se si installa Visual Studio 2010 SDK. Per ulteriori informazioni, vedere la sezione precedente relativa ai prerequisiti.

  4. Selezionare .NET Framework 4 dalla casella combinata nella parte superiore della finestra di dialogo. Le estensioni degli strumenti di SharePoint richiedono alcune funzionalità di questa versione di .NET Framework.

  5. Scegliere il modello VSIX Project.

  6. Nella casella Nome digitare ProjectExtensionPackage.

  7. Scegliere OK.

    Visual Studio aggiunge il progetto ProjectExtensionPackage a Esplora soluzioni.

Per creare il progetto di estensione

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul nodo della soluzione, scegliere Aggiungi, quindi Nuovo progetto.

    Nota

    Nei progetti Visual Basic, il nodo della soluzione viene visualizzato in Esplora soluzioni solo quando la casella di controllo Mostra sempre soluzione è selezionata in Finestra di dialogo Opzioni, Progetti e soluzioni, Generale.

  2. Nella finestra di dialogo Nuovo progetto espandere i nodi Visual C# o Visual Basic, quindi fare clic su Windows.

  3. Selezionare .NET Framework 4 dalla casella combinata nella parte superiore della finestra di dialogo.

  4. Selezionare il modello di progetto Libreria di classi.

  5. Nella casella Nome digitare ProjectExtension.

  6. Scegliere OK.

    Visual Studio aggiunge il progetto ProjectExtension alla soluzione e apre il file di codice predefinito Class1.

  7. Eliminare il file di codice Class1 dal progetto.

Configurazione del progetto

Prima di scrivere il codice per creare l'estensione di progetto, aggiungere al progetto di estensione file di codice e riferimenti all'assembly.

Per configurare il progetto

  1. Aggiungere al progetto ProjectExtension un nuovo file di codice denominato CustomProperty.

  2. Scegliere Aggiungi riferimento dal menu Progetto.

  3. Nella scheda .NET premere CTRL, fare clic sugli assembly seguenti e quindi su OK:

    • Microsoft.VisualStudio.SharePoint

    • System.ComponentModel.Composition

    • System.Windows.Forms

    • EnvDTE

  4. In Esplora soluzioni, nella cartella Riferimenti per il progetto ProjectExtension, scegliere EnvDTE.

  5. Nella finestra Proprietà, modificare la proprietà Incorpora tipi di interoperabilità in False.

Definizione della nuova proprietà di progetto SharePoint

Creare una classe che definisce l'estensione di progetto e il comportamento della nuova proprietà di progetto. Per definire la nuova estensione di progetto, la classe implementa l'interfaccia ISharePointProjectExtension. Implementare questa interfaccia ogni volta che si desidera definire un'estensione di un progetto SharePoint. Inoltre, aggiungere l'oggetto ExportAttribute alla classe. Questo attributo consente a Visual Studio di individuare e caricare l'implementazione di ISharePointProjectExtension. Passare il tipo ISharePointProjectExtension al costruttore dell'attributo.

Per definire la nuova proprietà di progetto SharePoint

  1. Se non è già aperto, fare doppio clic sul file di codice CustomProperty per modificarlo.

  2. Incollare il codice riportato di seguito nel file.

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

Compilazione della soluzione

A questo punto occorre compilare la soluzione per garantire che non vi siano errori di compilazione.

Per compilare la soluzione

  • Scegliere Compila soluzione dal menu Compila.

Creazione di un pacchetto VSIX per distribuire l'estensione della proprietà di progetto

Per distribuire l'estensione di progetto, utilizzare il progetto VSIX nella soluzione per creare un pacchetto VSIX. Anzitutto, configurare il pacchetto VSIX modificando il file source.extension.vsixmanifest incluso nel progetto VSIX. Quindi, creare il pacchetto VSIX compilando la soluzione.

Per configurare e creare il pacchetto VSIX

  1. In Esplora soluzioni fare doppio clic sul file source.vsixmanifest.

    In Visual Studio si apre il file nell'editor del manifesto. Questo editor fornisce un oggetto UI che può essere utilizzato per modificare l'oggetto XML nel manifesto. Queste informazioni vengono visualizzate in seguito in Gestione estensioni. Il file extension.vsixmanifest è richiesto da tutti i pacchetti VSIX. Per ulteriori informazioni su questo file, vedere VSIX Extension Schema Reference.

  2. Nella casella Nome prodotto digitare Custom Project Property.

  3. Nella casella Autore digitare Contoso.

  4. Nella casella Descrizione, digitare Proprietà di progetto SharePoint personalizzata che attiva o disattiva il mapping della cartella di risorse Images al progetto.

  5. Nella sezione Contenuto dell'editor, fare clic sul pulsante Aggiungi contenuto.

  6. Nella casella di riepilogo Seleziona un tipo di contenuto, selezionare Componente MEF.

    Nota

    Questo valore corrisponde all'elemento MEFComponent del file extension.vsixmanifest. Questo elemento specifica il nome di un assembly dell'estensione nel pacchetto VSIX. Per ulteriori informazioni, vedere MEFComponent Element (VSX Schema).

  7. Nella sezione Seleziona un'origine, fare clic sull'opzione Progetto. Quindi, selezionare ProjextExtension nella casella di riepilogo.

    Questo valore identifica il nome dell'assembly in corso di compilazione nel progetto.

  8. Al termine, scegliere OK per chiudere la finestra di dialogo Aggiungi contenuto.

  9. Al termine, fare clic su Salva tutto nel menu File, quindi chiudere la finestra di progettazione del manifesto.

  10. Scegliere Compila soluzione dal menu Compila. Assicurarsi che il progetto venga compilato correttamente.

  11. Selezionare il progetto ProjectExtensionPackage in Esplora soluzioni, fare clic sul pulsante Mostra tutti i file, quindi aprire la cartella dell'output di compilazione del progetto ProjectExtensionPackage. A questo punto questa cartella deve contenere un file denominato ProjectExtensionPackage.vsix.

    Per impostazione predefinita, la cartella dell'output di compilazione è .. \bin\Debug sotto la cartella che contiene il file di progetto.

Test della proprietà di progetto

È ora possibile testare la proprietà di progetto personalizzata. Il modo più semplice per eseguire il debug e il test della nuova estensione di proprietà di progetto è eseguirli in un'istanza sperimentale di Visual Studio. Si tratta dell'istanza di Visual Studio creata quando si esegue un VSIX o un progetto di estensibilità di altro tipo. Dopo il debug del progetto è possibile installare l'estensione nel sistema e quindi continuare a eseguirne il debug e il test in un'istanza normale di Visual Studio.

Per eseguire il debug e il test dell'estensione in un'istanza sperimentale di Visual Studio

  1. Riavviare Visual Studio con le credenziali amministrative e aprire la soluzione ProjectExtensionPackage.

  2. Premere F5 per avviare una compilazione di debug del progetto.

    Visual Studio installa l'estensione in %UserProfile%\Dati applicazione\Locale\Microsoft\VisualStudio\10.0Exp\Extensions\Contoso\Custom Project Property\1.0 e avvia un'istanza sperimentale di Visual Studio.

  3. Nell'istanza sperimentale di Visual Studio creare un nuovo progetto soluzione farm SharePoint, ad esempio un modulo. Utilizzare i valori predefiniti per gli altri valori nella procedura guidata.

  4. Fare clic sul nodo di progetto in Esplora soluzioni.

    Una nuova proprietà personalizzata denominata Map Images Folder verrà visualizzata nella finestra Proprietà con il valore predefinito False.

  5. Impostare Map Images Folder su True.

    Una cartella di risorse denominata Images verrà aggiunta al progetto SharePoint.

  6. Impostare Map Images Folder su False.

    La cartella di risorse Images verrà eliminata dal progetto SharePoint.

  7. Chiudere l'istanza sperimentale di Visual Studio.

Vedere anche

Altre risorse

Estensione di progetti SharePoint

Procedura: aggiungere una proprietà ai progetti SharePoint

Conversione tra tipi di sistemi di progetto SharePoint e altri tipi di progetto Visual Studio

Salvataggio dei dati nelle estensioni del sistema di progetto SharePoint

Associazione di dati personalizzati alle estensioni degli strumenti di SharePoint