Partilhar via


Passo a passo: Criando um Item de projeto de coluna do Site com um modelo de projeto, parte 2

Após você definir um tipo personalizado de item de projeto do SharePoint e o associa com um modelo de projeto no Visual Studio, também convém fornecer um assistente para o modelo.Você pode usar o assistente para coletar informações de usuários quando usam o modelo para criar um novo projeto que contém o item de projeto.Informações que você reunir pode ser usada para inicializar o item de projeto.

Em essa explicação passo a passo, você adicionará um assistente para o modelo de projeto de coluna de site que é demonstrado em Passo a passo: Criando um Item de projeto de coluna do Site com um modelo de projeto, parte 1.Quando um usuário cria um projeto da coluna da página, o assistente coleta informações sobre a coluna do site (como seu tipo base e grupo) e adiciona essa informação para o arquivo de Elements.xml no novo projeto.

Essa explicação passo a passo demonstra as seguintes tarefas:

  • Criando um assistente personalizado para o SharePoint projeta o tipo de item que está associado com um modelo de projeto.

  • Definir um assistente interface do usuário personalizada que se assemelha aos assistentes internas para o SharePoint projetos no Visual Studio.

  • Criando dois comandos do SharePoint que são usados para chamar no site do SharePoint local quando o assistente executar.Os comandos do SharePoint são métodos que podem ser usados por extensões do Visual Studio para chamar APIs no modelo de objeto de servidor do SharePoint.Para obter mais informações, consulte A chamada para os modelos de objeto do SharePoint.

  • Usando parâmetros substituível para inicializar arquivos de projeto do SharePoint com dados que você reunir no assistente.

  • Criando um novo arquivo .snk em cada nova instância de projeto da coluna do site.Este arquivo é usado para assinar a saída do projeto para que o assembly de solução do SharePoint pode ser implantado na cache global de assemblies.

  • Depuração e teste o assistente.

ObservaçãoObservação

Você pode baixar um exemplo que contém os projetos terminado, o código, e outros arquivos para essa explicação passo a passo de seguinte local: https://go.microsoft.com/fwlink/?LinkId=191369.

Pré-requisitos

Para executar esta explicação passo a passo, você deve primeiro criar a solução de SiteColumnProjectItem completando Passo a passo: Criando um Item de projeto de coluna do Site com um modelo de projeto, parte 1.

Você também precisa dos seguintes componentes no computador de desenvolvimento de concluir este explicação passo a passo:

Conhecer os seguintes conceitos é útil, mas não necessário, concluir a explicação passo a passo:

Entendendo os componentes do assistente

O assistente que é demonstrado em este passo-a-passo contém vários componentes.A tabela a seguir descreve esses componentes.

Componente

Descrição

Implementação do assistente

Esta é uma classe, SiteColumnProjectWizardchamado, que implementa a interface de IWizard .Essa interface define métodos que o Visual Studio chama quando o assistente inicia e terminar, e por vezes quando o assistente executar.

Assistente interface de usuário

Esta é uma janela com base WPF-, WizardWindowchamado.Esta janela inclui dois controles de usuário, Page1 chamado e Page2.Esses controles de usuário representam as duas páginas do assistente.

Em este passo-a-passo, o método de RunStarted da implementação do assistente exibe o assistente interface do usuário.

Modelo de dados do assistente

Esta é uma classe intermediária, SiteColumnWizardModeldenominado, que fornece uma camada entre o assistente interface do usuário e a implementação do assistente.Este exemplo usa esta classe para o sumário a implementação do assistente e o assistente interface do usuário de se; esta classe não é necessário um componente de todos os assistentes.

Em este passo-a-passo, a implementação do assistente passa um objeto de SiteColumnWizardModel para a janela do assistente exibe quando o assistente interface do usuário.O assistente interface de usuário usa métodos de esse objeto para salvar os valores dos controles na interface do usuário, e para executar tarefas como verificar que a URL do site de entrada é válida.Após o usuário concluir o assistente, a implementação do assistente usa o objeto de SiteColumnWizardModel para determinar o estado final de interface do usuário.

projeto que assina o gerenciador

Esta é uma classe auxiliar, ProjectSigningManagerchamado, que é usada pela implementação do assistente para criar um novo arquivo de key.snk em cada nova instância do projeto.

Comandos do SharePoint

Esses são métodos que são usados pelo modelo de dados do assistente para chamar no site do SharePoint local quando o assistente executar.Porque os comandos do SharePoint devem direcionar o .NET Framework 3,5, esses comandos são implementados em um conjunto diferente do restante do código do assistente.

Criando projetos

Para concluir esta explicação passo a passo, você precisa adicionar vários projetos na solução de SiteColumnProjectItem que você criou em Passo a passo: Criando um Item de projeto de coluna do Site com um modelo de projeto, parte 1:

  • Um projeto WPF.Você irá implementar a interface de IWizard e o assistente interface do usuário no projeto.

  • Um projeto de biblioteca de classe que define o SharePoint de comandos.Este projeto deve selecionar a estrutura do .NET framework 3,5.

Inicie o passo-a-passo criando projetos.

Para criar o projeto WPF

  1. Em Visual Studio, abra a solução de SiteColumnProjectItem.

  2. Em Gerenciador de Soluções, abra o menu de atalho para o nó da solução de SiteColumnProjectItemAdicionar, escolha, e escolha Novo Projeto.

    ObservaçãoObservação

    Em projetos Visual Basic, o nó da solução aparece somente quando a caixa de seleção de Sempre mostrar solução está selecionada em General, Projects and Solutions, Options Dialog Box.

  3. Em a parte superior da caixa de diálogo de Adicionar novo projeto , certifique-se de que o .NET Framework 4,5 é escolhido na lista de versões do .NET Framework.

  4. Expanda o nó de Visual C# ou o nó de Visual Basic , e escolha o nó de Janelas .

  5. Em a lista de modelos de projeto, escolha Biblioteca de Controle de Usuário do WPF, nomeie o projeto ProjectTemplateWizard, e então escolha o botão de OK .

    Visual Studio adiciona o projeto de ProjectTemplateWizard a solução e abre o arquivo padrão de UserControl1.xaml.

  6. Excluir o arquivo UserControl1.xaml do projeto.

Para criar o projeto dos comandos do SharePoint

  1. Em Gerenciador de Soluções, abra o menu de atalho para o nó da solução de SiteColumnProjectItem Adicionar, escolha, e escolha Novo Projeto.

  2. Em a parte superior da caixa de diálogo de Adicionar novo projeto , escolha o .NET Framework 3,5 na lista de versões do .NET Framework.

  3. Expanda o nó de Visual C# ou o nó de Visual Basic , e então escolha o nó de Janelas .

  4. Escolha o modelo de projeto de Biblioteca de Classes , nomeie o projeto SharePointCommands, e então escolha o botão de OK .

    Visual Studio adiciona o projeto de SharePointCommands a solução e abre o arquivo de código Class1 de opção.

  5. Exclua o arquivo de código Class1 do projeto.

Configurando projetos

Antes de criar o assistente, você deve adicionar alguns arquivos de código e referências assembly para projetos.

Para configurar o projeto do assistente

  1. Em Gerenciador de Soluções, abra o menu de atalho para o nó de projeto de ProjectTemplateWizard , e então escolha Propriedades.

  2. Em Designer de Projeto, escolha a guia de Aplicativo para um projeto visual C# ou a guia de Compilar para um projeto Visual Basic.

  3. Certifique-se de que a estrutura de destino está definido no.NET Framework 4,5, não o perfil de cliente do .NET Framework 4,5.

    Para obter mais informações, consulte Como: usar uma versão do.NET Framework.

  4. Abra o menu de atalho para o projeto de ProjectTemplateWizardAdicionar, escolha, e escolha Novo Item.

  5. Escolha o item de janela (WPF) , nomeie o item WizardWindow, e então escolha o botão de Adicionar .

  6. adicionar dois itens de Controle de usuário (WPF) ao projeto, e nomeie-os Page1 e Page2.

  7. Adicione quatro arquivos de código para o projeto, e forneça aos seguintes nomes:

    • SiteColumnProjectWizard

    • SiteColumnWizardModel

    • ProjectSigningManager

    • CommandIds

  8. Abra o menu de atalho para o nó de projeto de ProjectTemplateWizard , e então escolha Adicionar Referência.

  9. Expanda o nó de Assemblies , escolha o nó de Extensões em seguida, marque as caixas de seleção ao lado dos seguintes conjuntos de módulos (assemblies):

    • EnvDTE

    • Microsoft.VisualStudio.OLE.Interop

    • Microsoft.VisualStudio.SharePoint

    • Microsoft.VisualStudio.Shell.11.0

    • Microsoft.VisualStudio.Shell.Interop.10.0

    • Microsoft.VisualStudio.Shell.Interop.11.0

    • Microsoft.VisualStudio.TemplateWizardInterface

  10. Escolha o botão de OK para adicionar conjuntos para o projeto.

  11. Em Gerenciador de Soluções, na pasta de Referências para o projeto de ProjectTemplateWizard , escolha EnvDTE.

    ObservaçãoObservação

    Em projetos Visual Basic, a pasta de Referências aparece somente quando a caixa de seleção de Sempre mostrar solução está selecionada em General, Projects and Solutions, Options Dialog Box.

  12. Em a janela de Propriedades , altere o valor da propriedade de Inserir Tipos Interop a False.

  13. Se você estiver desenvolvendo um projeto Visual Basic, importar o namespace de ProjectTemplateWizard em seu projeto usando Designer de Projeto.

    Para obter mais informações, consulte Como: Adicionar ou remover Namespaces (Visual Basic) importados.

para configurar o projeto de SharePointCommands

  1. Em Gerenciador de Soluções, escolha o nó de projeto de SharePointCommands .

  2. Em a barra de menu, escolha Projeto, Adicionar item existente.

  3. Em a caixa de diálogo de Adicionar item existente , navegue até a pasta que contém os arquivos de código para o projeto de ProjectTemplateWizard, e então escolha o arquivo de código de CommandIds .

  4. Escolha a seta ao botão de Adicionar , e escolha a opção de menu Adicionar como vínculo no qual ele aparece.

    Visual Studio adicionar o arquivo de código para o projeto de SharePointCommands como um link.O arquivo de código está localizado no projeto de ProjectTemplateWizard , mas o código no arquivo também é criado no projeto de SharePointCommands .

  5. Em o projeto de SharePointCommands , adicione outro arquivo de código que é chamado Comando.

  6. Escolha o projeto de SharePointCommands e, em seguida, na barra de menu, escolha Projeto, Adicionar Referência.

  7. Expanda o nó de Assemblies , escolha o nó de Extensões em seguida, marque as caixas de seleção ao lado dos seguintes conjuntos de módulos (assemblies):

    • Microsoft.SharePoint

    • Microsoft.VisualStudio.SharePoint.Commands

  8. Escolha o botão de OK para adicionar conjuntos para o projeto.

