5 out of 6 rated this helpful - Rate this topic

Plug-ins, Part 2: Development and Deployment (Microsoft Dynamics CRM 4.0)

Peter Hecke
Microsoft Corporation

October 2009

Summary

A plug-in is custom computer code that is compiled and registered with Microsoft Dynamics CRM 4.0 to change or extend the system’s functionality. This article represents part 2 in a multi-part Getting Started series of articles about how to extend Microsoft Dynamics CRM through the development and deployment of plug-ins. Part 1 in the series covered the basics about what plug-ins are, what they can do, when to use them, and the environment in which they execute. This article discusses development, deployment, and debugging of plug-ins. In addition, this article contains information about tools and techniques that can improve your efficiency and development experience as you develop plug-ins.

Applies To

Microsoft Dynamics CRM 4.0

Visual Studio 2005

Visual Studio 2008

Introduction

In this multi-part Getting Started series of articles on plug-in technology, I will present a subset of the Microsoft Dynamics CRM SDK technical information in an easy to understand format. Along the way I hope to add new information to go beyond just understanding the technology. As the author of the plug-in section in the SDK documentation, I have learned ways to improve the plug-in development environment, how to improve plug-in design for increased performance, and more. In this article series, I hope to pass on some of this information and ease the learning curve associated with plug-in development.The information in this article is written to augment the plug-in information presented in the Microsoft Dynamics CRM SDK.

Prerequisites

This article assumes that you know how to write applications in Microsoft Visual C# or Microsoft Visual Basic .NET using the Microsoft .NET Framework. You should also have read the first article in this series called Plug-ins Part 1: The Big Picture.

To be able to write plug-in code, you must download and extract the Microsoft Dynamics CRM 4.0 Microsoft Dynamics CRM SDK and install Visual Studio 2005 or 2008 on your development computer. To deploy and execute plug-ins, you will need access to a Microsoft Dynamics CRM On-premise or Internet-facing deployment (IFD) server. Currently, Microsoft Dynamics CRM Online does not support uploading custom code (plug-ins or custom workflow activities) to the server. If you want to extend the functionality of Microsoft Dynamics CRM Online, you can do so by writing workflows.

Setting up Your Development Environment

Setting up an efficient development environment can improve your development experience by letting you write code faster, with less frustration and run-time errors. In the following sections, you will learn about tools and techniques that you can use to develop plug-ins. You may also want to search the Internet for tools or techniques that other developers are using to improve their experience. While you are at it, give the Bing search engine a try.

You can set up your development environment on any computer that is running Windows XP, Windows Vista, Windows Server 2003, or Windows Server 2008. You can also develop directly on your Microsoft Dynamics CRM server. However, we strongly recommend that you do not develop on a production Microsoft Dynamics CRM company server because plug-ins can affect performance and stability on the system.

noteNote
For more information, see the MSDN article: Setting Up Your Development Environment.

Installing the SDK

The Microsoft Dynamics CRM SDK contains programming documentation, source code samples and tools, and the required assemblies to develop plug-ins. You can download the latest version of the SDK from here. Note that we update the SDK several times a year so it is good to check the Microsoft download site periodically for updates. You can also subscribe to the Microsoft Dynamics CRM Team blog, where information about SDK updates is posted.

After you download the SDK, double-click the program in Windows Explorer. You will be prompted for a folder on the local computer to unzip the SDK to. Provide a folder path and then click OK.

Afterwards, in Windows Explorer, open the crmsdk4.chm file to view the SDK programming documentation. The SDK documentation, without the code sample directory or assemblies, is also available on MSDN.

Installing the Plug-in Template

The latest version of the SDK contains a Microsoft Visual Studio template containing basic plug-in code that makes it easier to start writing a plug-in. Note that installing the template is not required for developing plug-ins, but is highly recommended. Feel free to modify and improve the template according to your needs.

A version of the template for both Visual C# and Microsoft Visual Basic .NET is provided in the SDK. The plug-in template is located in the folder SDK\visualstudiotemplates\[cs|vb]\plugin. Read and follow the instructions in the readme.doc file in that same folder to install the template.

