Partilhar via


Demonstra Passo a passo: A criação de um Item de projeto da coluna de Site com um modelo de projeto, parte 2

Depois de definir um tipo personalizado de item de projeto do SharePoint e associá-la a um modelo de projeto de Visual Studio, também convém fornecer um Assistente para o modelo. Você pode usar o Assistente para coletar informações dos usuários quando eles usarem o seu modelo para criar um novo projeto que contém o item de projeto. As informações que você colete podem ser usadas para inicializar o item de projeto.

Esta explicação passo a passo, você adicionará um Assistente para o modelo de projeto de coluna do Site é demonstrado em Demonstra Passo a passo: A criação de um Item de projeto da coluna de Site com um modelo de projeto, parte 1. Quando um usuário cria um projeto de coluna do Site, o assistente coleta informações sobre a coluna de site (como, por exemplo, seu tipo base e o grupo) e adiciona essas informações ao arquivo elements no novo projeto.

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

  • Criando um Assistente para um tipo de item de projeto SharePoint personalizado que está associado um modelo de projeto.

  • Definir um assistente personalizado da interface do usuário é semelhante os assistentes internos para o SharePoint projetos em Visual Studio 2010.

  • A criação de dois comandos do SharePoint que são usados para chamar o site local do SharePoint durante a execução do assistente. Comandos do SharePoint são métodos que podem ser usados pelas extensões de Visual Studio para chamar as 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íveis para inicializar os arquivos de projeto do SharePoint com os dados coletados no assistente.

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

  • O Assistente de teste e depuração.

ObservaçãoObservação

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

Pré-requisitos

Para realizar este passo a passo, você deve primeiro criar a solução de SiteColumnProjectItem completando Demonstra Passo a passo: A criação de um Item de projeto da coluna de Site com um modelo de projeto, parte 1.

Você também precisa os seguintes componentes no computador de desenvolvimento para concluir este passo a passo:

Conhecimento dos seguintes conceitos é útil, mas não necessário para concluir o passo a passo:

Noções básicas sobre o Assistente de componentes

O assistente que é demonstrado neste 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, chamada SiteColumnProjectWizard, que implementa o IWizard interface. Essa interface define os métodos que Visual Studio chama quando o assistente inicia e termina e em determinados momentos enquanto o assistente é executado.

Assistente de interface do usuário

Esta é uma janela baseada no WPF, chamada WizardWindow. Esta janela contém dois controles de usuário, chamados Page1 e Page2. Esses controles de usuário representam as duas páginas do assistente.

Esta explicação passo a passo, o RunStarted método da implementação do assistente exibe o Assistente de interface do usuário.

Modelo de dados do Assistente

Esta é uma classe intermediária, chamada SiteColumnWizardModel, que fornece uma camada entre o Assistente de interface do usuário e a implementação do assistente. Este exemplo usa essa classe para ajudar a abstrair a implementação do assistente e o Assistente de interface do usuário de outros; Essa classe não é um componente obrigatório de todos os assistentes.

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

Assinatura do gerente de projeto

Esta é uma classe auxiliar, chamada ProjectSigningManager, que é usado 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 os métodos usados pelo modelo de dados do Assistente para chamar o site local do SharePoint durante a execução do assistente. Porque os comandos do SharePoint devem ter como destino o.NET Framework 3.5, esses comandos são implementados em um assembly diferente do resto do código do assistente.

A criação de projetos

Para concluir este passo a passo, você precisa adicionar vários projetos na solução de SiteColumnProjectItem que você criou na Demonstra Passo a passo: A criação de um Item de projeto da coluna de Site com um modelo de projeto, parte 1:

  • Um projeto do WPF. Você implementará o IWizard interface e definir o Assistente de interface do usuário neste projeto.

  • Um projeto de biblioteca de classe que define os comandos do SharePoint. Este projeto deve usar o.NET Framework 3.5.

Inicie o passo a passo através da criação de projetos.