Criando o modelo do assistente, assinando o gerenciador, e identificações de comando do SharePoint

Adicione código para o projeto de ProjectTemplateWizard implementar os seguintes componentes no exemplo:

  • Os IDs de comando do SharePoint.Estas cadeias de caracteres que identificam o SharePoint comando do assistente.Posteriormente em esta explicação passo a passo, você adicionará código para o projeto de SharePointCommands implementar os comandos.

  • O modelo de dados do assistente.

  • o projeto que assina o gerenciador.

Para obter mais informações sobre esses componentes, consulte Entendendo os componentes do assistente.

Para definir as identificações de comando do SharePoint

  • Em o projeto de ProjectTemplateWizard, abra o arquivo de código de CommandIds e em seguida, substitua todo o conteúdo do arquivo com o código a seguir.

    Namespace Contoso.SharePoint.Commands
        Public Class CommandIds
            Public Const GetFieldTypes As String = "Contoso.Commands.GetFieldTypes"
            Public Const ValidateSite As String = "Contoso.Commands.ValidateSite"
        End Class
    End Namespace
    
    namespace Contoso.SharePoint.Commands
    {
        public static class CommandIds
        {
            public const string GetFieldTypes = "Contoso.Commands.GetFieldTypes";
            public const string ValidateSite = "Contoso.Commands.ValidateSite";
        }
    }
    

Para criar o modelo do assistente

  • Abra o arquivo de código de SiteColumnWizardModel, e substitua todo o conteúdo do arquivo com o código a seguir.

    Imports EnvDTE
    Imports Microsoft.VisualStudio.SharePoint
    Imports Microsoft.VisualStudio
    Imports Microsoft.VisualStudio.Shell
    Imports Microsoft.VisualStudio.Shell.Interop
    Imports IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider
    
    Public Class SiteColumnWizardModel
        Private dteObject As DTE
        Private projectServiceValue As ISharePointProjectService
        Private validatedUrls As New List(Of String)
    
        Friend Sub New(ByVal dteObject As DTE, ByVal requiresFarmPriveleges As Boolean)
            Me.dteObject = dteObject
    
            ' Initialize default values for wizard choices.
            IsSandboxed = Not requiresFarmPriveleges
            IsSecondPagePopulated = False
            FieldType = "Text"
            FieldGroup = "Custom Columns"
            FieldName = "My Custom Column"
            CurrentSiteUrl = GetLocalHostUrl()
        End Sub
    
    #Region "Helper methods used by the wizard UI"
    
        ' Specifies whether the current site URL is valid. Uses the ValidateSite SharePoint command to do this.
        Friend Function ValidateCurrentUrl(ByVal errorMessage As String) As Boolean
            Dim isValid As Boolean = False
            errorMessage = String.Empty
    
            If validatedUrls.Contains(CurrentSiteUrl) Then
                isValid = True
            Else
                Dim uriToValidate As Uri = New Uri(CurrentSiteUrl, UriKind.Absolute)
                Dim vsThreadedWaitDialog As IVsThreadedWaitDialog2 = Nothing
    
                Try
                    vsThreadedWaitDialog = ShowProgressDialog("Connect to SharePoint",
                        "Connecting to SharePoint site " + CurrentSiteUrl)
                    isValid = Me.ProjectService.SharePointConnection.ExecuteCommand(Of Uri, Boolean)(
                        Contoso.SharePoint.Commands.CommandIds.ValidateSite, uriToValidate)
                Catch ex As Exception
                    errorMessage = "An error occurred while validating the site. " + ex.Message
                Finally
                    If isValid Then
                        validatedUrls.Add(CurrentSiteUrl)
                    End If
                    If vsThreadedWaitDialog IsNot Nothing Then
                        CloseProgressDialog(vsThreadedWaitDialog)
                    End If
                End Try
            End If
            Return isValid
        End Function
    
        ' Gets the available field types from the SharePoint site. Uses the GetFieldTypes SharePoint command to do this.
        Friend Function GetFieldTypes() As ArrayList
            ' If we have not yet validated this site, do it now.
            Dim errorMessage As String = String.Empty
            If Not ValidateCurrentUrl(errorMessage) Then
                MessageBox.Show(String.Format("Cannot connect to the SharePoint site: {0}. {1}",
                    CurrentSiteUrl, errorMessage), "SharePoint Connection Error")
                Return Nothing
            End If
    
            ' Site is valid, so go ahead and get the available field types.
            Dim siteUri As Uri = New Uri(CurrentSiteUrl, UriKind.Absolute)
            Dim vsThreadedWaitDialog As IVsThreadedWaitDialog2 = ShowProgressDialog(
                "Connect to SharePoint", "Connecting to SharePoint site " + CurrentSiteUrl)
            Dim fieldTypesArray As String() = Me.ProjectService.SharePointConnection.ExecuteCommand(Of Uri, String())(
                Contoso.SharePoint.Commands.CommandIds.GetFieldTypes, siteUri)
    
            If vsThreadedWaitDialog IsNot Nothing Then
                CloseProgressDialog(vsThreadedWaitDialog)
            End If
    
            Return New ArrayList(fieldTypesArray)
        End Function
    
        ' Returns the default column group names in SharePoint.
        Friend Function GetFieldGroups() As List(Of String)
            Dim groups As List(Of String) = New List(Of String)()
            groups.Add("Base Columns")
            groups.Add("Core Contact and Calendar Columns")
            groups.Add("Core Document Columns")
            groups.Add("Core Task and Issue Columns")
            groups.Add("Extended Columns")
            Return groups
        End Function
    #End Region
    
    #Region "Properties shared by the wizard implementation and the wizard UI"
    
        Friend ReadOnly Property ProjectService As ISharePointProjectService
            Get
                If projectServiceValue Is Nothing Then
                    projectServiceValue = GetProjectService()
                End If
                Return projectServiceValue
            End Get
        End Property
    
        Friend Property IsSecondPagePopulated As Boolean
        Friend Property IsSandboxed As Boolean
        Friend Property FieldType As String
        Friend Property FieldGroup As String
        Friend Property FieldName As String
        Friend Property CurrentSiteUrl As String
    #End Region
    
    #Region "Private methods"
    
        Private Function GetLocalHostUrl() As String
            Const HttpScheme As String = "http"
            Dim builder As UriBuilder = New UriBuilder(HttpScheme, Environment.MachineName.ToLowerInvariant())
            Return builder.ToString()
        End Function
    
        Private Function GetProjectService() As ISharePointProjectService
            Dim serviceProvider As ServiceProvider = New ServiceProvider(CType(dteObject, IOleServiceProvider))
            Return CType(serviceProvider.GetService(GetType(ISharePointProjectService)), ISharePointProjectService)
        End Function
    
        Private Function ShowProgressDialog(ByVal caption As String, ByVal message As String) As IVsThreadedWaitDialog2
            Dim oleServiceProvider As IOleServiceProvider = CType(dteObject, IOleServiceProvider)
            Dim dialogFactory As IVsThreadedWaitDialogFactory = CType(New ServiceProvider(oleServiceProvider).GetService(
                GetType(SVsThreadedWaitDialogFactory)), IVsThreadedWaitDialogFactory)
    
            If dialogFactory Is Nothing Then
                Throw New InvalidOperationException("The IVsThreadedWaitDialogFactory object could not be retrieved.")
            End If
    
            Dim vsThreadedWaitDialog As IVsThreadedWaitDialog2 = Nothing
            ErrorHandler.ThrowOnFailure(dialogFactory.CreateInstance(vsThreadedWaitDialog))
            ErrorHandler.ThrowOnFailure(vsThreadedWaitDialog.StartWaitDialog(caption, message,
                Nothing, Nothing, String.Empty, 0, False, True))
            Return vsThreadedWaitDialog
        End Function
    
        Private Sub CloseProgressDialog(ByVal vsThreadedWaitDialog As IVsThreadedWaitDialog2)
            If vsThreadedWaitDialog Is Nothing Then
                Throw New ArgumentNullException("vsThreadedWaitDialog")
            End If
            Dim canceled As Integer
            ErrorHandler.ThrowOnFailure(vsThreadedWaitDialog.EndWaitDialog(canceled))
        End Sub
    #End Region
    End Class
    
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Windows;
    using EnvDTE;
    using Microsoft.VisualStudio.SharePoint;
    using Microsoft.VisualStudio;
    using Microsoft.VisualStudio.Shell;
    using Microsoft.VisualStudio.Shell.Interop;
    using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
    
    namespace ProjectTemplateWizard
    {
        internal class SiteColumnWizardModel
        {
            private DTE dteObject;
            private ISharePointProjectService projectServiceValue;
            private List<string> validatedUrls = new List<string>();
    
            internal SiteColumnWizardModel(DTE dteObject, bool requiresFarmPriveleges)
            {
                this.dteObject = dteObject;
    
                // Initialize default values for wizard choices.
                IsSandboxed = !requiresFarmPriveleges;
                IsSecondPagePopulated = false;
                FieldType = "Text";
                FieldGroup = "Custom Columns";
                FieldName = "My Custom Column";
                CurrentSiteUrl = GetLocalHostUrl();
            }
    
            #region Helper methods used by the wizard UI
    
            // Specifies whether the current site URL is valid. Uses the ValidateSite SharePoint command to do this.
            internal bool ValidateCurrentUrl(out string errorMessage)
            {
                bool isValid = false;
                errorMessage = String.Empty;
    
                if (validatedUrls.Contains(CurrentSiteUrl))
                {
                    isValid = true;
                }
                else
                {
                    Uri uriToValidate = new Uri(CurrentSiteUrl, UriKind.Absolute);
                    IVsThreadedWaitDialog2 vsThreadedWaitDialog = null;
    
                    try
                    {
                        vsThreadedWaitDialog = ShowProgressDialog("Connect to SharePoint",
                            "Connecting to SharePoint site " + CurrentSiteUrl);
                        isValid = this.ProjectService.SharePointConnection.ExecuteCommand<Uri, bool>(
                            Contoso.SharePoint.Commands.CommandIds.ValidateSite, uriToValidate);
                    }
                    catch (Exception ex)
                    {
                        errorMessage = "An error occurred while validating the site. " + ex.Message;
                    }
                    finally
                    {
                        if (isValid)
                        {
                            validatedUrls.Add(CurrentSiteUrl);
                        }
    
                        if (vsThreadedWaitDialog != null)
                        {
                            CloseProgressDialog(vsThreadedWaitDialog);
                        }
                    }
                }
    
                return isValid;
            }
    
            // Gets the available field types from the SharePoint site. Uses the GetFieldTypes SharePoint command to do this.
            internal ArrayList GetFieldTypes()
            {
                // If we have not yet validated this site, do it now.
                string errorMessage;
                if (!ValidateCurrentUrl(out errorMessage))
                {
                    MessageBox.Show(String.Format("Cannot connect to the SharePoint site: {0}. {1}",
                        CurrentSiteUrl, errorMessage), "SharePoint Connection Error");
                    return null;
                }
    
                // Site is valid, so go ahead and get the available field types.
                Uri siteUri = new Uri(CurrentSiteUrl, UriKind.Absolute);
                IVsThreadedWaitDialog2 vsThreadedWaitDialog = ShowProgressDialog(
                    "Connect to SharePoint", "Connecting to SharePoint site " + CurrentSiteUrl);
                string[] fieldTypesArray = this.ProjectService.SharePointConnection.ExecuteCommand<Uri, string[]>(
                        Contoso.SharePoint.Commands.CommandIds.GetFieldTypes, siteUri);
    
                if (vsThreadedWaitDialog != null)
                {
                    CloseProgressDialog(vsThreadedWaitDialog);
                }
    
                return new ArrayList(fieldTypesArray);
            }
    
            // Returns the default column group names in SharePoint.
            internal List<string> GetFieldGroups()
            {
                List<string> groups = new List<string>();
                groups.Add("Base Columns");
                groups.Add("Core Contact and Calendar Columns");
                groups.Add("Core Document Columns");
                groups.Add("Core Task and Issue Columns");
                groups.Add("Extended Columns");
                return groups;
            }
    
            #endregion
    
            #region Properties shared by the wizard implementation and the wizard UI
    
            internal ISharePointProjectService ProjectService
            {
                get
                {
                    if (projectServiceValue == null)
                    {
                        projectServiceValue = GetProjectService();
                    }
                    return projectServiceValue;
                }
            }
    
            internal bool IsSecondPagePopulated { get; set; }
            internal bool IsSandboxed { get; set; }
            internal string FieldType { get; set; }
            internal string FieldGroup { get; set; }
            internal string FieldName { get; set; }
            internal string CurrentSiteUrl { get; set; }
    
            #endregion
    
            #region Private methods
    
            private string GetLocalHostUrl()
            {
                const string HttpScheme = "http";
                UriBuilder builder = new UriBuilder(HttpScheme, Environment.MachineName.ToLowerInvariant());
                return builder.ToString();
            }
    
            private ISharePointProjectService GetProjectService()
            {
                ServiceProvider serviceProvider = new ServiceProvider(dteObject as IOleServiceProvider);
                return serviceProvider.GetService(typeof(ISharePointProjectService)) as ISharePointProjectService;
            }
    
            private IVsThreadedWaitDialog2 ShowProgressDialog(string caption, string message)
            {
                IOleServiceProvider oleServiceProvider = dteObject as IOleServiceProvider;
                IVsThreadedWaitDialogFactory dialogFactory = new ServiceProvider(oleServiceProvider).GetService(
                    typeof(SVsThreadedWaitDialogFactory)) as IVsThreadedWaitDialogFactory;
    
                if (dialogFactory == null)
                {
                    throw new InvalidOperationException("The IVsThreadedWaitDialogFactory object could not be retrieved.");
                }
    
                IVsThreadedWaitDialog2 vsThreadedWaitDialog = null;
                ErrorHandler.ThrowOnFailure(dialogFactory.CreateInstance(out vsThreadedWaitDialog));
                ErrorHandler.ThrowOnFailure(vsThreadedWaitDialog.StartWaitDialog(caption, message,
                     null, null, String.Empty, 0, false, true));
                return vsThreadedWaitDialog;
            }
    
            private void CloseProgressDialog(IVsThreadedWaitDialog2 vsThreadedWaitDialog)
            {
                if (vsThreadedWaitDialog == null)
                {
                    throw new ArgumentNullException("vsThreadedWaitDialog");
                }
    
                int canceled;
                ErrorHandler.ThrowOnFailure(vsThreadedWaitDialog.EndWaitDialog(out canceled));
            }
    
            #endregion
        }
    }
    