To use the template, you just select the MSCRM Plug-in template when you create a new Microsoft Visual Studio project in either Visual C# or Microsoft Visual Basic .NET. A version of the template for both Visual C# and Microsoft Visual Basic .NET is provided in the SDK.

676afad7-729f-48fb-8c36-fa82cd0b665b

Building the Sample Tools

You will most likely want to build and use the Plug-in Registration tool provided as source code in the SDK. Your other option is to write your own installer. However, the tool simplifies the registration of plug-ins on the Microsoft Dynamics CRM server. I will provide more information about registering plug-ins later in this article. For now, open the SDK\tools\pluginregistration folder and follow the instructions in the readme.doc file in that folder to build the tool.

Other Useful Tools

There are other tools available for free on the Internet that can greatly improve your Microsoft Dynamics CRM development experience. Some of the tools are discussed here.

Microsoft Dynamics CRM Developer Toolkit
The toolkit provides a tool to generate initial code for a plug-in. Refer to the plug-in code generation feature for more information.

DynamicEntity Visualizer
During plug-in execution, business data for the entity type that is currently being processed by Microsoft Dynamics CRM is passed to plug-ins in an instance of the DynamicEntity class. The DynamicEntity Visualizer makes it much easier to browse the data in a DynamicEntity object when using the Microsoft Visual Studio debugger.

78470c6a-b15c-4aaf-9a44-0b3cc513c8d5

Plug-in Samples
This download contains several useful sample plug-ins. The LogContextToCRM plug-in is especially useful to visualize what entity type and message combination is being processed by Microsoft Dynamics CRM. The LogContextToCRM plug-in logs information (context) that is passed to registered plug-ins whenever a program or Web page makes a Web service method call or the user initiates an operation in the Web application. You can view this context log in a data grid view of the Microsoft Dynamics CRM Web application.

Snippet Designer
This tool enables you to create code snippets in Microsoft Visual Studio for common programming tasks. You can use this to create a library of useful code snippets to streamline your plug-in or application development.

8e8a15bb-15fe-417c-b8a5-640ab731ff8a

Setup and Configuration

In this section I am going to discuss setting up a Microsoft Dynamics CRM test server and creating a new organization for testing plug-ins. Later in the article I will show how to configure Microsoft Visual Studio to automatically register and deploy your plug-in whenever you do a build of your plug-in project.

Setting up a Test Server

You can set up a dedicated Microsoft Dynamics CRM test server for development. For my development environment, I have installed Microsoft Dynamics CRM in a virtual machine running on Windows Server 2008 with Hyper-V. My test server is a 64-bit quad-core computer with 8GB memory and two SATA drives. This server configuration enables me to run up to 3 or 4 virtual machines at the same time. If needed, I could set up a virtual network of computers where one computer is the domain controller, another computer is the Microsoft Dynamics CRM server, and another computer runs Microsoft SQL Server. In the past I have used Microsoft Virtual PC 2007 and Microsoft Virtual Server 2005 R2 to host the virtual machines. I find that Hyper-V is the better hosting environment, although the other two products I mentioned will do the job and are supported on either a desktop or server operating system.

A key benefit of using virtual machines to run Microsoft Dynamics CRM is that you can take “snapshots” of the virtual machine at any point in time. This lets you easily restore your Microsoft Dynamics CRM server to a previous configuration. For example, say that you have performed some Microsoft Dynamics CRM Web application user interface customizations and added or deleted test data. If you had taken a snapshot of the virtual machine before your changes were made, you could just restore the virtual machine to its previous state to wipe out those changes.

If you have logon access to Microsoft Partner Source, you can download a prebuilt Microsoft Dynamics CRM 4.0 virtual machine from that site.

Whether installing Microsoft Dynamics CRM on actual computer hardware or in a virtual environment, the Microsoft Dynamics CRM product needs 1536MB to 2GB of available memory to run with decent performance. If you have never installed Microsoft Dynamics CRM, look in the Microsoft Dynamics CRM Implementation Guide for installation and configuration instructions.

