Showing posts with label workflow. Show all posts
Showing posts with label workflow. Show all posts

Friday, October 30, 2009

Debugging CRM Plug-ins, Stored Procedures & Custom Workflow Activities

by Danny Varghese 02.24.09

Whether it's developing CRM plug-ins, custom workflow activities, or writing stored procedures against the CRM database, the most useful tool I've used is the Microsoft Visual Studio Debugger. The debugger allows developers to step through the code for the above mentioned scenarios and has saved me hours!

Microsoft has phenomenal documentation on how to setup remote debugging:

http://msdn.microsoft.com/en-us/library/bt727f1t.aspx

The biggest issues I've had trying to setup the debugger has always been with permissions. I would recommend paying especially close attention to this section. The next biggest issue I had was trying to attach the debugger to a running process: http://msdn.microsoft.com/en-us/library/c6wf8e4z.aspx

Once you've setup Visual Studio debugger, you can attach the following processes for the following CRM components:

  1. For plug-ins, attach the debugger to the w3wp.exe process.
  2. For custom workflow activities, attach the debugger to MSCRMAsyncService.exe
  3. For stored procedures, attach the debugger to sqlserver.exe

Once the debugger has been attached, you must set a breakpoint in the code (either the .NET or T-SQL code). After the breakpoint is set, to test, do the following:

  1. For plug-ins, login to CRM and execute actions that will trigger the plug-in, such as create/update/assign a record.
  2. For custom workflow activities, login to CRM and perform actions that will trigger the workflow. With this, being that it's an asynchronous service, you'll have to wait until that service runs, and then Visual Studio will let you step through the code.
  3. For the stored procedure, just execute the stored procedure in Visual Studio and it will go right to the breakpoint.

I hope this post will help CRM developers save time and effort. I use the debugger every time I develop now to test and it's saved me tremendous amount of maintenance time and effort after the code has been deployed. Happy debugging!

Thursday, February 12, 2009

Workflow: Determining the

Posted by: mitch of Mitch Milam's Microsoft Discussions


I ran into something unexpected this week at a customer site: Internal system jobs, like Matchcode Updates, stuck in with a waiting status.  For workflows, this usually means there are errors preventing the workflow from proceeding.  But, I've never seen it on internal jobs before.

After asking around, Mahesh at Microsoft pointed out a method for attaining additional information regarding the status of a System Job.  Follow these steps:

[ as a CRM Administrator ]

1) Select Settings, System Jobs to display a list of currently running or ran jobs.

2) Click the Advanced Find button and the following dialog will be displayed:

image

3) Click Edit Columns then add the column Message, as shown below:

image

This will display the actual status message and allow you to determine if a workflow or system job is waiting because it is supposed to, or if it is waiting because it encountered an error.

The following is a sample of system jobs - Matchcode Updates - that have failed because of an environmental change:

image

Note: The status is canceled because I manually canceled these jobs after I located and corrected the issue. Their normal status would have been Waiting.

This surely helped my troubleshooting.  I hope it helps yours.

Monday, December 29, 2008

Adding Notes to a Workflow E-mail

Posted by Jim Steger on December 23, 2008

In a recent post on the Microsoft Dynamics CRM Team blog, I discuss how you can easily overcome some of the native limitations of the CRM workflow Send E-mail action with some simple workflow assembly classes. Recently, I have been implementing the new eService Accelerator for our own corporate web site and came across a need for another CRM workflow e-mail utility...the ability to include all the notes of a record into the body of a workflow e-mail.

To accomplish this, I created a new activity class within my workflow utilities project and used the following code:

using System;
using System.Workflow.ComponentModel;
using System.Workflow.Activities;
using System.Web.Services.Protocols;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Sdk.Query;
using Microsoft.Crm.Workflow;
using System.Collections;
using System.Text;