para criar o projeto que assina o gerenciador

  • Abra o arquivo de código de ProjectSigningManager e em seguida, substitua todo o conteúdo do arquivo com o código a seguir.

    Imports EnvDTE
    Imports System
    Imports System.IO
    Imports System.Runtime.InteropServices
    
    Friend Class ProjectSigningManager
        Private Const KEY_FILENAME As String = "key.snk"
        Private keyBuffer As Byte()
        Private strongNameGenerated As Boolean = False
    
    #Region "Methods used by the project wizard"
    
        Friend Sub GenerateKeyFile()
            If Not strongNameGenerated Then
                keyBuffer = CreateNewKeyPair()
                strongNameGenerated = True
            End If
        End Sub
    
        Friend Sub AddKeyFile(ByVal project As Project)
            If strongNameGenerated Then
                AddKeyFileToProject(project)
            End If
        End Sub
    #End Region
    
    #Region "Private members"
    
        Private Function CreateNewKeyPair() As Byte()
            Dim buffer As IntPtr = IntPtr.Zero
            Dim bufferSize As UInteger
            Dim keyBuffer As Byte()
    
            Try
                If 0 = NativeMethods.StrongNameKeyGen(IntPtr.Zero, 0, buffer, bufferSize) Then
                    Marshal.ThrowExceptionForHR(NativeMethods.StrongNameErrorInfo())
                End If
                If buffer = IntPtr.Zero Then
                    Throw New InvalidOperationException("Cannot generate the strong name key.")
                End If
    
                ' Copy generated key to managed memory.
                keyBuffer = New Byte(bufferSize) {}
                Marshal.Copy(buffer, keyBuffer, 0, CInt(bufferSize))
            Finally
                ' Free native resources.
                NativeMethods.StrongNameFreeBuffer(buffer)
            End Try
            Return keyBuffer
        End Function
    
        Private Sub AddKeyFileToProject(ByVal project As Project)
    
            ' Save the key to a file.
            If keyBuffer IsNot Nothing Then
                Try
                    Dim destinationDirectory As String = Path.GetDirectoryName(project.FullName)
                    Dim keySavePath As String = Path.Combine(destinationDirectory, KEY_FILENAME)
    
                    File.WriteAllBytes(keySavePath, keyBuffer)
                    project.ProjectItems.AddFromFile(keySavePath)
    
                    ' Add properties in the project to use the key for signing.
                    Dim projProps As EnvDTE.Properties = project.Properties
                    projProps.Item("SignAssembly").Value = True
                    projProps.Item("AssemblyOriginatorKeyFile").Value = KEY_FILENAME
                Catch e As Exception
                    Throw New Exception("Cannot add the strong name key to the project. " & e.Message, e)
                End Try
            End If
        End Sub
    
        Private Class NativeMethods
            <DllImport("mscoree.dll")>
            Friend Shared Function StrongNameFreeBuffer(ByVal pbMemory As IntPtr) As Integer
            End Function
    
            <DllImport("mscoree.dll", CharSet:=CharSet.Unicode, ExactSpelling:=True)>
            Friend Shared Function StrongNameKeyGen(ByVal wszKeyContainer As IntPtr, ByVal dwFlags As UInteger, _
                ByRef KeyBlob As IntPtr, ByRef KeyBlobSize As UInteger) As Integer
            End Function
    
            <DllImport("mscoree.dll", CharSet:=CharSet.Unicode)>
            Friend Shared Function StrongNameErrorInfo() As Integer
            End Function
        End Class
    #End Region
    End Class
    
    using EnvDTE;
    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    
    namespace ProjectTemplateWizard
    {
        internal class ProjectSigningManager
        {
            private const string KEY_FILENAME = "key.snk";
            private byte[] keyBuffer;
            private bool strongNameGenerated = false;
    
            #region Methods used by the project wizard
    
            internal void GenerateKeyFile()
            {
                if (!strongNameGenerated)
                {
                    keyBuffer = CreateNewKeyPair();
                    strongNameGenerated = true;
                }
            }
    
            internal void AddKeyFile(Project project)
            {
                if (strongNameGenerated)
                {
                    AddKeyFileToProject(project);
                }
            }
    
            #endregion
    
            #region Private members
    
            private byte[] CreateNewKeyPair()
            {
                IntPtr buffer = IntPtr.Zero;
                uint bufferSize;
                byte[] keyBuffer;
    
                try
                {
                    if (0 == NativeMethods.StrongNameKeyGen(IntPtr.Zero, 0, out buffer, out bufferSize))
                    {
                        Marshal.ThrowExceptionForHR(NativeMethods.StrongNameErrorInfo());
                    }
    
                    if (buffer == IntPtr.Zero)
                    {
                        throw new InvalidOperationException("Cannot generate the strong name key.");
                    }
    
                    // Copy generated key to managed memory.
                    keyBuffer = new byte[bufferSize];
                    Marshal.Copy(buffer, keyBuffer, 0, (int)bufferSize);
                }
                finally
                {
                    // Free native resources.
                    NativeMethods.StrongNameFreeBuffer(buffer);
                }
    
                return keyBuffer;
            }
    
            private void AddKeyFileToProject(Project project)
            {
                // Save the key to a file.
                if (keyBuffer != null)
                {
                    try
                    {
                        string destinationDirectory = Path.GetDirectoryName(project.FullName);
                        string keySavePath = Path.Combine(destinationDirectory, KEY_FILENAME);
    
                        File.WriteAllBytes(keySavePath, keyBuffer);
                        project.ProjectItems.AddFromFile(keySavePath);
    
                        // Add properties in the project to use the key for signing.
                        EnvDTE.Properties projProps = project.Properties;
                        projProps.Item("SignAssembly").Value = true;
                        projProps.Item("AssemblyOriginatorKeyFile").Value = KEY_FILENAME;
                    }
                    catch (Exception e)
                    {
                        throw new Exception("Cannot add the strong name key to the project. " + e.Message, e);
                    }
                }
            }
    
            private static class NativeMethods
            {
                [DllImport("mscoree.dll")]
                internal extern static int StrongNameFreeBuffer(IntPtr pbMemory);
    
                [DllImport("mscoree.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
                internal static extern int StrongNameKeyGen(IntPtr wszKeyContainer, uint dwFlags, out IntPtr KeyBlob, 
                    out uint KeyBlobSize);
    
                [DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
                internal static extern int StrongNameErrorInfo();
            }
    
            #endregion
        }
    }
    

Criando o assistente interface de usuário

Adicione XAML para definir a interface do usuário da janela do assistente e os dois controles de usuário que fornecem interface de usuário para as páginas do assistente, e adicione código para definir o comportamento dos controles da janela e usuário.O assistente que você cria lembra o assistente interno para projetos do SharePoint no Visual Studio.

ObservaçãoObservação

As seguintes etapas, compilar o projeto mandará alguns erros XAML após adicionar ou o código ao seu projeto.Esses erros partirão quando você adiciona o código em etapas posteriores.

Para criar a janela interface do usuário assistente

  1. Em o projeto de ProjectTemplateWizard, abra o menu de atalho para o arquivo de WizardWindow.xaml, e então escolha Abrir para abrir a janela no designer.

  2. Em o modo de exibição XAML, substitua ao designer atual XAML com o seguinte XAML.O XAML define uma interface do usuário que inclui um título, um Grid que contém as páginas do assistente, e botões de navegação na parte inferior da janela.

    <ui:DialogWindow x:Class="ProjectTemplateWizard.WizardWindow"
                     xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
                     xmlns:ui="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.11.0"        
                     xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"                                
                     Title="SharePoint Customization Wizard" Height="500" Width="700" ResizeMode="NoResize" 
                     Loaded="Window_Loaded" TextOptions.TextFormattingMode="Display">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="75*" />
                <RowDefinition Height="364*" />
                <RowDefinition Height="1*" />
                <RowDefinition Height="60*" />
            </Grid.RowDefinitions>
            <Grid Grid.Row="0" Name="headingGrid" Background="White">
                <Label Height="28" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="18,0,0,0" 
                       Name="headingLabel" FontWeight="ExtraBold" />
            </Grid>
            <Grid Grid.Row="1" Name="pageGrid" />
            <Rectangle Grid.Row="2" Name="separatorRectangle" Fill="White"  />
            <StackPanel Grid.Row="3" Name="navigationPanel" Orientation="Horizontal">
                <Button Content="&lt; _Previous" Margin="300,0,0,0"  Height="25" Name="previousButton" Width="85" 
                        IsEnabled="False" Click="previousButton_Click" />
                <Button Content="_Next >" Margin="10,0,0,0" Height="25" Name="nextButton" Width="85" Click="nextButton_Click" 
                        IsDefault="True" />
                <Button Content="_Finish" Margin="10,0,0,0" Height="25" Name="finishButton" Width="85" 
                        Click="finishButton_Click" />
                <Button Content="Cancel" Margin="10,0,0,0" Height="25" Name="cancelButton" Width="85" 
                        IsCancel="True" />
            </StackPanel>
        </Grid>
    </ui:DialogWindow>
    
    ObservaçãoObservação

    A janela que é criada em este XAML é derivada da classe base de DialogWindow .Quando você adiciona uma caixa de diálogo personalizado WPF em Visual Studio, recomendamos que você derivado a caixa de diálogo de esta classe para ter o estilo consistente com as outras caixas de diálogo do Visual Studio e para evitar problemas da caixa de diálogo modais que podem ocorrer de outra forma.Para obter mais informações, consulte Como: criar e gerenciar caixas de diálogo.

  3. Se você estiver desenvolvendo um projeto Visual Basic, remova o namespace de ProjectTemplateWizard o nome da classe de WizardWindow no atributo de x:Class do elemento de Window .Este elemento está na primeira linha do XAML.Quando você terminar, a primeira linha deve se parecer com o exemplo a seguir.

    <Window x:Class="WizardWindow"
    
  4. Abra o arquivo code-behind para o arquivo de WizardWindow.xaml.

  5. Substitua o conteúdo do arquivo, exceto declarações de using na parte superior do arquivo, com o código a seguir.

    Public Class WizardWindow
        Private firstPage As Page1
        Private secondPage As Page2
        Private Const firstPageLabel As String = "Specify the site and security level for debugging"
        Private Const secondPageLabel As String = "Configure the site column"
    
        Friend Sub New(ByVal presentationModel As SiteColumnWizardModel)
            InitializeComponent()
            Me.PresentationModel = presentationModel
            firstPage = New Page1(Me)
            secondPage = New Page2(Me)
            secondPage.Visibility = Visibility.Hidden
        End Sub
    
        Friend Property PresentationModel As SiteColumnWizardModel
    
        Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            headingLabel.Content = firstPageLabel
            pageGrid.Children.Add(firstPage)
            pageGrid.Children.Add(secondPage)
        End Sub
    
        Private Sub nextButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    
            ' Initialize the second wizard page if this is the first time 
            ' it has been shown with the current site URL.
            If Not PresentationModel.IsSecondPagePopulated Then
    
                If Not ValidateUrl() Then
                    Return
                End If
    
                ' Refresh the UI in the second page.
                secondPage.ClearControls()
                secondPage.PopulateSiteColumnOptions()
    
                ' Do not do this work again until the user changes the site URL.
                PresentationModel.IsSecondPagePopulated = True
            End If
    
            ' Display the second wizard page and update related controls.
            firstPage.Visibility = Visibility.Hidden
            secondPage.Visibility = Visibility.Visible
            previousButton.IsEnabled = True
            nextButton.IsEnabled = False
            nextButton.IsDefault = False
            finishButton.IsDefault = True
            headingLabel.Content = secondPageLabel
        End Sub
    
        ' Display the first wizard page again and update related controls.
        Private Sub previousButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            secondPage.Visibility = Visibility.Hidden
            firstPage.Visibility = Visibility.Visible
            previousButton.IsEnabled = False
            finishButton.IsDefault = False
            nextButton.IsEnabled = True
            nextButton.IsDefault = True
            headingLabel.Content = firstPageLabel
        End Sub
    
        Private Sub finishButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            If ValidateUrl() Then
                DialogResult = True
                Close()
            End If
        End Sub
    
        Private Function ValidateUrl() As Boolean
            Dim errorMessage As String = String.Empty
            If Not PresentationModel.ValidateCurrentUrl(errorMessage) Then
                MessageBox.Show(String.Format("Cannot connect to the SharePoint site: {0}. {1}",
                    PresentationModel.CurrentSiteUrl, errorMessage),
                    "SharePoint Connection Error")
                Return False
            End If
            Return True
        End Function
    End Class
    
    using System;
    using System.Windows;
    using Microsoft.VisualStudio.PlatformUI;
    
    namespace ProjectTemplateWizard
    {
        public partial class WizardWindow : DialogWindow
        {
            private Page1 firstPage;
            private Page2 secondPage;
            private const string firstPageLabel = "Specify the site and security level for debugging";
            private const string secondPageLabel = "Configure the site column";
    
            internal WizardWindow(SiteColumnWizardModel presentationModel)
            {
                InitializeComponent();
                this.PresentationModel = presentationModel;
                firstPage = new Page1(this);
                secondPage = new Page2(this);
                secondPage.Visibility = Visibility.Hidden;
            }
    
            internal SiteColumnWizardModel PresentationModel { get; set; }
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                headingLabel.Content = firstPageLabel;
                pageGrid.Children.Add(firstPage);
                pageGrid.Children.Add(secondPage);
            }
    
            private void nextButton_Click(object sender, RoutedEventArgs e)
            {
                // Initialize the second wizard page if this is the first time 
                // it has been shown with the current site URL.
                if (!PresentationModel.IsSecondPagePopulated)
                {
                    if (!ValidateUrl())
                    {
                        return;
                    }
    
                    // Refresh the UI in the second page.
                    secondPage.ClearControls();
                    secondPage.PopulateSiteColumnOptions();
    
                    // Do not do this work again until the user changes the site URL.
                    PresentationModel.IsSecondPagePopulated = true;
                }
    
                // Display the second wizard page and update related controls.
                firstPage.Visibility = Visibility.Hidden;
                secondPage.Visibility = Visibility.Visible;
                previousButton.IsEnabled = true;
                nextButton.IsEnabled = false;
                finishButton.IsDefault = true;
                headingLabel.Content = secondPageLabel;
            }
    
            // Display the first wizard page again and update related controls.
            private void previousButton_Click(object sender, RoutedEventArgs e)
            {
                secondPage.Visibility = Visibility.Hidden;
                firstPage.Visibility = Visibility.Visible;
                previousButton.IsEnabled = false;
                finishButton.IsDefault = false;
                nextButton.IsEnabled = true;
                nextButton.IsDefault = true;
                headingLabel.Content = firstPageLabel;
            }
    
            private void finishButton_Click(object sender, RoutedEventArgs e)
            {
                if (ValidateUrl())
                {
                    DialogResult = true;
                    Close();
                }
            }
    
            private bool ValidateUrl()
            {
                string errorMessage;
                if (!PresentationModel.ValidateCurrentUrl(out errorMessage))
                {
                    MessageBox.Show(String.Format("Cannot connect to the SharePoint site: {0}. {1}",
                        PresentationModel.CurrentSiteUrl, errorMessage),
                        "SharePoint Connection Error");
                    return false;
                }
                return true;
            }
        }
    }
    

Para criar a primeira página interface do usuário assistente

  1. Em o projeto de ProjectTemplateWizard, abra o menu de atalho para o arquivo Page1.xaml, e então escolha Abrir para abrir o controle de usuário no designer.

  2. Em o modo de exibição XAML, substitua ao designer atual XAML com o seguinte XAML.O XAML define uma interface do usuário que inclui uma caixa de texto onde os usuários podem entrar no URL de sites locais que desejam usar para depurar.Interface de usuário também inclui botões de opção com que os usuários podem especificar se o projeto na área restrita.

    <UserControl x:Class="ProjectTemplateWizard.Page1"
                 xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" d:DesignHeight="364" d:DesignWidth="700" Loaded="UserControl_Loaded">
        <Grid Height="364" HorizontalAlignment="Left" Name="page1Grid" Width="700">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20*" />
                <ColumnDefinition Width="548*" />
                <ColumnDefinition Width="132*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <TextBox Grid.Row="1" Grid.Column="1" Margin="5,0,1,0" Height="23" Name="siteUrlTextBox" 
                     TextChanged="siteUrlTextBox_TextChanged" />
            <Label Grid.Row="0" Grid.Column="1" Margin="0,20,0,0" Name="siteLabel" FontWeight="Bold" 
                   Target="{Binding ElementName=siteUrlTextBox}" 
                   Content="What local _site do you want to use for debugging?" />
            <Button Grid.Row="1" Grid.Column="2" Content="_Validate" Height="25" Name="validateButton" 
                    Width="88" Click="validateButton_Click" HorizontalAlignment="Left" 
                    Margin="5,0,0,0" VerticalAlignment="Top" />
            <Label Grid.Row="2" Grid.Column="1" Margin="0,10,0,0" Content="What is the trust level for this SharePoint solution?" 
                   Name="trustLabel" FontWeight="Bold" />
            <StackPanel Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Orientation="Vertical">
                <RadioButton Content="Deploy as a sand_boxed solution" Margin="5,0,0,0" Name="sandboxedSolutionRadioButton" 
                             FontWeight="Bold" Checked="sandboxedSolutionRadioButton_Checked" />
                <TextBlock TextWrapping="WrapWithOverflow" Margin="20,7,50,0">Clicking this option causes the solution to be 
                           deployed as a Sandboxed solution. Sandboxed solutions can be deployed by the site collection owner 
                           and are run in a secure, monitored process that has limited resource access.</TextBlock>
                <RadioButton Content="Deploy as a _farm solution" Margin="5,7,0,0" Name="farmSolutionRadioButton" FontWeight="Bold" 
                             Checked="farmSolutionRadioButton_Checked" />
                <TextBlock TextWrapping="WrapWithOverflow" Margin="20,7,50,0">Clicking this option means that users must have 
                           SharePoint administrator privileges to run or deploy the solution.</TextBlock>
            </StackPanel>
        </Grid>
    </UserControl>
    
  3. Se você estiver desenvolvendo um projeto Visual Basic, remova o namespace de ProjectTemplateWizard o nome da classe de Page1 no atributo de x:Class do elemento de UserControl .Isso está na primeira linha do XAML.Quando você terminar, a primeira linha deve parecer como a seguir.

    <UserControl x:Class="Page1"
    
  4. Substitua o conteúdo do arquivo Page1.xaml, exceto declarações de using na parte superior do arquivo, com o código a seguir.

    Public Class Page1
        Private mainWindow As WizardWindow
    
        Friend Sub New(ByVal mainWindow As WizardWindow)
            Me.mainWindow = mainWindow
            InitializeComponent()
        End Sub
    
        Private Sub UserControl_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            If (mainWindow.PresentationModel.IsSandboxed) Then
                sandboxedSolutionRadioButton.IsChecked = True
            Else
                sandboxedSolutionRadioButton.IsEnabled = False
                farmSolutionRadioButton.IsChecked = True
            End If
            siteUrlTextBox.Text = mainWindow.PresentationModel.CurrentSiteUrl
        End Sub
    
        ' Validate that the URL exists on the development computer.
        Private Sub validateButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Dim errorMessage As String = String.Empty
            validateButton.IsEnabled = False
    
            If Not mainWindow.PresentationModel.ValidateCurrentUrl(errorMessage) Then
                MessageBox.Show(String.Format("Cannot connect to the SharePoint site: {0}. {1}",
                    mainWindow.PresentationModel.CurrentSiteUrl, errorMessage),
                    "SharePoint Connection Error")
            Else
                MessageBox.Show("Successfully connected to SharePoint site " +
                    mainWindow.PresentationModel.CurrentSiteUrl, "Connection Successful")
            End If
            validateButton.IsEnabled = True
        End Sub
    
        ' Prevent users from finishing the wizard if the URL is not formatted correctly.
        Private Sub siteUrlTextBox_TextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
            Dim url As String = EnsureTrailingSlash(siteUrlTextBox.Text)
    
            ' Perform some basic error-checking on the URL here.
            If url.Length > 0 AndAlso Uri.IsWellFormedUriString(Uri.EscapeUriString(url), UriKind.Absolute) Then
    
                mainWindow.finishButton.IsEnabled = True
                mainWindow.nextButton.IsEnabled = True
                validateButton.IsEnabled = True
                mainWindow.PresentationModel.CurrentSiteUrl = url
                mainWindow.PresentationModel.IsSecondPagePopulated = False
            Else
                mainWindow.finishButton.IsEnabled = False
                mainWindow.nextButton.IsEnabled = False
                validateButton.IsEnabled = False
            End If
        End Sub
    
        Private Sub sandboxedSolutionRadioButton_Checked(ByVal sender As Object, ByVal e As RoutedEventArgs)
            mainWindow.PresentationModel.IsSandboxed = CBool(sandboxedSolutionRadioButton.IsChecked)
        End Sub
    
        Private Sub farmSolutionRadioButton_Checked(ByVal sender As Object, ByVal e As RoutedEventArgs)
            mainWindow.PresentationModel.IsSandboxed = CBool(sandboxedSolutionRadioButton.IsChecked)
        End Sub
    
        Private Function EnsureTrailingSlash(ByVal url As String)
            If Not String.IsNullOrEmpty(url) AndAlso url(url.Length - 1) <> "/" Then
                url += "/"
            End If
            Return url
        End Function
    End Class
    
    using System;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace ProjectTemplateWizard
    {
        public partial class Page1 : UserControl
        {
            private WizardWindow mainWindow;
    
            internal Page1(WizardWindow mainWindow)
            {
                this.mainWindow = mainWindow;
                InitializeComponent();
            }
    
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                if (mainWindow.PresentationModel.IsSandboxed)
                {
                    sandboxedSolutionRadioButton.IsChecked = true;
                }
                else
                {
                    sandboxedSolutionRadioButton.IsEnabled = false;
                    farmSolutionRadioButton.IsChecked = true;
                }
    
                siteUrlTextBox.Text = mainWindow.PresentationModel.CurrentSiteUrl;
            }
    
            // Validate that the URL exists on the development computer.
            private void validateButton_Click(object sender, RoutedEventArgs e)
            {
                string errorMessage;
                validateButton.IsEnabled = false;
    
                if (!mainWindow.PresentationModel.ValidateCurrentUrl(out errorMessage))
                {
                    MessageBox.Show(String.Format("Cannot connect to the SharePoint site: {0}. {1}",
                        mainWindow.PresentationModel.CurrentSiteUrl, errorMessage),
                        "SharePoint Connection Error");
                }
                else
                {
                    MessageBox.Show("Successfully connected to SharePoint site " +
                        mainWindow.PresentationModel.CurrentSiteUrl, "Connection Successful");
                }
    
                validateButton.IsEnabled = true;
            }
    
            // Prevent users from finishing the wizard if the URL is not formatted correctly.
            private void siteUrlTextBox_TextChanged(object sender, TextChangedEventArgs e)
            {
                string url = EnsureTrailingSlash(siteUrlTextBox.Text);
    
                // Perform some basic error-checking on the URL here.
                if ((url.Length > 0) && (Uri.IsWellFormedUriString(Uri.EscapeUriString(url), UriKind.Absolute)))
                {
                    mainWindow.finishButton.IsEnabled = true;
                    mainWindow.nextButton.IsEnabled = true;
                    validateButton.IsEnabled = true;
                    mainWindow.PresentationModel.CurrentSiteUrl = url;
                    mainWindow.PresentationModel.IsSecondPagePopulated = false;
                }
                else
                {
                    mainWindow.finishButton.IsEnabled = false;
                    mainWindow.nextButton.IsEnabled = false;
                    validateButton.IsEnabled = false;
                }
            }
    
            private void sandboxedSolutionRadioButton_Checked(object sender, RoutedEventArgs e)
            {
                mainWindow.PresentationModel.IsSandboxed = (bool)sandboxedSolutionRadioButton.IsChecked;
            }
    
            private void farmSolutionRadioButton_Checked(object sender, RoutedEventArgs e)
            {
                mainWindow.PresentationModel.IsSandboxed = (bool)sandboxedSolutionRadioButton.IsChecked;
            }
    
            private string EnsureTrailingSlash(string url)
            {
                if (!String.IsNullOrEmpty(url)
                    && url[url.Length - 1] != '/')
                {
                    url += '/';
                }
                return url;
            }
        }
    }
    

Para criar a segunda página interface do usuário assistente

  1. Em o projeto de ProjectTemplateWizard, abra o menu de atalho para o arquivo de Page2.xaml, e então escolha Abrir.

    O controle de usuário é aberto no designer.

  2. Em o modo de exibição XAML, substitua a atual XAML com o seguinte XAML.O XAML define uma interface do usuário que inclui uma lista suspensa para escolher o tipo base de coluna de site, uma caixa de combinação para especificar um interna ou um grupo personalizado que em para exibir a coluna de site na galeria, e uma caixa de texto para especificar o nome da coluna do site.

    <UserControl x:Class="ProjectTemplateWizard.Page2"
                 xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="https://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" d:DesignHeight="364" d:DesignWidth="700" Loaded="UserControl_Loaded">
        <Grid Height="364" HorizontalAlignment="Left" Name="page2Grid" Width="700">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20*" />
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="450*" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Label Grid.Row="0" Grid.Column="1" Margin="0,20,0,0" Content="_Type:" Name="fieldTypeLabel" 
                   FontWeight="Bold" Target="{Binding ElementName=fieldTypeComboBox}"/>
            <Label Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" Content="_Group:" Name="groupLabel" 
                   FontWeight="Bold" Target="{Binding ElementName=groupComboBox}"/>
            <Label Grid.Row="2" Grid.Column="1" Margin="0,10,0,0" Content="_Name:" Name="nameLabel" 
                   FontWeight="Bold" Target="{Binding ElementName=nameTextBox}"/>
            <ComboBox Grid.Row="0" Grid.Column="2" HorizontalAlignment="Left" Margin="0,20,0,0" Height="23" 
                      Name="fieldTypeComboBox" Width="450" SelectionChanged="fieldTypeComboBox_SelectionChanged" />
            <ComboBox Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left" Margin="0,10,0,0" Height="23" 
                      Name="groupComboBox" Width="450" IsEditable="True"  />
            <TextBox Grid.Row="2" Grid.Column="2" HorizontalAlignment="Left"  Margin="0,10,0,0" Height="23" 
                     Name="nameTextBox" Width="450" TextChanged="nameTextBox_TextChanged" />
        </Grid>
    </UserControl>
    
  3. Se você estiver desenvolvendo um projeto Visual Basic, remova o namespace de ProjectTemplateWizard o nome da classe de Page2 no atributo de x:Class do elemento de UserControl .Isso está na primeira linha do XAML.Quando você terminar, a primeira linha deve parecer como a seguir.

    <UserControl x:Class="Page2"
    
  4. Substitua o conteúdo do arquivo de code-behind para o arquivo de Page2.xaml, exceto declarações de using na parte superior do arquivo, com o código a seguir.

    Public Class Page2
        Private mainWindow As WizardWindow
        Private innerTextBoxForGroupComboBox As TextBox
    
        Friend Sub New(ByVal mainWindow As WizardWindow)
            Me.mainWindow = mainWindow
            InitializeComponent()
        End Sub
    
        Friend Sub ClearControls()
            fieldTypeComboBox.Items.Clear()
            groupComboBox.Items.Clear()
            nameTextBox.Clear()
        End Sub
    
        Friend Sub PopulateSiteColumnOptions()
            ' Add the available field type names to the combo box.
            Dim fieldTypes As System.Collections.ArrayList = mainWindow.PresentationModel.GetFieldTypes()
            If fieldTypes IsNot Nothing Then
                fieldTypes.Sort()
                For Each fieldValue As String In fieldTypes
                    fieldTypeComboBox.Items.Add(fieldValue)
                Next
                fieldTypeComboBox.SelectedIndex = 0
            End If
    
            ' Add the default group names to the combo box.
            Dim fieldGroups As List(Of String) = mainWindow.PresentationModel.GetFieldGroups()
            For Each fieldGroupValue As String In fieldGroups
                groupComboBox.Items.Add(fieldGroupValue)
            Next
            groupComboBox.SelectedIndex = 0
        End Sub
    
        Private Sub UserControl_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Handle the TextChanged event of the underlying TextBox for the ComboBox. This enables us to determine 
            ' 1) when the user selects an item in the list and 2) when they type their own custom group name. 
            ' The ComboBox.SelectionChanged event is not raised when you type in an editable ComboboBox.
            innerTextBoxForGroupComboBox = CType(groupComboBox.Template.FindName(
                "PART_EditableTextBox", groupComboBox), TextBox)
            AddHandler innerTextBoxForGroupComboBox.TextChanged, AddressOf innerTextBoxForGroupComboBox_TextChanged
        End Sub
    
        Private Sub fieldTypeComboBox_SelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs)
            mainWindow.PresentationModel.FieldType = CStr(fieldTypeComboBox.SelectedItem)
        End Sub
    
        Private Sub innerTextBoxForGroupComboBox_TextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
            mainWindow.PresentationModel.FieldGroup = groupComboBox.Text
        End Sub
    
        Private Sub nameTextBox_TextChanged(ByVal sender As Object, ByVal e As TextChangedEventArgs)
            mainWindow.PresentationModel.FieldName = nameTextBox.Text
        End Sub
    End Class
    
    using System.Windows;
    using System.Windows.Controls;
    
    namespace ProjectTemplateWizard
    {
        public partial class Page2 : UserControl
        {
            private WizardWindow mainWindow;
            private TextBox innerTextBoxForGroupComboBox;
    
            internal Page2(WizardWindow mainWindow)
            {
                this.mainWindow = mainWindow;
                InitializeComponent();
            }
    
            internal void ClearControls()
            {
                fieldTypeComboBox.Items.Clear();
                groupComboBox.Items.Clear();
                nameTextBox.Clear();
            }
    
            internal void PopulateSiteColumnOptions()
            {
                // Add the available field type names to the combo box.
                System.Collections.ArrayList fieldTypes = mainWindow.PresentationModel.GetFieldTypes();
                if (fieldTypes != null)
                {
                    fieldTypes.Sort();
                    foreach (string fieldValue in fieldTypes)
                    {
                        fieldTypeComboBox.Items.Add(fieldValue);
                    }
    
                    fieldTypeComboBox.SelectedIndex = 0;
                }
    
                // Add the default group names to the combo box.
                System.Collections.Generic.List<string> fieldGroups = mainWindow.PresentationModel.GetFieldGroups();
                foreach (string fieldGroupValue in fieldGroups)
                {
                    groupComboBox.Items.Add(fieldGroupValue);
                }
    
                groupComboBox.SelectedIndex = 0;
            }
    
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                // Handle the TextChanged event of the underlying TextBox for the ComboBox. This enables us to determine 
                // 1) when the user selects an item in the list and 2) when they type their own custom group name. 
                // The ComboBox.SelectionChanged event is not raised when you type in an editable ComboboBox.
                innerTextBoxForGroupComboBox = groupComboBox.Template.FindName(
                    "PART_EditableTextBox", groupComboBox) as TextBox;
                innerTextBoxForGroupComboBox.TextChanged += innerTextBoxForGroupComboBox_TextChanged;
            }
    
            private void fieldTypeComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                mainWindow.PresentationModel.FieldType = (string)fieldTypeComboBox.SelectedItem;
            }
    
            void innerTextBoxForGroupComboBox_TextChanged(object sender, TextChangedEventArgs e)
            {
                mainWindow.PresentationModel.FieldGroup = groupComboBox.Text;
            }
    
            private void nameTextBox_TextChanged(object sender, TextChangedEventArgs e)
            {
                mainWindow.PresentationModel.FieldName = nameTextBox.Text;
            }
        }
    }
    