Para criar o projeto do WPF

  1. Abra a solução de SiteColumnProjectItem em Visual Studio.

  2. Em Solution Explorer, o botão direito do mouse no nó da solução, aponte para Adde em seguida, clique em Novo projeto.

    ObservaçãoObservação

    Em projetos de Visual Basic, o nó de solução aparece somente quando o Always show solution caixa de seleção estiver marcada na Geral, projetos e soluções, caixa de diálogo Options.

  3. No Add New Project caixa de diálogo caixa, expanda o Visual C# ou Visual Basic nós e clique Windows.

  4. Na caixa de combinação na parte superior do Add New Project caixa de diálogo caixa, certifique-se de que .NET Framework 4 está selecionada.

  5. Selecione o Biblioteca de controle de usuário do WPF o modelo de projeto.

  6. No nome , digite ProjectTemplateWizard.

  7. Clique em OK.

    Visual StudioAdiciona o ProjectTemplateWizard o projeto à solução.

  8. Exclua o arquivo de UserControl1.xaml do projeto.

Para criar o projeto de comandos do SharePoint

  1. Em Solution Explorer, o botão direito do mouse no nó da solução, aponte para Adde em seguida, clique em Novo projeto.

  2. No Add New Project caixa de diálogo caixa, expanda Visual C# ou Visual Basice em seguida, clique em Windows.

  3. Clique o Biblioteca de classe o modelo de projeto.

  4. Na caixa de combinação na parte superior da caixa de diálogo, selecione .NET Framework 3.5.

  5. No nome , digite SharePointCommands.

  6. Clique em OK.

    Adiciona a Visual Studio a SharePointCommands o projeto à solução e abre o arquivo de código padrão Class1.

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

Configurando os projetos

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

Para configurar o projeto de Assistente

  1. Em Solution Explorer, com o botão direito do ProjectTemplateWizard nó de projeto e, em seguida, clique em Propriedades.

  2. No Project Designer, alterar a estrutura de destino a partir do.NET Framework 4 o perfil do cliente para o.NET Framework 4. Em projetos do Visual C#, você pode fazer isso no aplicativo guia; para projetos de Visual Basic, você pode fazer isso no compilar guia. Para obter mais informações, consulte Como: Destino de um específico.NET Framework versão ou perfil.

    ObservaçãoObservação

    Por padrão, quando você cria um novo projeto voltado para o.NET Framework 4, o projeto destina-se o perfil do cliente. Este passo a passo requer a versão completa.NET Framework 4.

  3. No projeto ProjectTemplateWizard, adicione um novo Janela (WPF) item ao projeto. Nomeie o item WizardWindow.

  4. Adicione duas novas Controle de usuário (WPF) itens ao projeto. Nomeie esses itens Página1 e Página2.

  5. Adicione os quatro arquivos de código com os seguintes nomes:

    • SiteColumnProjectWizard

    • SiteColumnWizardModel

    • ProjectSigningManager

    • CommandIds

  6. No menu Project, escolha Add Reference.

  7. Sobre o .NET guia, pressione CTRL e clique os assemblies a seguir e clique em OK:

    • EnvDTE

    • Microsoft.VisualStudio.OLE.Interop

    • Microsoft.VisualStudio.SharePoint

    • Microsoft.VisualStudio.Shell.10.0

    • Microsoft.VisualStudio.Shell.Interop.10.0

    • Microsoft.VisualStudio.TemplateWizardInterface

  8. Em Solution Explorer, na referências a pasta para o projeto ProjectTemplateWizard, clique em EnvDTE.

    ObservaçãoObservação

    Em projetos de Visual Basic, você deve clicar na Mostrar todos os arquivos botão no Solution Explorer para ver o referências pasta.

  9. No Propriedades janela, alterar o Incorporar tipos de interoperabilidade propriedade para False.

  10. Se você estiver desenvolvendo um projeto de Visual Basic, importar o ProjectTemplateWizard o namespace em seu projeto usando o Project Designer. Para obter mais informações, consulte Como: Adicionar ou remover Namespaces (Visual Basic) importados.

