Exemplarische Vorgehensweise: Erstellen einer SharePoint-Projekterweiterung

Diese exemplarische Vorgehensweise veranschaulicht, wie eine Erweiterung für ein SharePoint-Projekt erstellt wird. Sie können mithilfe einer Projekterweiterung auf Ereignisse auf Projektebene reagieren, z. B. wenn ein Projekt hinzugefügt, gelöscht oder sein Name geändert wird. Sie können auch benutzerdefinierte Eigenschaften hinzufügen oder auf die Änderung eines Eigenschaftswerts reagieren. Im Gegensatz zu Projektelementerweiterungen können Projekterweiterungen einem bestimmten SharePoint-Projekttyp nicht zugeordnet werden. Wenn Sie eine Projekterweiterung erstellen, wird die Erweiterung bei jedem Öffnen eines SharePoint-Projekts in Visual Studio geladen.

In dieser exemplarischen Vorgehensweise erstellen wir eine benutzerdefinierte boolesche Eigenschaft, die jedem in Visual Studio erstellten SharePoint-Projekt hinzugefügt wird. Bei der Festlegung auf True wird dem Projekt von der neuen Eigenschaft ein Ressourcenordner für Bilder hinzugefügt oder zugewiesen. Bei der Festlegung auf False wird der Bilderordner ggf. entfernt. Weitere Informationen erhalten Sie unter Gewusst wie: Hinzufügen und Entfernen zugeordneter Ordner.

Diese exemplarische Vorgehensweise enthält die folgenden Aufgaben:

  • Erstellen einer Erweiterung Visual Studio für SharePoint-Projekte, mit der folgende Aufgaben ausgeführt werden können:

    • Hinzufügen einer benutzerdefinierten Projekteigenschaft zum Eigenschaftenfenster Die Eigenschaft gilt für jedes SharePoint-Projekt.

    • Verwenden des SharePoint-Projektobjektmodells zum Hinzufügen eines zugeordneten Ordners zu einem Projekt

    • Verwenden des Automatisierungsobjektmodells von Visual Studio zum Löschen eines zugeordneten Ordners aus dem Projekt

  • Erstellen eines Visual Studio-Erweiterungspakets (VSIX) zur Bereitstellung der Erweiterungsassembly der Projekteigenschaft

  • Debuggen und Testen der Projekteigenschaft

Vorbereitungsmaßnahmen

Zum Durchführen dieser exemplarischen Vorgehensweise werden auf dem Entwicklungscomputer die folgenden Komponenten benötigt:

Erstellen der Projekte

Zum Abschließen dieser exemplarischen Vorgehensweise müssen Sie zwei Projekte erstellen:

  • Ein VSIX-Projekt für die Erstellung des VSIX-Pakets zum Bereitstellen der Projekterweiterung.

  • Ein Klassenbibliotheksprojekt, in das die Projekterweiterung implementiert wird.

Beginnen Sie mit der exemplarischen Vorgehensweise, indem Sie beide Projekte erstellen.

So erstellen Sie das VSIX-Projekt

  1. Starten Sie Visual Studio.

  2. Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

  3. Erweitern Sie im Dialogfeld Neues Projekt den Knoten Visual C# oder Visual Basic, und klicken Sie dann auf den Knoten Erweiterungen.

    Tipp

    Der Knoten Erweiterungen ist nur verfügbar, wenn Sie Visual Studio 2010 SDK installieren. Weitere Informationen finden Sie weiter oben in diesem Thema im Abschnitt zu den erforderlichen Komponenten.

  4. Wählen Sie im Kombinationsfeld am oberen Rand des Dialogfelds .NET Framework 4 aus. SharePoint-Toolerweiterungen benötigen Funktionen dieser .NET Framework-Version.

  5. Klicken Sie auf die Vorlage VSIX Project.

  6. Geben Sie im Feld Name die Zeichenfolge ProjectExtensionPackage ein.

  7. Klicken Sie auf OK.

    Visual Studio fügt das ProjectExtensionPackage-Projekt dem Projektmappen-Explorer hinzu.