implementando o assistente

Define a funcionalidade do assistente implementando a interface de IWizard .Essa interface define métodos que o Visual Studio chama quando o assistente inicia e terminar, e por vezes quando o assistente executar.

para implementar o assistente

  1. Em o projeto de ProjectTemplateWizard, abra o arquivo de código de SiteColumnProjectWizard.

  2. Substitua todo o conteúdo do arquivo com o código a seguir.

    Imports EnvDTE
    Imports Microsoft.VisualStudio.SharePoint
    Imports Microsoft.VisualStudio.TemplateWizard
    Imports System
    Imports System.Collections.Generic
    
    Public Class SiteColumnProjectWizard
        Implements IWizard
    
        Private wizardUI As WizardWindow
        Private dteObject As DTE
        Private presentationModel As SiteColumnWizardModel
        Private signingManager As ProjectSigningManager
    
        Public Sub New()
            signingManager = New ProjectSigningManager()
        End Sub
    
        Public Sub RunStarted(ByVal automationObject As Object, ByVal replacementsDictionary As Dictionary(Of String, String), _
            ByVal runKind As WizardRunKind, ByVal customParams() As Object) Implements IWizard.RunStarted
    
            dteObject = CType(automationObject, DTE)
            presentationModel = New SiteColumnWizardModel(dteObject, False)
    
            If Not presentationModel.ProjectService.IsSharePointInstalled Then
                Dim errorString As String = "A SharePoint server is not installed on this computer. A SharePoint server " &
                    "must be installed to work with SharePoint projects."
                System.Windows.MessageBox.Show(errorString, "SharePoint Not Installed", System.Windows.MessageBoxButton.OK,
                    System.Windows.MessageBoxImage.Error)
                Throw New WizardCancelledException(errorString)
            End If
    
            wizardUI = New WizardWindow(presentationModel)
            Dim dialogCompleted? As Boolean = wizardUI.ShowModal()
    
            If (dialogCompleted = True) Then
                replacementsDictionary.Add("$selectedfieldtype$", presentationModel.FieldType)
                replacementsDictionary.Add("$selectedgrouptype$", presentationModel.FieldGroup)
                replacementsDictionary.Add("$fieldname$", presentationModel.FieldName)
                signingManager.GenerateKeyFile()
            Else
                Throw New WizardCancelledException()
            End If
        End Sub
    
        ' Populate the SiteUrl and IsSandboxedSolution properties in the new project, and add a new 
        ' key.snk file to the project.
        Public Sub ProjectFinishedGenerating(ByVal project As Project) _
            Implements IWizard.ProjectFinishedGenerating
            Dim sharePointProject As ISharePointProject = presentationModel.ProjectService.Convert(Of Project, ISharePointProject)(project)
            sharePointProject.SiteUrl = New Uri(presentationModel.CurrentSiteUrl, UriKind.Absolute)
            sharePointProject.IsSandboxedSolution = presentationModel.IsSandboxed
            signingManager.AddKeyFile(project)
        End Sub
    
        ' Always return true; this IWizard implementation throws a WizardCancelledException
        ' that is handled by Visual Studio if the user cancels the wizard.
        Public Function ShouldAddProjectItem(ByVal filePath As String) As Boolean _
            Implements IWizard.ShouldAddProjectItem
            Return True
        End Function
    
        ' The following IWizard methods are not used in this example.
        Public Sub BeforeOpeningFile(ByVal projectItem As ProjectItem) _
            Implements IWizard.BeforeOpeningFile
        End Sub
    
        Public Sub ProjectItemFinishedGenerating(ByVal projectItem As ProjectItem) _
            Implements IWizard.ProjectItemFinishedGenerating
        End Sub
    
        Public Sub RunFinished() Implements IWizard.RunFinished
        End Sub
    End Class
    
    using EnvDTE;
    using Microsoft.VisualStudio.SharePoint;
    using Microsoft.VisualStudio.TemplateWizard;
    using System;
    using System.Collections.Generic;
    
    namespace ProjectTemplateWizard
    {
        public class SiteColumnProjectWizard : IWizard
        {
            private WizardWindow wizardUI;
            private DTE dteObject;
            private SiteColumnWizardModel presentationModel;
            private ProjectSigningManager signingManager;
    
            public SiteColumnProjectWizard()
            {
                signingManager = new ProjectSigningManager();
            }
    
            public void RunStarted(object automationObject, Dictionary<string, string> replacementsDictionary, 
                WizardRunKind runKind, object[] customParams)
            {
                dteObject = automationObject as DTE;
                presentationModel = new SiteColumnWizardModel(dteObject, false);
    
                if (!presentationModel.ProjectService.IsSharePointInstalled)
                {
                    string errorString = "A SharePoint server is not installed on this computer. A SharePoint server " +
                        "must be installed to work with SharePoint projects.";
                    System.Windows.MessageBox.Show(errorString, "SharePoint Not Installed", System.Windows.MessageBoxButton.OK,
                        System.Windows.MessageBoxImage.Error);
                    throw new WizardCancelledException(errorString);
                }
    
                wizardUI = new WizardWindow(presentationModel);
                Nullable<bool> dialogCompleted = wizardUI.ShowModal();
    
                if (dialogCompleted == true)
                {
                    replacementsDictionary.Add("$selectedfieldtype$", presentationModel.FieldType);
                    replacementsDictionary.Add("$selectedgrouptype$", presentationModel.FieldGroup);
                    replacementsDictionary.Add("$fieldname$", presentationModel.FieldName);
                    signingManager.GenerateKeyFile();
                }
                else
                {
                    throw new WizardCancelledException();
                }
            }
    
            // Populate the SiteUrl and IsSandboxedSolution properties in the new project, and add a new 
            // key.snk file to the project.
            public void ProjectFinishedGenerating(Project project)
            {
                ISharePointProject sharePointProject = presentationModel.ProjectService.Convert<Project, ISharePointProject>(project);
                sharePointProject.SiteUrl = new Uri(presentationModel.CurrentSiteUrl, UriKind.Absolute);
                sharePointProject.IsSandboxedSolution = presentationModel.IsSandboxed;
                signingManager.AddKeyFile(project);
            }
    
            // Always return true; this IWizard implementation throws a WizardCancelledException
            // that is handled by Visual Studio if the user cancels the wizard.
            public bool ShouldAddProjectItem(string filePath)
            {
                return true;
            }
    
            // The following IWizard methods are not used in this example.
            public void BeforeOpeningFile(ProjectItem projectItem)
            {
            }
    
            public void ProjectItemFinishedGenerating(ProjectItem projectItem)
            {
            }
    
            public void RunFinished()
            {
            }
        }
    }
    