Para configurar o projeto de SharePointCommands

  1. No SharePointCommands de projeto, adicione um arquivo de código, chamado de comandos.

  2. Em Solution Explorer, clique na SharePointCommands no nó do projeto.

  3. No menu Project, selecione Add Existing Item.

  4. No Add Existing Item caixa de diálogo, navegue até a pasta que contém os arquivos de código para o projeto ProjectTemplateWizard.

  5. Selecione o arquivo de código CommandIds.

  6. Clique no menu drop-down para o Add botão e selecione Add As Link.

    Visual StudioAdiciona o arquivo de código para o projeto de SharePointCommands como um link. Isso significa que o arquivo de código está localizado no projeto ProjectTemplateWizard, mas o código no arquivo também é compilado no projeto SharePointCommands.

  7. No menu Project, escolha Add Reference.

  8. Sobre o .NET guia, pressione CTRL e selecione os seguintes assemblies e clique OK:

    • Microsoft. SharePoint

    • Microsoft.VisualStudio.SharePoint.Commands

Criação do modelo do assistente, a assinatura do gerente e IDs de comando do SharePoint

Adicione código para o projeto de ProjectTemplateWizard para implementar os seguintes componentes em uma amostra:

  • As IDs de comando do SharePoint. Essas são as seqüências de caracteres que identificam os comandos do SharePoint são usados pelo assistente. Posteriormente nesta explicação passo a passo, você irá adicionar código ao projeto para implementar os comandos SharePointCommands.

  • O modelo de dados do assistente.

  • O gerente de projeto de assinatura.

Para obter mais informações sobre esses componentes, consulte Noções básicas sobre o Assistente de componentes.

Para definir as IDs de comando do SharePoint

  1. No projeto ProjectTemplateWizard, abra o arquivo de código de CommandIds.

  2. Substitua todo o conteúdo desse 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 de Assistente

  1. Abra o arquivo de código SiteColumnWizardModel.

  2. Substitua todo o conteúdo desse 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 gerente de projeto de assinatura

  1. Abra o arquivo de código ProjectSigningManager.

  2. Substitua todo o conteúdo desse 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 a interface do Assistente

Adicionar o XAML para definir a interface do usuário da janela do assistente e os controles de usuário de duas que fornecem a interface do usuário para as páginas do assistente e, em seguida, adicione código para definir o comportamento dos controles de usuário e a janela. O assistente que você criar é semelhante o assistente interno para projetos do SharePoint no Visual Studio 2010.

ObservaçãoObservação

Nas etapas a seguir, o projeto terá alguns erros de compilação após adicionar o código ou XAML ao seu projeto. Esses erros desaparecem quando você adiciona o código em etapas posteriores.

Para criar a janela do Assistente de interface do usuário

  1. No projeto ProjectTemplateWizard, clique duas vezes no arquivo WizardWindow.xaml para abrir a janela no designer.

  2. No modo de exibição XAML do designer, substitua o XAML atual com o seguinte XAML. O XAML define uma interface de usuário inclui um título, um Grid que contém as páginas do assistente e os 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.10.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 nesse XAML é derivada de DialogWindow classe de base. Quando você adiciona uma caixa de diálogo do WPF personalizada para Visual Studio, é recomendável derivar de sua caixa de diálogo a partir dessa classe tenham um estilo consistente com as outras caixas de diálogo de Visual Studio e para evitar problemas de caixa de diálogo modal que possam ocorrer. Para obter mais informações, consulte How to: Create and Manage Dialog Boxes.

  3. Se você estiver desenvolvendo um projeto de Visual Basic, remova o ProjectTemplateWizard namespace da WizardWindow nome de classe a x:Class atributo da Window elemento. Essa é a primeira linha do XAML. Quando tiver terminado, a primeira linha deve ter aparência a seguir.

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

  5. Substitua todo o conteúdo desse 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 do Assistente da interface do usuário

  1. Clique duas vezes no arquivo Page1.xaml para abrir o controle de usuário no designer.

  2. No modo de exibição XAML do designer, substitua o XAML atual com o seguinte XAML. O XAML define uma interface de usuário inclui uma caixa de texto onde os usuários podem digitar a URL do site local que desejam usar para depuração e botões de opção para especificar se o projeto está em modo seguro.

    <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 de Visual Basic, remova o ProjectTemplateWizard namespace da Page1 nome de classe a x:Class atributo da UserControl elemento. Essa é a primeira linha do XAML. Quando tiver terminado, a primeira linha deve ter aparência a seguir.

    <UserControl x:Class="Page1"
    
  4. Abra o arquivo code-behind para o arquivo Page1.xaml.

  5. Substitua todo o conteúdo desse 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 do Assistente da interface do usuário

  1. Clique duas vezes no arquivo Page2.xaml para abrir o controle de usuário no designer.

  2. No modo de exibição XAML do designer, substitua o XAML atual com o seguinte XAML. O XAML define uma interface de usuário inclui uma lista suspensa para escolher o tipo base da coluna de site, uma caixa de combinação para especificar um grupo interno ou personalizado sob a qual exibir a coluna de site na Galeria e uma caixa de texto para especificar o nome da coluna de 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 de Visual Basic, remova o ProjectTemplateWizard namespace da Page2 nome de classe a x:Class atributo da UserControl elemento. Essa é a primeira linha do XAML. Quando tiver terminado, a primeira linha deve ter aparência a seguir.

    <UserControl x:Class="Page2"
    
  4. Abra o arquivo code-behind para o arquivo Page2.xaml.

  5. Substitua todo o conteúdo desse 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;
            }
        }
    }
    