namespace SonomaPartners.Crm.Workflow.Utilities
{
[CrmWorkflowActivity("Format Notes", "Utilities")]
public partial class FormatNotes : SequenceActivity
{
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
IWorkflowContext ctx = contextService.Context;
ICrmService service = ctx.CreateCrmService();

this.FormattedNotes = BuildNotesString(service, ctx.PrimaryEntityId);

return base.Execute(executionContext);
}

public static DependencyProperty FormattedNotesProperty = DependencyProperty.Register("FormattedNotes", typeof(string), typeof(FormatNotes));
[CrmOutput("Formatted Notes")]
public string FormattedNotes
{
get { return (string)base.GetValue(FormattedNotesProperty); }
set { base.SetValue(FormattedNotesProperty, value); }
}


private string BuildNotesString(ICrmService service, Guid id)
{
StringBuilder results = new StringBuilder();
results.Append("Notes:<br>");

BusinessEntityCollection notes = new BusinessEntityCollection();
notes = RetrieveNotesForId(service, id);

foreach (annotation note in notes.BusinessEntities)
{
results.Append(string.Format("{0}<br>", note.subject));
results.Append(string.Format("{0}<br><br>", note.notetext));
}

return results.ToString();
}

private BusinessEntityCollection RetrieveNotesForId(ICrmService service, Guid id)
{
QueryByAttribute query = new QueryByAttribute();
query.EntityName = "annotation";
query.ColumnSet = new ColumnSet(new String[] { "subject", "notetext", "createdby", "createdon" });

query.Attributes = new String[] { "objectid" };
query.Values = new Object[] { id };
query.Orders = new ArrayList();
query.Orders.Add(new OrderExpression("createdon", OrderType.Descending));

try
{
RetrieveMultipleRequest request = new RetrieveMultipleRequest();
request.Query = query;

RetrieveMultipleResponse returnedNotes = (RetrieveMultipleResponse)service.Execute(request);
return returnedNotes.BusinessEntityCollection;
}
catch (SoapException ex)
{
throw new Exception(ex.Detail.InnerText);
}
}
}
}


Now, your e-mail includes any notes in the body of the message as shown here:



Feel free to download the Visual Studio 2008 workflow utilities assembly solution file.



Btw, I also wanted to thank Steve Kaplan and Jim Glass for allowing me to contribute on the Microsoft Dynamics CRM Team blog.





Posted by Jim Steger on December 23, 2008 | Permalink

Friday, December 19, 2008

Custom Workflow Activity - Add to Marketing List

Wednesday, 22 October 2008 Posted by Chris Cohen

I needed to use workflow to add a new member to a marketing list, but found I needed to create a custom workflow activity to do this. In fact once you have VS2005 setup with workflow project types it wasn't too hard.

You need to use Dependency Properties to pass parameters in (and out). The worflow activity form assistant will allow you to set some dynamically. You can use the context to get a handle to the crmService. CrmWorkflowActivity defines the menu labelling in the workflow activity.

Use the Developer PluginRegistration tool to register it, or there is sample installer code in the SDK workflow walkthrough.

Hope this helps someone.


using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Workflow;

namespace Vizola.VEMWorkflow
{
[CrmWorkflowActivity("Add to Marketing List", "VEM Workflow")]
public partial class Add2ML: SequenceActivity
{
public static DependencyProperty listIdProperty = DependencyProperty.Register("listId", typeof(Lookup), typeof(Add2ML));
[CrmInput("Marketing List")]
[CrmReferenceTarget("list")]
public Lookup listId
{
get
{
return (Lookup)base.GetValue(listIdProperty);
}
set
{
base.SetValue(listIdProperty, value);
}
}
public static DependencyProperty contactIdProperty = DependencyProperty.Register("contactId", typeof(Lookup), typeof(Add2ML));
[CrmInput("Contact")]
[CrmReferenceTarget("contact")]
public Lookup contactId
{
get
{
return (Lookup)base.GetValue(contactIdProperty);
}
set
{
base.SetValue(contactIdProperty, value);
}
}
public Add2ML()
{
InitializeComponent();
}
///
/// The Execute method is called by the workflow runtime to execute an activity.
///

/// The context for the activity
///
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
// Get the context service.
IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
IWorkflowContext context = contextService.Context;
// Use the context service to create an instance of CrmService.
ICrmService crmService = context.CreateCrmService(true);

AddMemberListRequest amReq = new AddMemberListRequest();
amReq.EntityId = contactId.Value;
amReq.ListId = listId.Value;
AddMemberListResponse amRes = (AddMemberListResponse)crmService.Execute(amReq);

return ActivityExecutionStatus.Closed;
}
}
}

Wednesday, November 26, 2008

Custom Workflow Activity - Add to Marketing List

Wednesday, 22 October 2008 Posted by Chris Cohen