Criando comandos do SharePoint

Crie dois comandos personalizados que chamam no modelo de objeto de servidor do SharePoint.Um comando determina se o URL do site que o usuário digita no assistente é válido.O outro comando obtém todos os tipos de campo de site web do SharePoint especificada para que os usuários possam selecionar um de eles para usar como a base para a nova coluna do site.

Para definir comandos do SharePoint

  1. Em o projeto de SharePointCommands , abra o arquivo de código de comandos.

  2. Substitua todo o conteúdo do arquivo com o código a seguir.

    Imports Microsoft.SharePoint
    Imports Microsoft.VisualStudio.SharePoint.Commands
    
    Namespace Contoso.SharePoint.Commands
    
        Friend Class Commands
    
            <SharePointCommand(CommandIds.ValidateSite)> _
            Private Function ValidateSite(ByVal context As ISharePointCommandContext, ByVal url As Uri) As Boolean
                Using site As SPSite = New SPSite(url.AbsoluteUri)
                    Dim webUrl As String = DetermineWebUrl(url.AbsolutePath, site.ServerRelativeUrl)
                    If webUrl IsNot Nothing Then
                        Using web As SPWeb = site.OpenWeb(webUrl, True)
                            Return web.Exists
                        End Using
                    End If
                End Using
                Return False
            End Function
    
            ' For simplicity, this command does not check to make sure the provided Uri is valid. 
            ' Use the ValidateSite command to verify that the Uri is valid first.
            <SharePointCommand(CommandIds.GetFieldTypes)> _
            Private Function GetFieldTypes(ByVal context As ISharePointCommandContext, ByVal url As Uri) As String()
                Dim columnDefinitions As List(Of String) = New List(Of String)()
                Using site As SPSite = New SPSite(url.AbsoluteUri)
                    Dim webUrl As String = DetermineWebUrl(url.AbsolutePath, site.ServerRelativeUrl)
                    Using web As SPWeb = site.OpenWeb(webUrl, True)
                        For Each columnDefinition As SPFieldTypeDefinition In web.FieldTypeDefinitionCollection
                            columnDefinitions.Add(columnDefinition.TypeName)
                        Next
                        ' SharePoint commands cannot serialize List<string>, so return an array.
                        Return columnDefinitions.ToArray()
                    End Using
                End Using
            End Function
    
            Private Function DetermineWebUrl(ByVal serverRelativeInputUrl As String, ByVal serverRelativeSiteUrl As String) As String
                ' Make sure both URLs have a trailing slash.
                serverRelativeInputUrl = EnsureTrailingSlash(serverRelativeInputUrl)
                serverRelativeSiteUrl = EnsureTrailingSlash(serverRelativeSiteUrl)
    
                Dim webUrl As String = Nothing
                Dim isSubString As Boolean = serverRelativeInputUrl.StartsWith(serverRelativeSiteUrl, StringComparison.OrdinalIgnoreCase)
    
                If isSubString Then
                    ' The Web URL cannot have escaped characters.
                    webUrl = Uri.UnescapeDataString(serverRelativeInputUrl.Substring(serverRelativeSiteUrl.Length))
                End If
                Return webUrl
            End Function
    
            Private Function EnsureTrailingSlash(ByVal url As String)
                If Not String.IsNullOrEmpty(url) AndAlso url(url.Length - 1) <> "/" Then
                    url += "/"
                End If
                Return url
            End Function
        End Class
    End Namespace
    
    using System;
    using System.Collections.Generic;
    using Microsoft.SharePoint;
    using Microsoft.VisualStudio.SharePoint.Commands;
    
    namespace Contoso.SharePoint.Commands
    {
        internal class Commands
        {
            [SharePointCommand(CommandIds.ValidateSite)]
            private bool ValidateSite(ISharePointCommandContext context, Uri url)
            {
                using (SPSite site = new SPSite(url.AbsoluteUri))
                {
                    string webUrl = DetermineWebUrl(url.AbsolutePath, site.ServerRelativeUrl);
                    if (webUrl != null)
                    {
                        using (SPWeb web = site.OpenWeb(webUrl, true))
                        {
                            return web.Exists;
                        }
                    }
                }
    
                return false;
            }
    
            // For simplicity, this command does not check to make sure the provided Uri is valid. 
            // Use the ValidateSite command to verify that the Uri is valid first.
            [SharePointCommand(CommandIds.GetFieldTypes)]
            private string[] GetFieldTypes(ISharePointCommandContext context, Uri url)
            {
                List<string> columnDefinitions = new List<string>();
                using (SPSite site = new SPSite(url.AbsoluteUri))
                {
                    string webUrl = DetermineWebUrl(url.AbsolutePath, site.ServerRelativeUrl);
                    using (SPWeb web = site.OpenWeb(webUrl, true))
                    {
                        foreach (SPFieldTypeDefinition columnDefinition in web.FieldTypeDefinitionCollection)
                        {
                            columnDefinitions.Add(columnDefinition.TypeName);
                        }
    
                        // SharePoint commands cannot serialize List<string>, so return an array.
                        return columnDefinitions.ToArray();
                    }
                }
            }
    
            private string DetermineWebUrl(string serverRelativeInputUrl, string serverRelativeSiteUrl)
            {
                // Make sure both URLs have a trailing slash.
                serverRelativeInputUrl = EnsureTrailingSlash(serverRelativeInputUrl);
                serverRelativeSiteUrl = EnsureTrailingSlash(serverRelativeSiteUrl);
    
                string webUrl = null;
                bool isSubString = serverRelativeInputUrl.StartsWith(serverRelativeSiteUrl, StringComparison.OrdinalIgnoreCase);
    
                if (isSubString)
                {
                    // The Web URL cannot have escaped characters.
                    webUrl = Uri.UnescapeDataString(serverRelativeInputUrl.Substring(serverRelativeSiteUrl.Length));
                }
    
                return webUrl;
            }
    
            private string EnsureTrailingSlash(string url)
            {
                if (!String.IsNullOrEmpty(url)
                    && url[url.Length - 1] != '/')
                {
                    url += '/';
                }
                return url;
            }
        }
    }
    