O Assistente de implementação

Definir a funcionalidade principal do assistente, Implementando o IWizard interface. Essa interface define os métodos que Visual Studio chama quando o assistente inicia e termina e em determinados momentos enquanto o assistente é executado.

Para implementar o assistente.

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

  2. Substitua todo o conteúdo desse 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 os comandos do SharePoint

Crie dois comandos personalizados que chamam o modelo de objeto de servidor do SharePoint. Um comando determina se a URL do site que o usuário digita no assistente é válida. O outro comando obtém todos os tipos de campo do site do SharePoint especificado para que os usuários podem selecionar qual delas usar como base para sua nova coluna de site.

Para definir os comandos do SharePoint

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

  2. Substitua todo o conteúdo desse 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

Neste momento o passo a passo, todo o código para o assistente está agora no projeto. Construa o projeto para certificar-se de que ele foi compilado sem erros.

Para construir seu projeto.

  • Sobre o Build menu, selecione Build Solution.

Removendo o arquivo de key.snk do modelo de projeto

Em Demonstra Passo a passo: A criação de um Item de projeto da coluna de 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 de coluna do Site. Este arquivo key.snk não é mais necessário porque o assistente agora gera um novo arquivo de key.snk para cada projeto. Remova o arquivo de key.snk do modelo de projeto e remover referências a esse arquivo.

Para remover o arquivo de key.snk do modelo de projeto

  1. Em Solution Explorer, na SiteColumnProjectTemplate nó, com o botão direito do key.snk de arquivo e clique em Excluir. Na caixa de mensagem pede confirmação, clique em OK.

  2. Sob o SiteColumnProjectTemplate o nó, abra o arquivo SiteColumnProjectTemplate.vstemplate.

  3. Remova o seguinte elemento do arquivo.

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

  5. Sob o SiteColumnProjectTemplate o nó, abra o arquivo ProjectTemplate.csproj ou ProjectTemplate.vbproj.

  6. Remova os seguintes itens PropertyGroup elemento.

    <PropertyGroup>
      <SignAssembly>true</SignAssembly>
      <AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
    </PropertyGroup>
    
  7. Remova os seguintes itens None elemento.

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

Associando o Assistente de modelo de projeto

Agora que você implementou o assistente, você deve associar o assistente com o Coluna do Site o modelo de projeto. Há três procedimentos que devem ser concluídas para fazer isso:

  1. Assine o Assistente de assembly com um nome forte.

  2. Obtenha a chave pública token para o assembly do assistente.

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

Para assinar o Assistente de assembly com um nome forte

  1. Em Solution Explorer, com o botão direito do ProjectTemplateWizard no nó do projeto e clique em Propriedades.

  2. Clique na guia Signing.

  3. Marque a caixa de seleção Sign the assembly.

  4. Na lista suspensa Choose a strong name key file, selecione &lt;New...&gt;.

  5. No Create Strong Name Key caixa de diálogo caixa, digite um nome para o novo arquivo de chave e limpar o Protect my key file com uma senha caixa de seleção.

  6. Clique em OK.

  7. Sobre o Build menu, selecione Build Solution.