I needed to use workflow to add a new member to a marketing list, but found I needed to create a custom workflow activity to do this. In fact once you have VS2005 setup with workflow project types it wasn't too hard.

You need to use Dependency Properties to pass parameters in (and out). The worflow activity form assistant will allow you to set some dynamically. You can use the context to get a handle to the crmService. CrmWorkflowActivity defines the menu labelling in the workflow activity.

Use the Developer PluginRegistration tool to register it, or there is sample installer code in the SDK workflow walkthrough.

Hope this helps someone.


using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
using System.Workflow.Runtime;
using System.Workflow.Activities;
using System.Workflow.Activities.Rules;
using Microsoft.Crm.Sdk;
using Microsoft.Crm.SdkTypeProxy;
using Microsoft.Crm.Workflow;

namespace Vizola.VEMWorkflow
{
[CrmWorkflowActivity("Add to Marketing List", "VEM Workflow")]
public partial class Add2ML: SequenceActivity
{
public static DependencyProperty listIdProperty = DependencyProperty.Register("listId", typeof(Lookup), typeof(Add2ML));
[CrmInput("Marketing List")]
[CrmReferenceTarget("list")]
public Lookup listId
{
get
{
return (Lookup)base.GetValue(listIdProperty);
}
set
{
base.SetValue(listIdProperty, value);
}
}
public static DependencyProperty contactIdProperty = DependencyProperty.Register("contactId", typeof(Lookup), typeof(Add2ML));
[CrmInput("Contact")]
[CrmReferenceTarget("contact")]
public Lookup contactId
{
get
{
return (Lookup)base.GetValue(contactIdProperty);
}
set
{
base.SetValue(contactIdProperty, value);
}
}
public Add2ML()
{
InitializeComponent();
}
///
/// The Execute method is called by the workflow runtime to execute an activity.
///

/// The context for the activity
///
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
// Get the context service.
IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
IWorkflowContext context = contextService.Context;
// Use the context service to create an instance of CrmService.
ICrmService crmService = context.CreateCrmService(true);

AddMemberListRequest amReq = new AddMemberListRequest();
amReq.EntityId = contactId.Value;
amReq.ListId = listId.Value;
AddMemberListResponse amRes = (AddMemberListResponse)crmService.Execute(amReq);

return ActivityExecutionStatus.Closed;
}
}
}

Thursday, July 17, 2008

Custom Workflow Activity for matching email addresses to customers

Jagan Peri Published Friday, June 20, 2008 7:02 AM

In an earlier blog (E-mail to Case/Lead Using CRM 4 Workflow ), I described a sample workflow that could be used to automatically create cases based on emails sent to a queue.

One of the questions that was frequently asked for the above blog was that the email activity’s regarding field set to blank. In this blog, I’ll show how this can be done using a custom CRM workflow activity.

Let’s summarize the problem we are trying to solve. Joe (joe@mycustomer.com) is a customer in your system and say you have an account that is capturing this. Joe sends an email to your support alias to report an issue. We would like the email activity that is created to be regarding Joe’s account.

For those of you new to writing custom workflow activities, I highly recommend that you take a look at the SDK documentation at: http://msdn.microsoft.com/en-us/library/cc151142.aspx --It contains all the information needed for you to start using custom workflow activities.

I’m going to split my solution into 2 parts:

1) A custom workflow activity that takes an email address as input and returns a matching account as output

2) A workflow rule that uses the above custom activity. This workflow rule is triggered when an email is created and updates the email activity to have the regarding field set to the output returned by the custom workflow activity.

Custom Workflow Activity

Let’s walk thru’ the code for the custom workflow activity.

1) Define the class skeleton and the using statements for the various namespaces that we will need. Please ensure you have read and understood the SDK documentation at: http://msdn.microsoft.com/en-us/library/cc151142.aspx to get an overview of how to develop CRM custom workflow activities.

using System.Workflow.Activities;

using System.Workflow.ComponentModel;

using Microsoft.Crm.Sdk;

using Microsoft.Crm.SdkTypeProxy;

using Microsoft.Crm.Workflow;

using Microsoft.Crm.Sdk.Query;

namespace CrmCustomWFActivity

{

   [CrmWorkflowActivity("Find Customer with specified email address")]

   public class MatchSenderWithExistingCustomerActivity:  

   System.Workflow.Activities.SequenceActivity

   {

       // Activity code goes here.

   }

}