Creating Organizations

If you are using the enterprise edition of Microsoft Dynamics CRM, it is useful to create an organization for testing. In Microsoft Dynamics CRM, all plug-ins, workflows, GUI customizations, and business data are organization-specific. By creating an organization for testing, you can isolate any development changes you make to that organization. This is helpful if there are several developers that use the same test server. If needed, each developer can work within his or her own organization.

At some point in your development work, you can delete your test organization and create a new one if you need to. For more information about how to manage organizations, see the Deployment Manager online Help. The Deployment Manager tool is available from the Microsoft Dynamics CRM programs submenu on the Microsoft Dynamics CRM server. Note that only an administrator of the server can use Deployment Manager.

In addition to a test organization, I also create another organization that contains sample data that I use for screen snapshots in product documentation.

Designing and Writing a Plug-in

Now that we have an effective plug-in development and test environment set up, we can move on to writing plug-ins. In Part 1 of this article series, I covered such concepts as messages and requests, the event pipeline, execution context, input and output parameters, and images. I will now use some of these concepts as I describe how to write a plug-in.

noteNote
More information, see the SDK topic: Quickstart Guide to Plug-in Development.

Using the Plug-in Template

The plug-in template contains useful code to handle the following typical programming tasks:

  • Checking that the plug-in is registered on the correct entity and message combination

  • Getting a reference to the entity so that you can access the entity’s properties

  • Creating or obtaining the Web service proxy

  • Handling exceptions

To begin writing a plug-in using the plug-in template, do the following:

  1. Create a new project in Microsoft Visual Studio and select the MSCRM Plug-in template in the New Project dialog box.

  2. Add references to the project for the Microsoft.Crm.Sdk.dll and Microsoft.Crm.SdkTypeProxy.dll assemblies located in the bin folder of the SDK download.

  3. If you are writing a plug-in for the child pipeline and want to access the Microsoft Dynamics CRM Web services from the plug-in, add Web References for those services.

  4. In the project’s properties dialog box, set the default namespace to the namespace of your plug-in class. Also make sure that assembly will be signed by checking Sign the assembly under the Signing tab.

  5. Add the required code to the plug-in according to business needs.

For example, if we copy the code snippet from one of the scenarios into the plug-in template, the Execute method would be as follows.


public void Execute(IPluginExecutionContext context)
{
    DynamicEntity entity = null;

    // Check if the InputParameters property bag contains a target
    // of the current operation and that target is of type DynamicEntity.
    if (context.InputParameters.Properties.Contains(ParameterName.Target) &&
       context.InputParameters.Properties[ParameterName.Target] is DynamicEntity)
    {
        // Obtain the target business entity from the input parmameters.
        entity = (DynamicEntity)context.InputParameters.Properties[ParameterName.Target];

        // (Optional) Test for an entity type and message supported by your plug-in.
        if (entity.Name != EntityName.account.ToString()) { return; }
        if (context.MessageName != MessageName.Create.ToString()) { return; }
    }
    else
    {
        return;
    }

    try
    {
        // Create a task activity to follow up with the account customer in 7 days.
        DynamicEntity followup = new DynamicEntity();
        followup.Name = EntityName.task.ToString();

        followup.Properties = new PropertyCollection();
        followup.Properties.Add(new StringProperty("subject", "Send e-mail to the new customer."));
        followup.Properties.Add(new StringProperty("description",
            "Follow up with the customer. Check if there are any new issues that need resolution."));

        followup.Properties.Add(new CrmDateTimeProperty("scheduledstart",
            CrmTypes.CreateCrmDateTimeFromUniversal(DateTime.Now.AddDays(7))));
        followup.Properties.Add(new CrmDateTimeProperty("scheduledend",
            CrmTypes.CreateCrmDateTimeFromUniversal(DateTime.Now.AddDays(7))));

        followup.Properties.Add(new StringProperty("category", context.PrimaryEntityName));

        // Refer to the new account in the task activity.
        if (context.OutputParameters.Properties.Contains("id"))
        {
            Lookup lookup = new Lookup();
            lookup.Value = new Guid(context.OutputParameters.Properties["id"].ToString());
            lookup.type = EntityName.account.ToString();

            followup.Properties.Add(new LookupProperty("regardingobjectid", lookup));
        }

        TargetCreateDynamic targetCreate = new TargetCreateDynamic();
        targetCreate.Entity = followup;

        // Create the request object.
        CreateRequest create = new CreateRequest();
        create.Target = targetCreate;

        // Execute the request.
        ICrmService service = context.CreateCrmService(true);
        CreateResponse created = (CreateResponse)service.Execute(create);
    }
    catch (System.Web.Services.Protocols.SoapException)
    {
        // For this example, just re-throw the exception.
        throw;
    }
}