Ponto de Verificação

Em esse ponto do passo-a-passo, todo o código para o assistente agora está no projeto.Compile o projeto para certificar-se de que compila sem erros.

Para criar seu projeto

  • Em a barra de menu, escolha Compilar, Compilar solução.

Removendo os key.snk arquivo de modelo de projeto

Em Passo a passo: Criando um Item de projeto de coluna do Site com um modelo de projeto, parte 1, o modelo de projeto que você criou contém um arquivo de key.snk que é usado para assinar cada instância de projeto da coluna do site.Este arquivo de key.snk não é mais necessário porque o assistente gera agora um novo arquivo de key.snk para cada projeto.Remova o arquivo de key.snk modelos de projeto e remover referências para o arquivo.

Para remover os key.snk arquivo de modelo de projeto

  1. Em Gerenciador de Soluções, sob o nó de SiteColumnProjectTemplate , abra o menu de atalho para o arquivo de key.snk , e então escolha Excluir.

  2. Em a caixa de diálogo de confirmação que aparece, escolha o botão de OK .

  3. Sob o nó de SiteColumnProjectTemplate , abra o arquivo de SiteColumnProjectTemplate.vstemplate, e remova o seguinte elemento de ele.

    <ProjectItem ReplaceParameters="false" TargetFileName="key.snk">key.snk</ProjectItem>
    
  4. Salve e feche o arquivo.

  5. Sob o nó de SiteColumnProjectTemplate , abra o arquivo de ProjectTemplate.csproj ou de ProjectTemplate.vbproj, e remova o seguinte elemento de PropertyGroup de ele.

    <PropertyGroup>
      <SignAssembly>true</SignAssembly>
      <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
    </PropertyGroup>
    
  6. Remova o seguinte elemento de None .

    <None Include="key.snk" />
    
  7. Salve e feche o arquivo.