2) Now, add properties that represent the inputs and outputs. As discussed earlier, the input is an email address (of type string) and the output will be the matching account (of type Lookup).

DependencyProperty is a Windows Workflow concept and you can read more about it here: http://msdn.microsoft.com/en-us/library/system.workflow.componentmodel.dependencyproperty.aspx

   1: // Input property
   2: public static DependencyProperty senderProperty = DependencyProperty.Register("sender", typeof(string), typeof(MatchSenderWithExistingCustomerActivity));
   3:  
   4:         [CrmInput("Sender")]
   5:         public string sender
   6:         {
   7:             get
   8:             {
   9:                 return (string)base.GetValue(senderProperty);
  10:             }
  11:             set
  12:             {
  13:                 base.SetValue(senderProperty, value);
  14:             }
  15:  
  16:         }
  17:  
  18: // Output property
  19: public static DependencyProperty accountIdProperty = DependencyProperty.Register("accountId", typeof(Lookup), typeof(MatchSenderWithExistingCustomerActivity));
  20:  
  21:         [CrmOutput("AccountId")]
  22:         [CrmReferenceTarget("account")]
  23:         public Lookup accountId
  24:         {
  25:             get
  26:             {
  27:                 return (Lookup)base.GetValue(accountIdProperty);
  28:             }
  29:             set
  30:             {
  31:                 base.SetValue(accountIdProperty, value);
  32:             }
  33:  
  34:         }

3) This custom workflow activity needs to be able to retrieve accounts whose email address matches the sender property value. To do this, it needs to be able to call into CRM SDK methods and can do this thru’ IcrmService interface that is provided to all crm custom workflow activities. The following is code for a helper method that uses CRM query functionality to return account that matches the email address.

   1: private Guid MatchSenderWithExistingAccount(ICrmService crmService, string fromAddress)
   2: {
   3:     // Retrieve accounts with this email address.
   4:     QueryByAttribute query = new QueryByAttribute();
   5:     query.EntityName = EntityName.account.ToString();
   6:     query.Attributes = new string[] { "emailaddress1" };
   7:     query.Values = new string[] { fromAddress };
   8:  
   9:     RetrieveMultipleRequest retrieveMultipleRequest = new RetrieveMultipleRequest();
  10:     retrieveMultipleRequest.Query = query;
  11:     retrieveMultipleRequest.ReturnDynamicEntities = true;
  12:  
  13:     RetrieveMultipleResponse retrieveMultipleResponse = (RetrieveMultipleResponse)crmService.Execute(retrieveMultipleRequest);
  14:  
  15:  
  16:  
  17:     Guid accountId = Guid.Empty;
  18:  
  19:     foreach (BusinessEntity busEntity in retrieveMultipleResponse.BusinessEntityCollection.BusinessEntities)
  20:     {
  21:         // Pick the first accountid.
  22:         accountId = ((Key)(((DynamicEntity)busEntity)["accountid"])).Value;
  23:         break;
  24:     }
  25:  
  26:     return accountId;
  27: }

4) Now, we can implement the Execute method of the custom workflow activity.

   1: protected override System.Workflow.ComponentModel.ActivityExecutionStatus Execute(System.Workflow.ComponentModel.ActivityExecutionContext executionContext)
   2:         {
   3:             IContextService contextService = (IContextService)executionContext.GetService(typeof(IContextService));
   4:             IWorkflowContext context = contextService.Context;
   5:  
   6:         // Obtain IcrmService so we can call into CRM SDK to retrieve
   7:         // accounts
   8:             ICrmService crmService = context.CreateCrmService(); 
   9:  
  10:             // this.sender property will have the email address that needs to be matched.
  11:             Guid accountId = MatchSenderWithExistingAccount(crmService, this.sender);
  12:  
  13:             // Set the accountId output property to return this data
  14:         // back to the calling workflow
  15:             this.accountId = new Lookup("account", accountId);
  16:  
  17:             return ActivityExecutionStatus.Closed;
  18:         }
  19:       
  20:     return accountId;

Using The Custom Workflow Activity

In order to use MatchSenderWithExistingCustomerActivity in workflow rules, you need to register the activity. Follow the steps at: http://msdn.microsoft.com/en-us/library/cc151144.aspx to accomplish this.

We will create a workflow rule that does the following:

1) When an email is created, it checks if the email’s regarding field is set.

2) If not set, it invokes MatchSenderWithExistingCustomerActivity