Accessing the Web Services

To access the Web services from a plug-in, you may have to authenticate with Microsoft Dynamics CRM to obtain a proxy to the service. If your plug-in is registered with and executes in the parent pipeline, authentication has already been done by the platform when your plug-in is executed. You can obtain the service proxy to access the Web services by calling the CreateCrmService or CreateMetadataService methods of the IPluginExecutionContext instance that is passed as a parameter to your plug-in’s Execute method. This is shown in the previous code sample.

On the other hand, if your plug-in is registered with and executes in the child pipeline, you must create your own Web service proxy instance and authenticate the system user account under which the plug-in is to make Web service calls. I have provided two private methods named CreateCrmService and CreateMetadataService in the plug-in template code that, when they are called, will handle creating the proxies for you. Look at the code comments and methods in the template for more information.

After you have obtained a proxy instance, you can call Web service methods to send message requests to the platform. However, plug-ins are restricted to a subset of all available messages supported by the platform. A list of all plug-in supported messages is provided in a Microsoft Office Excel 2007 workbook named “Plug-in message-entity table.xls” that can be found in the tools folder of the SDK download.

TipTip
With respect to plug-in performance, it is better to access the Web services from a plug-in registered in the parent pipeline because authentication has already been done when your plug-in executes. Authentication takes a relatively long time. If your plug-in design allows, restrict child pipeline registered plug-ins to tasks such as reading and modifying context property data or other operations that do not require authentication.

noteNote
For more information, see the SDK topics: Web Services: CrmService, Web Services: MetadataService

Handling Exceptions

In your plug-in you may optionally catch and handle exceptions that are thrown from Microsoft Dynamics CRM or the .NET Framework. Microsoft Dynamics CRM throws exceptions of type System.Web.Services.Protocols.SoapException. If any exception is passed from the plug-in back to the Microsoft Dynamics CRM platform, the following behavior occurs:

  • The exception information is written to the operating system’s Application event log.

  • If the executing plug-in is registered in a pre-event stage of the parent pipeline, the core operation does not occur. If the plug-in is registered in the child pipeline, the core operation is rolled back.

  • Any plug-ins that are registered but have not yet executed will not run.

  • If the exception is of type InvalidPluginExecutionException, the exception’s message is displayed in a dialog box of the Web application to the user who caused the plug-in to run.

noteNote
For more information, see the SDK topic: Exception Handling Behavior

Common Plug-in Scenarios

I am now going to address several of the typical scenarios that you might want to write a plug-in for and describe how to write and register a plug-in to address those scenarios.

Modifying Entity Record Data

In this scenario, you want to modify or add one or more attributes of the entity type that is currently being processed by the execution pipeline.

For example, say that you want to generate or obtain a well-defined sequential account number for every new account and set the accountnumber property to that value. To do this in a plug-in, you would add or modify the accountnumber attribute in the DynamicEntity property bag as shown in the following code snippet.


if (entity.Properties.Contains("accountnumber"))
    // The user has entered an account number, so replace it.
    entity["accountnumber"] = GetNextAccountNumber();
else
    // No account number was specified by the user, so add one.
    entity.Properties.Add(new StringProperty("accountnumber", GetNextAccountNumber()));

