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:
Unterstützte Editionen von Microsoft Windows, SharePoint und Visual Studio. Weitere Informationen finden Sie unter Anforderungen für die Entwicklung von SharePoint-Lösungen.
Visual Studio 2010 SDK. In dieser exemplarischen Vorgehensweise wird die Vorlage VSIX Project im SDK verwendet, um ein VSIX-Paket zur Bereitstellung der Projekteigenschaftenerweiterung zu erstellen. Weitere Informationen erhalten Sie unter Erweitern der SharePoint-Tools in Visual Studio.
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
Starten Sie Visual Studio.
Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.
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.
Wählen Sie im Kombinationsfeld am oberen Rand des Dialogfelds .NET Framework 4 aus. SharePoint-Toolerweiterungen benötigen Funktionen dieser .NET Framework-Version.
Klicken Sie auf die Vorlage VSIX Project.
Geben Sie im Feld Name die Zeichenfolge ProjectExtensionPackage ein.
Klicken Sie auf OK.
Visual Studio fügt das ProjectExtensionPackage-Projekt dem Projektmappen-Explorer hinzu.
So erstellen Sie das Erweiterungsprojekt
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.
Erweitern Sie im Dialogfeld Neues Projekt den Knoten Visual C# oder Visual Basic, und klicken Sie anschließend auf Windows.
Wählen Sie im Kombinationsfeld am oberen Rand des Dialogfelds die Option .NET Framework 4 aus.
Wählen Sie die Projektvorlage Klassenbibliothek aus.
Geben Sie im Feld Name die Zeichenfolge ProjectExtension ein.
Klicken Sie auf OK.
Visual Studio fügt das Projekt ProjectExtension zur aktuellen Projektmappe hinzu und öffnet die Class1-Codedatei.
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
Fügen Sie dem ProjectExtension-Projekt eine neue Codedatei mit dem Namen CustomProperty hinzu.
Klicken Sie im Menü Projekt auf Verweis hinzufügen.
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
Klicken Sie im Projektmappen-Explorer unter dem Ordner Verweise für das Projekt ProjectExtension auf EnvDTE.
Ä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
Doppelklicken Sie auf die CustomProperty-Codedatei, um sie zu bearbeiten, sofern sie noch nicht geöffnet ist.
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
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.
Geben Sie im Feld Produktname die Zeichenfolge Custom Project Property ein.
Geben Sie im Feld Autor den Namen Contoso ein.
Geben Sie im Feld Beschreibung Folgendes ein: Eine benutzerdefinierte SharePoint-Projekteigenschaft zur Zuordnung des Ressourcenordners für Bilder zum Projekt.
Klicken Sie im Abschnitt Inhalt des Editors auf die Schaltfläche Inhalte hinzufügen.
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).
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.
Klicken Sie anschließend auf OK, um das Dialogfeld Inhalte hinzufügen zu schließen.
Klicken Sie anschließend im Menü Datei auf Alle speichern, und schließen Sie dann den Manifest-Designer.
Klicken Sie im Menü Erstellen auf Projektmappe erstellen. Stellen Sie sicher, dass das Projekt fehlerfrei kompiliert werden kann.
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
Starten Sie Visual Studio neu mit Administratorrechten, und öffnen Sie die Lösung "ProjectExtensionPackage".
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.
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.
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.
Ä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.
Ä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.
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