3) It updates email with the accountid returned by MatchSenderWithExistingCustomerActivity.

Let’s walk through these in more detail.

1) Create the workflow rule, call it SetEmailRegarding and set it to trigger on email create

clip_image002

2) Insert a check condition step and configure it to check if Email:regarding field does not contain data

clip_image004

3) If Email:regarding is not set, we want to invoke the MatchSenderWithExistingCustomerActivity. Under the add step drop-down, you should find the custom workflow activity as shown below:

clip_image006

4) After you select MatchSenderWithExistingCustomerActivity, you need to ensure that it is being invoked with the correct input. Click ‘Set Properties’ and set the value of the input parameter Sender to that of Email:Sender

clip_image008

5) The next step would be to update the email’s regarding to the value returned by the custom workflow activity in the previous step. To do this, add a Update Email step, select ‘Set Properties’ and tab to the ‘Regarding’ field. In the dynamic values form assistant, you will now find that it shows ‘Match email address:accountid’ to indicate the return value from the previous step. Select this to be the value for regarding field as shown below.

clip_image010

6) Publish the workflow and verify that it is working.

Since the functionality to match email address to an account has been captured as a custom workflow activity, you will be able to use that activity in all your workflow rules. You can also enhance the custom workflow activity by making it return either a matching account or contact if needed. If you need to create an account/contact if a match wasn’t found, you can do this by adding a Create step to the workflow rule.

Jagan Peri

Differences between Workflow and Plugins in CRM 4.0

Posted by David Jennaway at 19:09
A common question I get is ‘what is the difference between workflow and plugins, and when should I use one or the other ?’. This article is intended to be a comprehensive answer to these 2 questions.

First of all, I want to clarify the distinction between what I consider 3 distinct categories of workflow – the terminology is my own:
  • Simple workflow. This is one or more workflow rules created within the MSCRM interface, and which do not include custom workflow activities.
  • Workflow with custom workflow activities. I’ll explain more about custom workflow activities later in this article; for now the key point is that a custom workflow activity is .Net code that is written to perform functions not possible in simple workflow, and this code can be called from a workflow rule
  • Workflows created with the Workflow Designer in Windows Workflow Foundation. It is possible to build workflows outside of the CRM user interface, but I’m not going to include them in this article.
Simple workflows
The main characteristics of simple workflows are:
  • * Creating a simple workflow involves no code
  • Workflows run only on the CRM server – workflow processing is not available within a client that is offline
  • Workflows run asynchronously – any data changes made within a workflow rule will not show up immediately within the CRM user interface
  • Workflows can be run manually or automatically. The automatic running of workflows is based on several data modification events
  • Workflow rules are entity specific
  • The state and stage of a workflow instance can be viewed within the CRM user interface by any CRM user with appropriate permissions

Some limitations of workflows are:

  • Workflow rules cannot be created for all entities
  • Although workflow rules can be triggered by the most common data modification events, there are some events that don’t trigger workflow rules
  • * Simple workflows offering limited capability to perform calculations

Characteristics and limitations marked with an asterix (*) do not apply if using custom workflow activities; the others do still apply.

Custom workflow activities
Custom workflow activities allow you to extend the capabilities of workflow rules. Three common uses are to perform calculations on CRM data, to access CRM functionality that is not available in the out-of-the-box workflow activities, and to access external data.

Custom workflow activities are written as .Net assemblies which have to be registered on the CRM server. These assemblies can include information about parameters that can be passed into or out of the activity.

Plugins
A plugin is .Net code that is registered on the CRM server. A plugin assembly can be registered for one or more steps – these steps correspond to the combination of the message (event), entity and stage. An example of a step would be the Create message for the account entity on the pre-event stage. Registration of the assembly and steps is part of the plugin deployment process, and there is no direct user interaction with plugins

The main characteristics of plugins are:

  • They have to be written as .Net code
  • Although they typically run on the CRM server, they can be deployed and configured to run on a CRM client that is offline
  • They can run either synchronously or asynchronously. If they run synchronously, any data changes made within the plugin will show up immediately within the CRM user interface
  • Synchronous plugins can run on either the pre-event or post-event stage. The pre-event stage happens before data is written to the CRM database, and a plugin registered on a pre-event step can cancel the data writing and provide an error message to the user.
  • More entities can have plugins registered for them than can have workflow rules
  • Plugins can run on more events than can workflow rules. An example is that plugins can run on data retrieval, not just modification events