The following table is an example of how the plug-in would be registered when you use the Plug-in Registration tool.

 

Registration Setting Setting Value Description

Message

Create

In this scenario, the plug-in is registered to execute when an account is created.

Primary Entity

account

In this scenario, the plug-in is registered to execute when an account is created.

Stage of Execution

Pre Stage

The plug-in executes before the core operation so the entity record is created with the added or modified attributes.

Execution Mode

Synchronous

Pre-event plug-ins are always synchronous.

Step Deployment

Server

Execute the plug-in on the server.

Triggering Pipeline

Parent

Execute the plug-in in the parent pipeline.

noteNote
For more information, see the SDK topic: Common Context.

Perform an Operation on a Different Entity Record

In this scenario, you want to perform a delete, modify, or other operation on an existing entity record other than the one that is currently being processed by the execution pipeline.

For example, say that whenever an account owner is changed, you want to re-assign all open tasks associated with that account to the new owner. The plug-in must find the GUIDs of all open tasks associated with that account by using the RetrieveMultiple method. For each task, the plug-in assigns the task to the new account owner, by using the Assign message.

The following table is an example of how the plug-in would be registered when you use the Plug-in Registration tool.

 

Registration Setting Setting Value Description

Message

Assign

In this scenario, the plug-in is registered to execute when an account is re-assigned to another user.

Primary Entity

account

In this scenario, the plug-in is registered to execute when an account is re-assigned to another user.

Stage of Execution

Post Stage

The plug-in executes after the account has been successfully assigned to another user. The assign is performed during the core operation stage.

Execution Mode

Synchronous or Asynchronous

If it is not critical that the tasks be re-assigned immediately after the account owner changes, use Asynchronous for improved Web application responsiveness.

Step Deployment

Server

Execute the plug-in on the server.

Triggering Pipeline

Parent

Execute the plug-in in the parent pipeline.

Interrupt the Core Operation

In this scenario, you want to check entity instance data that the user has filled out in the Web application’s create or update form for validity and cancel the core Microsoft Dynamics CRM operation if the data entered is not valid.

For example, if the user specifies a ZIP Code/Postal Code for an account, verify that the ZIP Code/Postal Code is valid. If the ZIP Code/Postal Code is not valid, cancel the core operation and display an error message by throwing an InvalidPluginExecutionException exception in the plug-in.


if (entity.Properties.Contains("address1_postalcode"))
{
    // The user has entered a zip code, so verify the value.
    if (!ValidateZipCode(entity["address1_postalcode"].ToString()))
        throw new InvalidPluginExecutionException("Please enter a valid zip code.");
}

The following table is an example of how the plug-in would be registered when you are using the Plug-in Registration tool.

 

Registration Setting Setting Value Description

Message

Create, Modify

In this scenario, the plug-in is registered to execute when the ZIP Code/Postal Code of an account is set or changed.

Primary Entity

account

In this scenario, the plug-in is registered to execute when the ZIP Code/Postal Code of an account is set or changed.

Stage of Execution

Pre Stage

The plug-in must execute before the core operation to cancel the operation.

Execution Mode

Synchronous

Pre-event plug-ins are always synchronous.

Step Deployment

Server

Execute the plug-in on the server.

Triggering Pipeline

Parent

Execute the plug-in in the parent pipeline.

noteNote
For more information, see the SDK topic: Exception Handling Behavior

Post Processing

In this scenario, you want to perform some other operation after the core operation has successfully completed.

For example, whenever an account is created, create an e-mail task for the account owner to follow up with the account primary contact in one week. Refer to the previous topic named “Designing and Writing a Plug-in” for sample code demonstrating this type of plug-in.

The following table is an example of how the plug-in would be registered when you are using the Plug-in Registration tool.

 

Registration Setting Setting Value Description

Message

Create

In this scenario, the plug-in is registered to execute when an account is created.

Primary Entity

account

In this scenario, the plug-in is registered to execute when an account is created.

Stage of Execution

Post Stage

The plug-in executes only after the account has been successfully created during the core operation.

Execution Mode