Associando o assistente com o modelo de projeto

Agora que você implementou o assistente, você deve associar o assistente com o modelo de projeto de Coluna de Site .Há três procedimentos que você deve completar para fazer isso:

  1. Assine o assembly do assistente com um nome forte.

  2. Obter o símbolo de chave pública para o assembly do assistente.

  3. Adicione uma referência ao assembly do assistente no arquivo .vstemplate para o modelo de projeto de Coluna de Site .

Para assinar o assembly do assistente com um nome forte

  1. Em Gerenciador de Soluções, abra o menu de atalho para o projeto de ProjectTemplateWizard , e então escolha Propriedades.

  2. Em a guia de Assinando , selecione a caixa de seleção de Assinar o assembly .

  3. Em a lista de Escolha um arquivo de chave de nome forte , escolha <New...>.

  4. Em a caixa de diálogo de Criar Chave de Nome Forte , digite um nome para o novo arquivo de chave, desmarque a caixa de seleção de Proteger o arquivo de chaves com senha , e então escolha o botão de OK .

  5. Abra o menu de atalho para o projeto de ProjectTemplateWizard , e então escolha Compilar para criar o arquivo de ProjectTemplateWizard.dll.

Para obter o símbolo de chave pública para o assembly do assistente

  1. Em Menu Iniciar, escolha Todos os Programas, escolha Miscrosoft Visual Studio 2012O Visual Studio, escolha, e escolha Prompt de Comando do Desenvolvedor para VS2012.

    Uma janela de prompt de comando do Visual Studio abre.

  2. Execute o seguinte comando, substituindo PathToWizardAssembly com o caminho completo do assembly criado de ProjectTemplateWizard.dll para o projeto de ProjectTemplateWizard no seu computador de desenvolvimento:

    sn.exe -T PathToWizardAssembly
    

    O símbolo de chave pública para o assembly de ProjectTemplateWizard.dll é escrito na janela do prompt de comando do Visual Studio.

  3. Manter a janela do prompt de comando do Visual Studio aberta.Você precisará o símbolo de chave pública durante o procedimento a seguir.