The main limitations of plugins are:

  • Plugins cannot be run manually; they only run on the steps for which they are registered
  • There is no user interaction with plugins, other than error messages that might be throw by a synchronous plugin

Sample Scenarios
So, having covered the main characteristics and limitations of simple workflows, custom workflow activities and plugins, when should you choose one or another ? Here are some common scenarios:

What you want to achieve can be done with a simple workflow, and it is acceptable or desirable for this to happen asynchronously and on the server only
In this case I’d go with simple workflows; there’s no point writing code if you don’t have to.

What you want to achieve has to run synchronously
If so, workflow won’t do, so it would have to be a plugin. An alternative could be to use client script, but I don’t intend to complicate this article by including this in any more detail

You need to be able to cancel the data operation
A pre-event plugin is the only option covered here, though again client script should be considered

You want to give users the discretion to run the operation manually
Here you’ll need a workflow. Whether or not you need a custom workflow activity depends on the complexity of the operations. Again, there may be an option outside of the scope of this article – to write an ASP .Net application that is called from an ISV Config button

You need to write custom code, but you want users to decide whether this code should run, and under what circumstances
In this case I’d go with a custom workflow activity, as you could make this available for users to add to their own workflows

Further Information
There is more detail about how to write and deploy plugins and custom workflow assemblies within the CRM 4.0 SDK, though unfortunately there’s not a lot of information about when to choose one or the other.

The classroom training material ‘Extending Microsoft Dynamics CRM 4.0’, course number 8969, should have more information both about building plugins and custom workflow assemblies, and when to use them. This course will also cover other solution technologies such as client script and ASP .Net extensions.

One of the MS team, Humberto Lezama has also produced a useful matrix indicating the relative merits of workflow and plugins. This can be found here

Wednesday, July 16, 2008

Plug-in Registration Tool 2.1

Published Tuesday, July 01, 2008 8:42 AM by crmblog


I have made some minor upgrades to the Plug-in Registration v2.0 tool that is included in the Microsoft CRM 4.0 SDK download or downloaded from Code Gallery.

The following features were added for making the developer’s life easier.

1. Support for https:// in the tool

The Connections Grid now accepts a Discovery Service server name in one of the following formats.

a. https://myMachine

b. mymachine

c. http://mymachine

When making web service calls to the https:// servers, the current logic blindly accepts all the certificates. The program trusts the https:// endpoint that you provided to the tool. It does not verify if the certificate is Expired or if it is from VeriSign etc. You could change the implementation of the logic in the code.

2. Support to change the endpoint returned by the DiscoveryService Web service

Sometimes due to incorrect configuration the SDK endpoint returned by the discovery service is incorrect. So I made modifications to the tool to allow you to change the endpoint that is returned by the discovery service before making any calls to the CrmService Web service.

3. Support registering images for a subordinate entity for Merge

The Merge request involves 2 entities, a parent entity and a subordinate entity. Inside the plug-in you might want to Plug-in Registration Tool 2.1get the image of both the parent and subordinate entities. Now, in the plugin registration tool 2.1, when you register an image for Merge, a dialog is displayed that states “Do you want the image for Parent or Subordinate entity?” You can now register for both.

4. Plugin Registration in IFD/SPLA

IFD or SPLA installations do support plug-ins. You can now use the tool to register a plug-in on the Microsoft CRM server using AD authentication. You will need the DeploymentAdmin privilege to register a plug-in just like you would for an on-premise installation.

5. Works with Visual Studio 2008

6. Restrict image registration for a Create pre-event and Delete post-event

Images are snapshots of the entity’s attributes at the corresponding stage in the pipeline. When you look at the CreateRequest, a plug-in registered for a pre-event on Create gets fired before the Create platform operation occurs. For example, the plug-in is fired before the entity is created in the system. So it doesn’t make sense to register the plug-in step for a pre-event image. The new version of the tool doesn’t allow that image registration.

Similarly for post-event Delete step, we don’t have an entity after a Delete operation, so it doesn’t make sense to support registering for a post-event image.

You can download the latest version of the Plug-in Registration tool (v2.1) at Plugin Code Gallery http://code.msdn.microsoft.com/crmpluign

Thanks for the feedback on prior versions of the tool

Ajith Gande