Synchronous or Asynchronous

There is no requirement to send out the e-mail immediately after the account is created. Use Asynchronous for improved Web application responsiveness.

Step Deployment

Server

Execute the plug-in on the server.

Triggering Pipeline

Parent

Execute the plug-in in the parent pipeline.

Identifying What Entity Record Data has Changed

In this scenario, you want to determine what data was changed by the user. For example, a business wants to audit business data changes. To determine what data has changed, you must register both pre and post entity images and do attribute value comparisons between these images to discover which attributes have changed.

The following table is an example of how the plug-in would be registered when you are using the Plug-in Registration tool.

 

Registration Setting Setting Value Description

Message

Modify

In this scenario, the plug-in is registered to execute after data in an entity has changed.

Primary Entity

(any)

In this scenario, the plug-in is registered to execute after data in an entity has changed.

Stage of Execution

Post Stage

The plug-in executes after the entity has been successfully modified during the core operation.

Execution Mode

Synchronous or Asynchronous

If it is not critical that the audit be done immediately after the entity attributes change, use Asynchronous for improved Web application responsiveness.

Step Deployment

Server

Execute the plug-in on the server.

Triggering Pipeline

Parent

Execute the plug-in in the parent pipeline.

noteNote
In the Plug-in Registration tool, register images by selecting the Register New Image menu item.

Building a Plug-in

You build the plug-in project just like any other Microsoft Visual Studio project. However, one thing that you must do is to sign the assembly. Only plug-ins from signed assemblies are loaded and executed by Microsoft Dynamics CRM.

To sign an assembly, follow these steps.

  1. Open the property page of your plug-in project by right-clicking the project name in Solution Explorer and selecting Properties from the shortcut menu.

  2. In the property page, select the Signing tab.

  3. Select the Sign the assembly check box.

  4. Under Choose a string name key file, select <New…> in the drop-down box.

  5. In the dialog box, type a name for the key file, make sure Protect my key file with a password is not checked, and then click OK.

  6. Build the project.

Deploying a Plug-in

Deployment involves copying one or more plug-in assemblies to the Microsoft Dynamics CRM server or to the computer that is running the Microsoft Dynamics CRM for Microsoft Office Outlook with Offline Access product, depending on whether you are deploying an online (server based) or offline (mobile client based) plug-in. If your plug-in requires other custom assemblies, those assemblies must be deployed to the Global Assembly Cache (GAC) on the target computer. In addition, each plug-in must be registered with the Microsoft Dynamics CRM server.

There are two kinds of plug-in deployments: database or on-disk. An on-disk deployment is used when you are developing and debugging a plug-in. After building a plug-in assembly, you must copy that assembly to a specific folder location on the server or client computer’s disk. A database deployment stores a copy of your plug-in assembly in the Microsoft Dynamics CRM server database and is the preferred storage method for a production version of your plug-in. A database deployed plug-in assembly will be automatically deployed to each Microsoft Dynamics CRM server in a datacenter.

Notice that there are security permissions that restrict who can deploy and register plug-ins. For more information, see the SDK topic Registering Plug-ins.

Deploying Plug-in Assemblies

If you are deploying your plug-in to the Microsoft Dynamics CRM database, you can skip this section. The assembly bits are automatically copied to and stored in the database as part of the plug-in registration process. Otherwise, for on-disk deployment, you must copy your custom plug-in assembly to the <crm-root>\server\bin\assembly folder for a server deployment or to <crm-root>\client\bin\assembly for an Outlook client (offline) plug-in deployment. For the default installation, the folder path is C:\Program Files\Microsoft CRM\{server|client}\bin\assembly. That is the folder where Microsoft Dynamics CRM looks for all on–disk registered plug-ins and also Microsoft Dynamics CRM 3.0 callouts. If you are planning on debugging your plug-in, also copy the plug-in assembly’s .pdb file to that location.