Para adicionar uma referência para o assembly do assistente no arquivo .vstemplate

  1. Em Gerenciador de Soluções, expanda o nó de projeto de SiteColumnProjectTemplate e o arquivo de SiteColumnProjectTemplate.vstemplate.

  2. Por ao final do arquivo, adicione o seguinte elemento de WizardExtension entre </TemplateContent> e as marcas de </VSTemplate> .Substitua o valor de o token de atributo de PublicKeyToken com o símbolo de chave pública que você tiver obtido no procedimento anterior.

    <WizardExtension>
      <Assembly>ProjectTemplateWizard, Version=1.0.0.0, Culture=neutral, PublicKeyToken=your token</Assembly>
      <FullClassName>ProjectTemplateWizard.SiteColumnProjectWizard</FullClassName>
    </WizardExtension>
    

    Para obter mais informações sobre o elemento de WizardExtension , consulte Elemento de WizardExtension (modelos Visual Studio).

  3. Salve e feche o arquivo.

Adicionando parâmetros substituível ao Elements.xml arquivo no modelo de projeto

Adicionar vários parâmetros substituível para o arquivo de Elements.xml no projeto de SiteColumnProjectTemplate.Esses parâmetros são inicializados no método de RunStarted na classe de SiteColumnProjectWizard que você definiu anteriormente.Quando um usuário cria um projeto de coluna de site, o Visual Studio substitui automaticamente esses parâmetros no arquivo de Elements.xml no novo projeto com os valores que especificadas no assistente.

Um parâmetro substituível é um símbolo que inicie e termina com o caractere de cifrão ($).Além da definição de seus próprios parâmetros substituível, você pode usar os parâmetros internos que são definidos e inicializados pelo sistema do projeto do SharePoint.Para obter mais informações, consulte Parâmetros substituíveis.

Para adicionar os arquivos para o Elements.xml parâmetros substituível

  1. Em o projeto de SiteColumnProjectTemplate, substitua o conteúdo do arquivo de Elements.xml com o seguinte XML.

    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="https://schemas.microsoft.com/sharepoint/">
      <Field ID="{$guid5$}" 
             Name="$fieldname$" 
             DisplayName="$fieldname$" 
             Type="$selectedfieldtype$" 
             Group="$selectedgrouptype$">
      </Field>
    </Elements>
    

    Novo XML modifica os valores de Name, de DisplayName, de Type, e atributos de Group aos parâmetros substituível personalizados.

  2. Salve e feche o arquivo.

Adicionando o assistente o pacote de VSIX

Para implantar o assistente com o VSIX empacotar que contém o modelo de projeto de coluna de site, adicione referências para o projeto do assistente e comandos do SharePoint projeto para o arquivo de source.extension.vsixmanifest no projeto de VSIX.

Para adicionar o assistente o pacote de VSIX

  1. Em Gerenciador de Soluções, no projeto de SiteColumnProjectItem , abra o menu de atalho para o arquivo de source.extension.vsixmanifest , e então escolha Abrir.

    O Visual Studio abre o arquivo no editor manifesto.

  2. Em a guia de Ativos do editor, escolha o botão de Novo .

    a caixa de diálogo de adicionar o novo recurso abre.

  3. Em a lista de Tipo , escolha Microsoft.VisualStudio.Assembly.

  4. Em a lista de Origem , escolha Um projeto na solução atual.

  5. Em a lista de Projeto , escolha, e escolha ProjectTemplateWizardno botão de OK .

  6. Em a guia de Ativos do editor, escolha o botão de Novo novamente.

    a caixa de diálogo de adicionar o novo recurso abre.

  7. Em a lista de Tipo , entre em SharePoint.Commands.v4.

  8. Em a lista de Origem , escolha Um projeto na solução atual.

  9. Em a lista de Projeto , escolha o projeto de SharePointCommands , e então escolha o botão de OK .

  10. Em a barra de menu, escolha Compilar, Compilar solução, e então certifique-se de que a solução compila sem erros.

testando o assistente

Você agora está pronto para testar o assistente.Primeiro, iniciar a depuração da solução SiteColumnProjectItem na instância de avaliação do Visual Studio.Em seguida, testar o assistente para o projeto de coluna de site na instância de avaliação do Visual Studio.Finalmente, compilação e executar o projeto para verificar que a coluna de site funciona como esperado.

Para iniciar a depuração da solução

  1. Reinicie o Visual Studio com credenciais administrativas, e abra a solução de SiteColumnProjectItem.

  2. Em o projeto de ProjectTemplateWizard, abra o arquivo de código de SiteColumnProjectWizard, e adicione um ponto de interrupção na primeira linha de código no método de RunStarted .

  3. Em a barra de menu, escolha Depurar, Exceções.

  4. Em a caixa de diálogo de Exceções , certifique-se de que as caixas de seleção de Lançado e de Sem tratamento do usuário para Exceções do common language runtime são desmarcadas, e escolher-se no botão de OK .

  5. Iniciar a depuração escolhendo a chave de F5 ou, na barra de menus, escolhendo Depurar, Iniciar Depuração.

    O Visual Studio instala a extensão em %UserProfile%\AppData\Local\Microsoft\VisualStudio\11.0Exp\Extensions\Contoso\Site Column\1.0 e inicia uma instância de avaliação do Visual Studio.Você irá testar o item de projeto em esse caso do Visual Studio.

Para testar o assistente no Visual Studio

  1. Em a instância de avaliação do Visual Studio, na barra de menu, escolha Arquivo, Novo, Projeto.

  2. Expanda o nó de Visual C# ou o nó de Visual Basic (dependendo do idioma que seu modelo de projeto oferece suporte), expanda o nó de SharePoint , e então escolha o nó de 2010 .

  3. Em a lista de modelos de projeto, escolha Coluna de Site, nomeie o projeto SiteColumnWizardTest, e então escolha o botão de OK .

  4. Verifique se o código em outra instância do Visual Studio pára no ponto de interrupção que anteriormente definido no método de RunStarted .

  5. Continuar a depuração o projeto escolhendo a chave de F5 ou, na barra de menus, escolhendo Depurar, Continuar.

  6. Em Assistente de personalização do SharePoint, digite o URL do site que você deseja usar para depuração, e então escolha o botão de Avançar .

  7. Em a segunda página de Assistente de personalização do SharePoint, faça as seleções seguintes:

    • Em a lista de Tipo , escolha Booliano.

    • Em a lista de Grupo , escolha Sim/não colunas personalizadas.

    • Em a caixa de Nome , entre no my coluna sim/não, e então escolha o botão de Concluir .

    Em Gerenciador de Soluções, um novo projeto aparece e contém um item de projeto que é chamado Campo1, e o Visual Studio abre o arquivo de Elements.xml de projeto no editor.

  8. Verifique se Elements.xml contém os valores que você especificou no assistente.

Para testar a coluna de site no SharePoint

  1. Em a instância de avaliação do Visual Studio, escolha a tecla F5.

    A coluna do site é empacotada e implantado para o site do SharePoint que a propriedade de URL do Site de projeto especifica.Navegador da web abre a página padrão de esse site.

    ObservaçãoObservação

    Se a caixa de diálogo aparece Depuração de Script Desabilitada , escolha o botão de Sim para continuar a depuração o projeto.

  2. Em o menu de Ações do Site , escolha Configurações do Site.

  3. Em a página das definições de Galeriaslocal, sob, clique no link de Colunas de Site .

  4. Em a lista de colunas de site, verifique se um grupo de Sim/não colunas personalizadas contém uma coluna que é chamada Minha coluna sim, e então feche o navegador da web.

Limpando o computador de desenvolvimento

Depois que você concluir testar o item de projeto, remova o modelo de projeto de instância de avaliação do Visual Studio.

Para limpar o computador de desenvolvimento

  1. Em a instância de avaliação do Visual Studio, na barra de menu, escolha Ferramentas, Extensões e Atualizações.

    a caixa de diálogo de Extensões e Atualizações abre.

  2. Em a lista de extensões Coluna de Site, escolha, e escolha no botão de Desinstalar .

  3. Em a caixa de diálogo que aparece, escolha o botão de Sim para confirmar que você deseja desinstalar a extensão, e então escolha o botão de Reiniciar Agora para concluir a desinstalação.

  4. Feche a instância de avaliação do Visual Studio e a instância na qual a solução de CustomActionProjectItem é aberta.

    Para obter informações sobre como implantar as extensões de Visual Studio , consulte Implantação de extensão de Visual Studio.

Consulte também

Tarefas

Passo a passo: Criando um Item de projeto de coluna do Site com um modelo de projeto, parte 1

Como: usar assistentes com modelos de projeto

Referência

Referência do esquema de modelo do Visual Studio

IWizard

Conceitos

Definindo tipos de Item de projeto do SharePoint personalizados

Criando modelos de Item e projeto para itens de projeto do SharePoint