So erstellen Sie das Erweiterungsprojekt

  1. Klicken Sie mit der rechten Maustaste auf den Projektmappenknoten im Projektmappen-Explorer, klicken Sie auf Hinzufügen, und klicken Sie dann auf Neues Projekt.

    Tipp

    In Visual Basic-Projekten wird der Lösungsknoten nur imProjektmappen-Explorer angezeigt, wenn unter Allgemein, Projekte und Projektmappen, Dialogfeld "Optionen" das Kontrollkästchen Projektmappe immer anzeigen aktiviert ist.

  2. Erweitern Sie im Dialogfeld Neues Projekt den Knoten Visual C# oder Visual Basic, und klicken Sie anschließend auf Windows.

  3. Wählen Sie im Kombinationsfeld am oberen Rand des Dialogfelds die Option .NET Framework 4 aus.

  4. Wählen Sie die Projektvorlage Klassenbibliothek aus.

  5. Geben Sie im Feld Name die Zeichenfolge ProjectExtension ein.

  6. Klicken Sie auf OK.

    Visual Studio fügt das Projekt ProjectExtension zur aktuellen Projektmappe hinzu und öffnet die Class1-Codedatei.

  7. Löschen Sie die Class1-Codedatei aus dem Projekt.

Konfigurieren des Projekts

Bevor Sie Code zum Erstellen der Projekterweiterung schreiben, fügen Sie dem Erweiterungsprojekt Codedateien und Assemblyverweise hinzu.

So konfigurieren Sie das Projekt

  1. Fügen Sie dem ProjectExtension-Projekt eine neue Codedatei mit dem Namen CustomProperty hinzu.

  2. Klicken Sie im Menü Projekt auf Verweis hinzufügen.

  3. Halten Sie die STRG-Taste gedrückt, und klicken Sie auf der Registerkarte .NET auf folgende Assemblys. Klicken Sie dann auf OK.

    • Microsoft.VisualStudio.SharePoint

    • System.ComponentModel.Composition

    • System.Windows.Forms

    • EnvDTE

  4. Klicken Sie im Projektmappen-Explorer unter dem Ordner Verweise für das Projekt ProjectExtension auf EnvDTE.

  5. Ändern Sie im Fenster Eigenschaften den Wert der Eigenschaft Interoptypen einbetten in False.

Definieren der neuen SharePoint-Projekteigenschaft

Erstellen Sie eine Klasse, die die Projekterweiterung und das Verhalten der neuen Projekteigenschaft definiert. Zur Definition der neuen Projekterweiterung wird von der Klasse die ISharePointProjectExtension-Schnittstelle implementiert. Implementieren Sie diese Schnittstelle, wenn Sie eine Erweiterung für ein SharePoint-Projekt erstellen möchten. Fügen Sie der Klasse auch ExportAttribute hinzu. Anhand dieses Attributs kann Visual Studio die ISharePointProjectExtension-Implementierung erkennen und laden. Übergeben Sie den ISharePointProjectExtension-Typ an den Konstruktor des Attributs.

So definieren Sie die neue SharePoint-Projekteigenschaft

  1. Doppelklicken Sie auf die CustomProperty-Codedatei, um sie zu bearbeiten, sofern sie noch nicht geöffnet ist.

  2. Fügen Sie folgenden Code in die Datei ein.

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

Erstellen der Lösung

Erstellen Sie als Nächstes die Lösung, um sicherzustellen, dass sie ohne Fehler kompiliert wird.

So erstellen Sie die Projektmappe

  • Klicken Sie im Menü Erstellen auf Projektmappe erstellen.

Erstellen eines VSIX-Pakets zur Bereitstellung der Projekteigenschaftenerweiterung

Zur Bereitstellung der Projekterweiterung verwenden Sie das VSIX-Projekt in der Lösung, um ein VSIX-Paket zu erstellen. Konfigurieren Sie zuerst das VSIX-Paket, indem Sie die im VSIX-Projekt enthaltene Datei "source.extension.vsixmanifest" ändern. Erstellen Sie anschließend das VSIX-Paket, indem Sie die Lösung erstellen.