There is an issue that you will experience as you deploy your plug-in assembly on-disk. Let’s assume that you have deployed, registered, and executed your plug-in for testing. The plug-in assembly may be locked by Internet Information Services (IIS) so that you cannot re-deploy a newer version of your assembly. The solution is to reset IIS. You can do this by running the iisreset command or by connecting to and resetting IIS using the Internet Information Services (IIS) Manager administrative tool.

Configuring Visual Studio to Automate Plug-in Deployment

For an on-disk deployment, you can configure Microsoft Visual Studio to automatically deposit, after each build, the compiled plug-in assembly to the {server|client}\bin\assembly folder. If you have Microsoft Visual Studio and the plug-in project installed on the same computer that you are deploying to, have a system administrator change the {server|client}\bin\assembly folder security so that you have write access to that folder. Make sure that you are deploying to a test system and not a production system. Next, in your Microsoft Visual Studio plug-in project, open the Build tab of the project’s properties and set the Output path field to the …\bin\assembly folder.

If you are developing your plug-in on a different computer than you are deploying to, you can accomplish the same result by configuring the {server|client}\bin\assembly folder as a network share. Again, make sure that you have write access to that share.

8e2c9d1d-a723-4c27-9b57-810d2f8658c7

Registering a Plug-in

After a plug-in is compiled into an assembly and deployed to the target server or mobile client computer, the plug-in must be registered with Microsoft Dynamics CRM in order to be executed. Registration identifies what plug-in to execute, when to execute it, how to execute it, and what optional information to pass to the plug-in.

TipTip
For an on-disk deployment, you do not have to re-register a plug-in every time that you deploy an updated plug-in assembly. As long as you do not change the version information about the assembly in the AssemblyInfo.{cs|vb} project file, the registration is still valid. However, for a database deployment, you cannot deploy the plug-in assembly without registration.

There are two different methods available to register an assembly and the plug-ins that it contains. The first method is to write your own registration code by using the RegisterSolutionRequest class in the SDK. This method is typically used to write a custom plug-in installer. The second and more commonly used method is to build and use the Plug-in Registration tool that is provided as source code in the SDK folder Tools\PluginRegistration. This tool supports both command-line and graphical user interfaces.

0e6cc1ee-db50-41ff-9972-650d018c14c6

Understanding Registration Options

The following table identifies some of the key decisions that you have to make when registering a plug-in. The table also shows where the resulting configuration values are set in the Plug-in Registration tool’s graphical user interface and where the values appear during run-time in the context that is passed to the plug-in.

 

Registration Decisions Plug-in Registration tool
GUI control
IPluginExecutionContext
Property

On what message should the plug-in execute?

Message field

MessageName

For which entity should the plug-in execute?

Primary Entity field

PrimaryEntityName

What is the related entity (if any)?

Secondary Entity field

SecondaryEntityName

Which plug-in in the assembly should run?

Plugin field

Not applicable

What user owns the data changes that were made by the plug-in?

Run in User’s Context drop down

UserId

Should the plug-in execute before or after the core platform operation (pre or post event)?

Pre Stage or Post Stage radio buttons

Stage

Should the plug-in run immediately or be queued to run later?

Synchronous or Asynchronous radio buttons

Mode

Is the plug-in deployed to the server, the mobile (Outlook) client or both?

Server and Offline check boxes

IsExecutingInOfflineMode (only applies to Offline deployed plug-ins)

In which pipeline (parent or child) should the plug-in be registered?

Parent Pipeline or Child Pipeline radio buttons

InvocationSource, ParentContext

Do I need a copy of any entity attributes before or after the core operation?

Register New Image dialog

PreEntityImages, PostEntityImages

Debugging a Plug-in

Let’s assume that you have a custom plug-in written, compiled, registered, and deployed. How do you debug it? To be able to debug a plug-in you must have the Professional or Team edition of Microsoft Visual Studio installed on the Microsoft Dynamics CRM server, or for offline plug-ins, on the computer that is running Microsoft Office Outlook. Alternately, you can install just the remote debugging feature that is available in the Microsoft Visual Studio Professional and Team editions. If you do not want to install a debugger on the server, you can add code to your plug-in to write information to the Application event log on the server by using the System.Diagnostics.EventLog class, or to a file.

