Поделиться через


Пошаговое руководство. Создание расширения проекта SharePoint

В этом пошаговом руководстве иллюстрируется создание расширения для проектов SharePoint.Расширение проекта можно использовать для реагирования на события проект- уровня например, если добавление, удаление и переименование проекта.Кроме того, при изменении значения свойства можно добавить настраиваемые свойства или выполнить определенные действия.В отличие от расширений элемента проекта, расширения проекта нельзя связать с определенный типом проекта SharePoint.При создании расширения проекта это расширение загружается при открытии любого проекта SharePoint в Visual Studio.

В этом пошаговом руководстве будет создано настраиваемое свойство логического типа, добавляемое ко всем проектам SharePoint, создаваемым в Visual Studio.Если для него задано значение True, новое свойство добавляет в проект или сопоставляет с ним папку ресурсов "Изображения".Если для него задано значение False, папка "Изображения" удаляется, если она существует.Дополнительные сведения см. в разделе Практическое руководство. Добавление и удаление сопоставленных папок.

В этом пошаговом руководстве показано выполнение следующих задач.

  • Создание расширения Visual Studio для проектов SharePoint, которое выполняет следующие действия.

    • Добавляет настраиваемое свойство проекта в окно "Свойства".Это свойство применяется к любым проектам SharePoint.

    • Использует объектную модель проекта SharePoint для добавления в проект сопоставленной папки.

    • Использует объектную модель автоматизации Visual Studio (DTE) для удаления сопоставленной папки из проекта.

  • Построение пакета расширения Visual Studio (VSIX) для развертывания сборки расширения свойств проекта.

  • Отладка и тестирование свойства проекта.

Обязательные компоненты

Для выполнения данного пошагового руководства на компьютере разработчика должны быть установлены следующие компоненты:

  • Поддерживаемые выпуски Microsoft Windows, SharePoint и Visual Studio.Дополнительные сведения см. в разделе Требования по разработке решений SharePoint.

  • SDK для Visual Studio.В этом пошаговом руководстве шаблон Проект VSIX (Пакет SDK) используется для создания пакета VSIX, который служит для развертывания расширения свойства проекта.Дополнительные сведения см. в разделе Расширение средств SharePoint в Visual Studio.

Создание проектов

Чтобы выполнить это пошаговое руководство, необходимо создать два проекта:

  • проект VSIX для создания пакета VSIX с целью развертывания расширения проекта;

  • проект библиотеки классов, реализующей расширение проекта.

Начните выполнение пошагового руководства с создания проектов.

Создание проекта VSIX

  1. Запустите Visual Studio.

  2. В строке меню выберите Файл, Создать, Проект.

  3. В диалоговом окне Создать проект разверните узлы Visual C# или Visual Basic, а затем выберите узел Расширение среды.

    ПримечаниеПримечание

    Этот узел доступен, только если установить пакет SDK для Visual Studio.Дополнительные сведения см. в параграфе предварительных требований ранее в этом разделе.

  4. В верхней части диалогового окна, выберите платформа .NET Framework 4,5 в списке версий платформы .NET Framework, а затем выберите шаблон Проект VSIX.

  5. В окне Имя, вставки ProjectExtensionPackage, а затем кнопку ОК.

    Проект ProjectExtensionPackage отображается в Обозреватель решений.

Создание проекта расширения

  1. В Обозреватель решений открыть контекстное меню для узла решения выберите Добавить, а затем выберите Создать проект.

    ПримечаниеПримечание

    В проектах Visual Basic узел решения отображается в Обозреватель решений, только если флажок Всегда показывать решение выбрать в General, Projects and Solutions, Options Dialog Box.

  2. В диалоговом окне Создать проект разверните узлы Visual C# или Visual Basic, а затем выберите Окна.

  3. В верхней части диалогового окна, выберите платформа .NET Framework 4,5 в списке версий платформы .NET Framework, а затем выберите шаблон проекта Библиотека классов.

  4. В окне Имя, вставки ProjectExtension, а затем кнопку ОК.

    Visual Studio добавит проект Расширение_проекта в решение и откроет заданный по умолчанию файл с кодом Class1.

  5. Удалите из проекта файл c кодом Class1.

Настройка проекта

Перед разработкой кода для создания расширения проекта добавьте в проект расширения ссылки на файлы с кодом и ссылки на сборки.

Настройка проекта

  1. Добавьте файл кода с именем CustomProperty в проект ProjectExtension.

  2. Открыть контекстное меню для проекта ProjectExtension, а затем выберите Добавить ссылку.

  3. В диалоговом окне Диспетчер ссылок – CustomProperty выберите узел Платформа, а затем установите флажок рядом с сборками и System.Windows.Forms System.ComponentModel.Composition.

  4. Выберите узел Расширения установите флажок рядом с сборками Microsoft.VisualStudio.SharePoint и EnvDTE, а затем нажмите кнопку ОК.

  5. В Обозреватель решений в папке Ссылки для проекта ProjectExtension выберите EnvDTE.

  6. В окне Свойства измените значение свойства Внедрить типы взаимодействия на False.

Определение нового свойства проекта SharePoint

Создайте класс, определяющий расширение проекта и поведение нового свойства проекта.Для определения нового расширения проекта класс реализует интерфейс ISharePointProjectExtension.Этот интерфейс следует реализовывать при каждом определении расширения для проекта SharePoint.Кроме того, следует добавить к классу атрибут ExportAttribute.Данный атрибут позволяет приложению Visual Studio находить и загружать пользовательскую реализацию ISharePointProjectExtension.Передайте конструктору этого атрибута тип ISharePointProjectExtension.