So erstellen und konfigurieren Sie das VSIX-Paket

  1. Doppelklicken Sie im Projektmappen-Explorer auf die Datei source.extension.vsixmanifest.

    Visual Studio öffnet die Datei im Manifest-Editor. Dieser Editor stellt eine UI zum Bearbeiten des XML im Manifest zur Verfügung. Diese Informationen werden später im Erweiterungs-Manager angezeigt. Die Datei "extension.vsixmanifest" ist für alle VSIX-Pakete erforderlich. Weitere Informationen zu dieser Datei finden Sie unter VSIX Extension Schema Reference.

  2. Geben Sie im Feld Produktname die Zeichenfolge Custom Project Property ein.

  3. Geben Sie im Feld Autor den Namen Contoso ein.

  4. Geben Sie im Feld Beschreibung Folgendes ein: Eine benutzerdefinierte SharePoint-Projekteigenschaft zur Zuordnung des Ressourcenordners für Bilder zum Projekt.

  5. Klicken Sie im Abschnitt Inhalt des Editors auf die Schaltfläche Inhalte hinzufügen.

  6. Wählen Sie im Dropdownfeld zum Auswählen eines Inhaltstyps MEF-Komponente aus.

    Tipp

    Dieser Wert entspricht dem MEFComponent-Element in der Datei "extension.vsixmanifest". Dieses Element gibt den Namen einer Erweiterungsassembly im VSIX-Paket an. Weitere Informationen erhalten Sie unter MEFComponent Element (VSX Schema).

  7. Klicken Sie im Abschnitt zur Auswahl einer Quelle auf die Option Projekt, wählen Sie dann im Dropdownfeld ProjextExtension aus.

    Dieser Wert bestimmt den Namen der Assembly, die Sie in das Projekt integrieren.

  8. Klicken Sie anschließend auf OK, um das Dialogfeld Inhalte hinzufügen zu schließen.

  9. Klicken Sie anschließend im Menü Datei auf Alle speichern, und schließen Sie dann den Manifest-Designer.

  10. Klicken Sie im Menü Erstellen auf Projektmappe erstellen. Stellen Sie sicher, dass das Projekt fehlerfrei kompiliert werden kann.

  11. Klicken Sie im Projektmappen-Explorer auf das ProjectExtensionPackage-Projekt, klicken Sie auf die Schaltfläche Alle Dateien anzeigen, und öffnen Sie dann den Buildausgabeordner für das ProjectExtensionPackage-Projekt. Dieser Ordner sollte jetzt die Datei "ProjectExtensionPackage.vsix" enthalten.

    Standardmäßig ist der Buildausgabeordner der Ordner "\bin\Debug" im Ordner mit der Projektdatei.

Testen der Projekteigenschaft

Sie können jetzt die benutzerdefinierte Projekteigenschaft testen. Das Debuggen und Testen der neuen Projekteigenschaftenerweiterung gestaltet sich am einfachsten in einer experimentellen Instanz von Visual Studio. Dies ist die Instanz von Visual Studio, die bei der Ausführung eines VSIX-Projekts oder eines anderen Erweiterungsprojekts erstellt wird. Nach dem Debuggen des Projekts können Sie die Erweiterung auf dem System installieren und in einer regulären Instanz von Visual Studio mit dem Debuggen und Testen fortfahren.

So debuggen und testen Sie die Erweiterung in einer experimentellen Instanz von Visual Studio

  1. Starten Sie Visual Studio neu mit Administratorrechten, und öffnen Sie die Lösung "ProjectExtensionPackage".

  2. Drücken Sie F5, um einen Debugbuild vom Projekt zu starten.

    Visual Studio installiert die Erweiterung in "%UserProfile%\AppData\Local\Microsoft\VisualStudio\10.0Exp\Extensions\Contoso\Custom Project Property\1.0" und startet eine experimentelle Instanz von Visual Studio.

  3. Erstellen Sie in der experimentellen Instanz von Visual Studio ein neues SharePoint-Projekt für eine Farmlösung, z. B. ein Modul. Übernehmen Sie für die übrigen Werte im Assistenten die Standardwerte.

  4. Klicken Sie im Projektmappen-Explorer auf den Projektknoten.

    Ein neue benutzerdefinierte Eigenschaft zur Zuweisung des Bilderordners wird im Fenster Eigenschaften mit dem Standardwert False angezeigt.

  5. Ändern Sie den Wert für die Eigenschaft zum Zuweisen des Bilderordners in True.

    Dem SharePoint-Projekt wird ein Ressourcenordner für Bilder hinzugefügt.

  6. Ändern Sie den Wert für die Eigenschaft zum Zuweisen des Bilderordners in False um.

    Der Ressourcenordner für Bilder wird aus dem SharePoint-Projekt gelöscht.

  7. Schließen Sie die experimentelle Instanz von Visual Studio.

Siehe auch

Weitere Ressourcen

Erweitern von SharePoint-Projekten

Gewusst wie: Hinzufügen einer Eigenschaft zu SharePoint-Projekten

Konvertieren zwischen SharePoint-Projektsystemtypen und anderen Visual Studio-Projekttypen

Speichern von Daten in Erweiterungen des SharePoint-Projektsystems

Zuordnen von benutzerdefinierten Daten zu SharePoint-Tools-Erweiterungen