The key to debugging a plug-in is to attach the debugger to the Microsoft Dynamics CRM process that loads the plug-in assembly and executes the Execute method of your plug-in class. The following table identifies which process is appropriate depending on how your plug-in is registered and deployed.

 

Deployment Execution Mode Process Name

Server

Synchronous

w3wp.exe

Server

Asynchronous

CrmAsyncService.exe

Outlook (offline)

Synchronous

Microsoft.Crm.Application.Hoster.exe

ImportantImportant
The Microsoft.Crm.Application.Hoster.exe process executes on the computer that is running Microsoft Office Outlook. It is on that computer that you must have Microsoft Visual Studio installed to be able to debug an offline plug-in.

The following steps describe how to debug a plug-in using Microsoft Visual Studio. This procedure assumes that you have Visual Studio installed on the Microsoft Dynamics CRM server, are logged into that server, and have registered a plug-in for synchronous server deployment.

  • Load the plug-in project into Visual Studio

    1. If you have not already done this, open the plug-in project in Microsoft Visual Studio, build the project, deploy and register the plug-in assembly as described previously in this article. Make sure that you have compiled the plug-in assembly for debugging, registered the plug-in assembly for on-disk deployment, and deployed the plug-in assembly with its associated .pdb file to server.

      TipTip
      If you are developing your plug-in on a computer other than the Microsoft Dynamics CRM server, you are not required to copy the Microsoft Visual Studio plug-in project (with source code) to the server to be able to debug the plug-in. In the next steps I will show you how to debug a plug-in given only the plug-in assembly and .pdb file deployed to the server.

  • Configure the debugger

    1. Attach the debugger to the appropriate process on the Microsoft Dynamics CRM server or other computer by opening the Tools menu and selecting Attach to process. If there are multiple processes running with the same process name, attach the debugger to all of them because you do not know which process executes your custom plug-in. If there are no w3wp.exe or Microsoft.Crm.Application.Hoster.exe processes shown, open the Microsoft Dynamics CRM Web application or Microsoft Office Outlook application to start the target process, refresh the process list in Visual Studio, and attach to the process.

    2. Set one or more breakpoints in your plug-in code. If you do not have the Microsoft Visual Studio plug-in project with source code available on the server, follow these steps to set a breakpoint.

      Setting a breakpoint when no source code is available

      1. In the Debug menu, select New Breakpoint, and then select Break at Function.

      2. In the dialog box, enter the fully qualified path of the Execute method in your plug-in. For example: Crm.Plugins.MyPlugin.Execute.

      3. From the language drop-down list, select C# or Basic (Visual Basic).

      4. Click OK to close the dialog box.

  • Execute the plug-in

    1. Execute your plug-in by using the Microsoft Dynamics CRM Web application. The debugger will stop on the first executable line in the plug-in’s Execute method.

      TipTip
      If you try to execute your plug-in by using the Web application, and the debugger never stops at the first breakpoint in the plug-in, you probably do not have the plug-in registered on the correct entity and message combination. The workaround is to verify the entity and message combination that is being processed by Microsoft Dynamics CRM and correctly register the plug-in for that combination. You can discover what entity and message is being processed by using the LogContextToCRM plug-in mentioned earlier in this article or by enabling tracing. Instructions on how to enable tracing can be found in the Microsoft Dynamics CRM Implementation Guide.

TipTip
When debugging your plug-in, you can use the DynamicEntity Visualizer to view the DynamicEntity (Target) data that is passed in the context to the plug-in. For more information, see Common Context.

Send Us Your Feedback about this Article

We appreciate hearing from you. To send your feedback, click the following link and type your comments in the message body.

noteNote
The subject-line information is used to route your feedback. If you remove or modify the subject line we may be unable to process your feedback.

Send Feedback

 

In this article, I have covered how to set up an efficient work environment and basic plug-in development. There is more information available in the Plug-in topic in the Microsoft Dynamics CRM SDK. Part 3 in this article series will cover more information about plug-in design.

 
Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