Para obter a chave pública token para o assembly do Assistente

  1. Abra uma janela de Prompt de comando Visual Studio.

  2. Execute o seguinte comando. Substitua o caminho para o Assistente de assembly com o caminho completo para o assembly de ProjectTemplateWizard.dll criado para o projeto de ProjectTemplateWizard no computador de desenvolvimento.

    sn.exe -T path to wizard assembly
    

    O token de chave público para o assembly de ProjectTemplateWizard.dll é gravado para a janela do Prompt de comando Visual Studio.

  3. Mantenha aberta a janela do Prompt de comando Visual Studio. Será necessário o token de chave público durante o próximo procedimento.

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

  1. Em Solution Explorer, expanda o SiteColumnProjectTemplate nó de projeto e abrir o arquivo SiteColumnProjectTemplate.vstemplate.

  2. Próximo ao final do arquivo, adicione o seguinte WizardExtension elemento entre o </TemplateContent> e </VSTemplate> marcas. Substituir o seu token valor o PublicKeyToken atributo com o token de chave público que você obteve 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 WizardExtension elemento, consulte Elemento WizardExtension (modelos de Visual Studio).

  3. Salve e feche o arquivo.

Adicionando parâmetros substituíveis ao arquivo elements no modelo de projeto

Adicione vários parâmetros substituíveis ao arquivo elements no projeto SiteColumnProjectTemplate. Esses parâmetros são inicializados na RunStarted método na SiteColumnProjectWizard classe definido anteriormente. Quando um usuário cria um projeto de coluna do Site, o Visual Studio substitui automaticamente esses parâmetros no arquivo elements no novo projeto com os valores que elas são especificadas no assistente.

Um parâmetro de substituição é um token que começa e termina com o caractere de cifrão ($). Além de definir seus próprios parâmetros substituíveis, você pode usar 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 parâmetros substituíveis para arquivo elements.

  1. Abra o arquivo elements XML no projeto SiteColumnProjectTemplate.

  2. Substitua o conteúdo desse arquivo 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 altera os valores da Name, DisplayName, Type, e Group atributos a parâmetros substituíveis personalizado.

  3. Salve e feche o arquivo.

Adicionando o Assistente para o pacote VSIX

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

Para adicionar o Assistente do pacote VSIX

  1. Em Solution Explorer, clique duas vezes o source.extension.vsixmanifest arquivo no projeto SiteColumnProjectItem.

    Visual Studio abre o arquivo no editor de manifesto.

  2. No conteúdo seção do editor, clique na Adicionar conteúdo botão.

  3. No Adicionar conteúdo na caixa de Selecione um tipo de conteúdo caixa de listagem, selecione Assistente de modelo.

  4. Em Selecionar uma fonte de, clique o projeto botão de opção e, em seguida, selecione ProjectTemplateWizard em que a caixa de listagem.

  5. Clique em OK.

  6. No editor de manifesto, clique na Adicionar conteúdo novamente.

  7. No Adicionar conteúdo na caixa de Selecione um tipo de conteúdo caixa de listagem, selecione Tipo de extensão personalizada.

    ObservaçãoObservação

    Este valor corresponde do CustomExtension elemento no arquivo extension.vsixmanifest. Este elemento Especifica uma extensão personalizada que você deseja incluir na extensão de Visual Studio. Para obter mais informações, consulte CustomExtension Element (VSX Schema).

  8. No tipo de caixa de texto, digite SharePoint.Commands.v4.

    ObservaçãoObservação

    Este valor corresponde do Type atributo da CustomExtension elemento no arquivo extension.vsixmanifest. O valor Sharepoint.Commands.v4 é necessária para todos os assemblies de extensão personalizada que contêm comandos personalizados do SharePoint.

  9. Em Selecionar uma fonte de, clique o projeto botão de opção e, em seguida, selecione SharePointCommands em que a caixa de listagem.

  10. Clique em OK.

  11. Sobre o Build menu, clique em Build Solution. Certifique-se de que a solução é compilado sem erros.

O Assistente de teste.