Определение нового свойства проекта SharePoint

  • Вставьте следующий код в файл кода CustomProperty.

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

Построение решения

Далее нужно построить решение, чтобы убедиться в отсутствии ошибок при его компиляции.

Построение решения

  • В строке меню выберите Построение, Построить решение.

Создание пакета VSIX для развертывания расширения свойства проекта

Для развертывания расширения проекта воспользуйтесь проектом VSIX в своем решении для создания пакета VSIX.Сначала настройте пакет VSIX, изменив содержимое файла source.extension.vsixmanifest, входящего в состав проекта VSIX.Затем создайте пакет VSIX, выполнив построение решения.

Настройка и создание пакета VSIX

  1. В Обозреватель решений открыть контекстное меню для файла source.extension.vsixmanifest, а затем нажмите кнопку Открыть.

    Visual Studio открывает файл в конструкторе манифестов.Сведения, которые отображаются на вкладке Метаданные также отображается в Расширения и обновления. Все пакеты VSIX, необходим файл extension.vsixmanifest.Дополнительные сведения об этом файле см. в разделе Справочник по схеме расширения VSIX.

  2. В окне Название продукта введите Пользовательское свойство проекта.

  3. В окне Автор введите Contoso.

  4. В окне Описание введите Пользовательское свойство проекта SharePoint, которое переключает сопоставление папки ресурсов изображений в проект.

  5. Выберите вкладку Активы, а затем нажмите кнопку Создать.

    Диалоговое окно Добавить новый актив.

  6. В списке Тип выберите Microsoft.VisualStudio.MefComponent.

    ПримечаниеПримечание

    Это значение соответствует элементу MEFComponent, описанному в файле extension.vsixmanifest.Этот элемент задает имя сборки расширения в пакете VSIX.Дополнительные сведения см. в разделе MEFComponent Element.

  7. В списке Источник выберите переключатель Проект в текущем решении.

  8. В списке Проект выберите ProjectExtension.

    Это значение указывает имя сборки, что построении проекта.

  9. Выберите ОК, чтобы закрыть диалоговое окно Добавить новый актив.

  10. В строке меню выберите Файл, Сохранить все завершив, а затем закройте конструктор манифеста.

  11. В строке меню выберите Построение, Построить решение и убедитесь, что проект будет компилироваться без ошибок.

  12. В Обозреватель решений открыть контекстное меню для проекта ProjectExtensionPackage и нажмите кнопку Открыть папку в проводнике.

  13. В Проводник, откройте выходную папку построения для проекта ProjectExtensionPackage, а затем проверьте, что папка содержит файл с именем ProjectExtensionPackage.vsix.

    По умолчанию выходной папкой построения является папка ..\bin\Debug, расположенная в папке, содержащей файл проекта.

Проверка свойства проекта

Теперь можно проверить пользовательское свойство проекта.Проще всего отладка и тестирование нового расширения свойства проекта в экспериментальном экземпляре Visual Studio.Этот экземпляр Visual Studio созданы при запуске VSIX или другого проекта расширяемости.После отладки проекта можно задать расширения в системе, а затем продолжить отладку и протестировать его в обычном экземпляре Visual Studio.

Отладка и тестирование расширения в экспериментальном экземпляре Visual Studio

  1. Перезапустите Visual Studio с учетными данными администратора, а затем откройте решение ProjectExtensionPackage.

  2. Начните построение отладки проекта, то путем выбора ключа F5 либо в строке меню, при выборе Отладка, Начать отладку.

    Visual Studio установит расширения до %UserProfile% \ AppData \ local \ Microsoft \ VisualStudio \ 11.0Exp \ extensions \ Contoso \ пользовательское свойство проекта \ 1.0 и запускает экспериментальном экземпляре Visual Studio.

  3. В экспериментальном экземпляре Visual Studio создайте проект SharePoint для решения фермы и используйте значения по умолчанию для остальных значений в мастере.

    1. В строке меню выберите Файл, Создать, Проект.

    2. В верхней части диалогового окна Создать проект выберите .NET Framework 3.5 в списке версий платформы .NET Framework.

      Расширения средств SharePoint требуют функций в этой версии .NET Framework.

    3. В узле Шаблоны разверните узел Visual C# или Visual Basic выберите узел SharePoint, а затем выберите узел 2010.

    4. Выберите шаблон Проект SharePoint 2010, а затем введите в качестве имени проекта ModuleTest.

  4. В Обозреватель решений выберите узел проекта ModuleTest.

    В окне Свойства отобразится новое настраиваемое свойство Сопоставить папку изображений со значением по умолчанию False.

  5. Измените значение свойства в True.

    В проект SharePoint будет добавлена папка ресурсов "Изображения".

  6. Измените значение свойства обратно в False.

    Если выбрана кнопка Да в диалоговом окне Удалите папку образов?, то в папке ресурсов изображений удаляется из проекта SharePoint.

  7. Закройте экспериментальный экземпляр Visual Studio.

См. также

Основные понятия

Расширение проектов SharePoint

Практическое руководство. Добавление свойства в проекты SharePoint

Преобразование между типами системы проектов SharePoint и другими типами проектов Visual Studio

Сохранение данных в расширениях системы проектов SharePoint

Связь пользовательских данных с расширениями средств SharePoint