How to Register a Plug-in

banner art

[Applies to: Microsoft Dynamics CRM 4.0]

Find the latest SDK documentation: CRM 2015 SDK

The code below includes a sample plug-in and installer. The RegisterSolution function is used to register the steps for the plug-in assembly.

This sample code can be found in the following files in the SDK download:

SDK\Server\FullSample\PluginInstaller\CS\Installer.cs

This sample uses some of the capabilities of the plug-in registration API. Notably absent are support for entity images, secure configuration, and invocation source. The interactive Plug-in Registration tool provided in the SDK supports the full range of plug-in registration capabilities.

  

Example

[C#]
namespace Microsoft.Crm.Sdk.Plugin.Installer
{
   using System;
   using System.Collections;
   using System.Collections.Generic;
   using System.ComponentModel;
   using System.Configuration.Install;
   using System.Globalization;
   using System.IO;
   using System.Net;
   using System.Reflection;
   using System.Text;

   using Microsoft.Crm.Sdk;
   using Microsoft.Crm.SdkTypeProxy;

   [RunInstaller(true)]
   public class HelloWorldInstaller : Installer
   {
      // Install, Commit, Rollback, and Uninstall methods
      public override void Install(IDictionary state)
      {
         base.Install(state);

         Initialize();

         Assembly assembly = GetType().Assembly;

         List<SdkMessageProcessingStepRegistration> stepRegistrations = 
             GetStepsInformation(assembly);

         Guid id = RegisterSolution(assembly, "My Solution", stepRegistrations);

         state["SolutionId"] = id;
      }

      public override void Uninstall(IDictionary state)
      {
         Initialize();

         Guid solutionId = (Guid)state["SolutionId"];
         UnregisterSolution(solutionId);

         base.Uninstall(state);
      }

      private void Initialize()
      {
            ICredentials credentials = CredentialCache.DefaultCredentials;

            if (Context.Parameters.ContainsKey("username") &&
                Context.Parameters.ContainsKey("password") &&
                Context.Parameters.ContainsKey("domain"))
            {
                credentials = new NetworkCredential(
                    Context.Parameters["username"],
                    Context.Parameters["password"],
                    Context.Parameters["domain"]);
            }

         CrmAuthenticationToken token = new CrmAuthenticationToken();
         token.AuthenticationType = AuthenticationType.AD;

            // TODO Change the organization name or use the Discovery Web service
            // to find an organization at run-time.
            token.OrganizationName = "Adventure Works Cycle";

         _service = new CrmService();
         _service.Url = Context.Parameters["url"];
         _service.Credentials = credentials;
         _service.CrmAuthenticationTokenValue = token;
      }

      private void UnregisterSolution(Guid solutionId)
      {
         UnregisterSolutionRequest request = new UnregisterSolutionRequest();
         request.PluginAssemblyId = solutionId;

         _service.Execute(request);
      }

      private Guid RegisterSolution(Assembly assembly, string description,
            List<SdkMessageProcessingStepRegistration> stepRegistrations)
      {
         RegisterSolutionRequest request = new RegisterSolutionRequest();
         request.PluginAssembly = GetPluginAssembly(assembly);
         request.Steps = stepRegistrations.ToArray();

         RegisterSolutionResponse response = 
            (RegisterSolutionResponse)_service.Execute(request);
         return response.PluginAssemblyId;
      }

      private static string GetPublicKeyToken(Assembly assembly)
      {
         Byte[] tokenBytes = assembly.GetName().GetPublicKeyToken();

         StringBuilder builder = new StringBuilder(32);
            foreach (byte b in tokenBytes)
            {
                builder.Append(b.ToString("x").PadLeft(2, '0'));
            }

         return builder.ToString();
      }

      private static DynamicEntity GetPluginAssembly(Assembly assembly)
      {
         DynamicEntity library = new DynamicEntity();
         library.Name = EntityName.pluginassembly.ToString();

         library["name"] = assembly.GetName().Name;
         library["sourcetype"] = new Picklist(0 /* AssemblySourceType.Database */);
            library["publickeytoken"] = GetPublicKeyToken(assembly);
            // The following property values are defined in the AssemblyInfo.cs file. 
            library["culture"] = assembly.GetName().CultureInfo.ToString();
            library["version"] = assembly.GetName().Version.ToString();

         FileInfo fi = new FileInfo(assembly.Location);
         using (FileStream fs = File.OpenRead(assembly.Location))
         {
            byte[] buffer = new byte[fi.Length];

            fs.Read(buffer, 0, (int)fi.Length);

            int outputSize = (int)Math.Ceiling(fi.Length / 3d) * 4;
            char[] output = new char[outputSize];

            Convert.ToBase64CharArray(buffer, 0, buffer.Length, output, 0);

            library["content"] = new string(output);
         }

         return library;
      }

      private static List<SdkMessageProcessingStepRegistration> 
          GetStepsInformation(Assembly assembly)
      {
         List<SdkMessageProcessingStepRegistration> steps = 
             new List<SdkMessageProcessingStepRegistration>();
         foreach (Type t in assembly.GetExportedTypes())
         {
            Type plugin = t.GetInterface("Microsoft.Crm.Sdk.IPlugin");

            if (plugin != null)
            {
               foreach (StepAttribute step1 in
                   t.GetCustomAttributes(typeof(StepAttribute), true))
               {
                  SdkMessageProcessingStepRegistration s = 
                      new SdkMessageProcessingStepRegistration();
                  s.CustomConfiguration = step1.Configuration;
                  s.Description = string.Format(CultureInfo.InvariantCulture,
                      "{0}.{1} invokes {2} plug-in",
                      step1.PrimaryEntityName, step1.MessageName, t.FullName);
                  s.FilteringAttributes = step1.FilteringAttributes;
                  s.Mode = step1.Mode;
                  s.MessageName = step1.MessageName;
                  s.PrimaryEntityName = step1.PrimaryEntityName;
                  s.Stage = step1.Stage;
                  s.SupportedDeployment = step1.SupportedDeployment;
                  s.PluginTypeName = t.FullName;
                  s.PluginTypeFriendlyName = Guid.NewGuid().ToString("N");

                  steps.Add(s);
               }
            }
         }
         return steps;
      }

      private CrmService _service;
   }


    [Serializable]
    [AttributeUsageAttribute(AttributeTargets.All, Inherited = true,
        AllowMultiple = false)]
    public class StepAttribute : Attribute
    {
        public int Stage
        {
            get { return _stage; }
            set { _stage = value; }
        }

        public int Mode
        {
            get { return _mode; }
            set { _mode = value; }
        }

        public int SupportedDeployment
        {
            get { return _supportedDeployment; }
            set { _supportedDeployment = value; }
        }

        public int Rank
        {
            get { return _rank; }
            set { _rank = value; }
        }

        public string MessageName
        {
            get { return _messageName; }
            set { _messageName = value; }
        }

        public string PrimaryEntityName
        {
            get { return _primaryEntityName; }
            set { _primaryEntityName = value; }
        }

        public string SecondaryEntityName
        {
            get { return _secondaryEntityName; }
            set { _secondaryEntityName = value; }
        }

        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }

        public string Configuration
        {
            get { return _configuration; }
            set { _configuration = value; }
        }

        public string ImpersonationUserID
        {
            get { return _impersonationUserID; }
            set { _impersonationUserID = value; }
        }

        public string FilteringAttributes
        {
            get { return _filteringAttributes; }
            set { _filteringAttributes = value; }
        }


        public StepAttribute( string messageName,
                              string primaryEntityName
                            ): this(messageName, primaryEntityName,
                                    MessageProcessingStage.AfterMainOperationOutsideTransaction) { }

        public StepAttribute( string messageName,
                              string primaryEntityName,
                              int stage
                            ): this(messageName, primaryEntityName, stage,
                                    MessageProcessingMode.Synchronous) { }

        public StepAttribute( string messageName,
                              string primaryEntityName,
                              int stage,
                              int mode
                            ): this(messageName, primaryEntityName, stage, mode, 0) { }

        public StepAttribute( string messageName,
                              string primaryEntityName,
                              int stage,
                              int mode,
                              int supportedDeployment
                            ): this(messageName, primaryEntityName,
                                    stage, mode, supportedDeployment, 0) { }

        public StepAttribute( string messageName,
                              string primaryEntityName,
                              int stage,
                              int mode,
                              int supportedDeployment,
                              int rank
                            ): this(messageName, primaryEntityName, stage,
                                    mode, supportedDeployment, rank, null) { }

        public StepAttribute( string messageName,
                              string primaryEntityName,
                              int stage,
                              int mode,
                              int supportedDeployment,
                              int rank,
                              string description
                            ): this(messageName, primaryEntityName, stage, mode,
                                    supportedDeployment, rank, description, null) { }

        public StepAttribute( string messageName,
                              string primaryEntityName,
                              int stage,
                              int mode,
                              int supportedDeployment,
                              int rank,
                              string description,
                              string configuration
                            ): this(messageName, primaryEntityName, stage, mode, 
                                    supportedDeployment, rank, description, configuration, null) { }

        public StepAttribute( string messageName,
                              string primaryEntityName,
                              int stage,
                              int mode,
                              int supportedDeployment,
                              int rank,
                              string description,
                              string configuration,
                              string impersonationUserId
                            )
        {
            MessageName = messageName;
            PrimaryEntityName = primaryEntityName;
            Stage = stage;
            Mode = mode;
            SupportedDeployment = supportedDeployment;
            Rank = rank;
            Description = description;
            Configuration = configuration;
            ImpersonationUserID = impersonationUserId;
        }

        private int _stage;
        private int _mode;
        private int _supportedDeployment;
        private int _rank;
        private string _messageName;
        private string _primaryEntityName;
        private string _secondaryEntityName;
        private string _description;
        private string _configuration;
        private string _impersonationUserID;
        private string _filteringAttributes;
    }
}

See Also

Reference

© 2010 Microsoft Corporation. All rights reserved.