Agora você está pronto para testar o assistente. Primeiro, inicie a solução de SiteColumnProjectItem na instância experimental do Visual Studio de depuração. Em seguida, teste o Assistente para o projeto de coluna do Site na instância experimental do Visual Studio. Finalmente, construir e executar o projeto para verificar se a coluna de site funciona como esperado.

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

  1. Reinicie o Visual Studio com privilégios de administrador e abra a solução de SiteColumnProjectItem.

  2. No projeto ProjectTemplateWizard, abra o arquivo de código de SiteColumnProjectWizard e adicionar um ponto de interrupção para a primeira linha do código de RunStarted método.

  3. No menu Debug, clique em Exceptions.

  4. No exceções caixa de diálogo, certifique-se de que o Thrown e User-unhandled caixas de seleção para Common Language runtime Exceptions estão desmarcadas.

  5. Clique em OK.

  6. Pressione F5 para iniciar a depuração.

    Visual Studio instala a extensão %UserProfile%\AppData\Local\Microsoft\VisualStudio\10.0Exp\Extensions\Contoso\Site Column\1.0 e inicia uma instância experimental do Visual Studio. Você testará o item de projeto nesta instância do Visual Studio.

Para testar o assistente em Visual Studio

  1. Na instância experimental do Visual Studio, sobre o arquivo , aponte para novae, em seguida, clique em projeto.

  2. Expanda Visual C# ou Visual Basic (dependendo do idioma que oferece suporte a seu modelo de projeto), expanda SharePointe em seguida, clique em 2010.

  3. Na lista de modelos de projeto, clique em Coluna do Site.

  4. No nome , digite SiteColumnWizardTest.

  5. Clique em OK.

  6. Verificar que o código na instância de Visual Studio pára no ponto de interrupção que você definiu anteriormente na RunStarted método. Pressione F5 para continuar a depurar o projeto.

  7. No O Assistente para personalização do SharePoint, digite a URL do site que você deseja usar para depuração e clique em próximo.

  8. Na segunda página da O Assistente para personalização do SharePoint, faça as seguintes seleções:

    • Para tipo de, selecione Boolean na lista drop-down.

    • Para grupo, tipo Colunas do personalizadas para na caixa de combinação.

    • Para nome, tipo Coluna do meu para na caixa de texto.

  9. Clique em Finish.

    Um novo projeto aparece na Solution Explorer com um item de projeto chamado campo1, e Visual Studio abre o arquivo elements XML no editor. Verifique se que elements contém os valores que você especificou no assistente.

Para testar a coluna de site do SharePoint

  1. Na instância experimental do Visual Studio, pressione F5. A coluna de site é empacotada e implantada no site do SharePoint especificado pelo URL do Site a propriedade do projeto. O navegador da Web abre para a página padrão deste site.

    ObservaçãoObservação

    Se o Desativado de depuração de Script caixa de diálogo exibida, clique em Sim para continuar a depurar o projeto.

  2. Sobre o Ações do Site menu, clique em Configurações do Site.

  3. Em galerias, clique em colunas de Site.

  4. Na lista de colunas de site, verifique se há um Colunas do personalizadas para o grupo que contém uma coluna chamada Coluna do meu para.

  5. Feche o navegador da Web.

Limpando o computador de desenvolvimento

Após concluir o teste de item de projeto, remova o modelo de projeto da instância experimental do Visual Studio.

Para limpar o computador de desenvolvimento

  1. Na instância experimental do Visual Studio, sobre o Ferramentas menu, clique em Extension Manager.

    O Extension Manager abre a caixa de diálogo.

  2. Na lista de extensões, clique em Coluna do Sitee em seguida, clique em desinstalar.

  3. Na caixa de diálogo que aparece, clique em Sim para confirmar que você deseja desinstalar a extensão.

  4. Clique em Reiniciar agora para concluir a desinstalação.

  5. Feche as duas instâncias de Visual Studio (a instância experimental e a instância do Visual Studio que abriu a solução de SiteColumnProjectItem).

Consulte também

Tarefas

Como: Usar assistentes com modelos de projeto

Referência

Referência de esquema de modelo do Studio Visual

IWizard

Outros recursos

Demonstra Passo a passo: A criação de um Item de projeto da coluna de Site com um modelo de projeto, parte 1

Definindo tipos de Item de projeto do SharePoint personalizados

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