Banner

Custom Code Workflows Using Microsoft Dynamics CRM 4

Back to Blog Listing


Uploading/Updating Custom Code Workflows in CRM

1. Compile the code in visual studio, ensure any references or dependencies are signed.

2. Ensure you have access to the CRM.

3. For deployment you require additional access.

        1. To add your user account go to the server holding the CRM and from the programs menu select Microsoft Dynamics CRM – Deployment Manager.

deploymentmanager

 

 

        2. Select “Deployment Administrators” to get a list of existing administrators. If your user account is not present then add it using the “New Deployment Administrator” option on the right hand side.

  1. Once you have appropriate access to CRM then open Microsoft’s PluginRegistration tool (can be found at http://archive.msdn.microsoft.com/crmplugin/Release/ProjectReleases.aspx?ReleaseId=2010)
    1. On initial connection page add the following details:
      1. Label – any text that will help you identify the connection (ie Globalscot – Krusty)
      2. Discovery server – url of the discovery server ( ie c2-krusty/mscrmservices/2007/ad/crmdiscoveryservice.asmx?WSDL&uniquename=GlobalScot)
      3. Domain – “C2”
        pluginregistrationtool
         
      4. User Name – Your network user name (ie Rebecca)
        pluginregistration-passwordbox
         
    2. Use your network password for access.
    3. Once connected to the discovery service select one of the options on the left (ie GlobalScot) and then select connect again.
      pluginregistration-connected
       
    4. If there have been custom workflows defined on this CRM before then select the assembly name from the list that will appear on the right hand screen and remove it. This is necessary or CRM will not update the assembly. After it has been successfully removed add the updated assembly by registering it as a new assembly (follow steps e – i for more information).
      pluginregistration-full
       
    5. If there have been no previous versions of your assembly loaded to the CRM then select Register -> Register New Assembly from the options
    6. On the following screen you can upload the assembly of your project by using the top box. This must be an up to date version of the assembly (remember to check last modified date). In addition the folder containing your assembly must also contain the DLL microsoft.crm.sdk.dll, this DLL must also be a part of your GAC (see Appendix A.1 for instruction)
      pluginregistration-newplugin
       
    7. If successful then the assembly should appear in the Step #2 box. If you expand this assembly there should be a list of the classes within your assembly. You do not have to select all of these, simply the ones you want to add/update. Once you have selected the classes you want then select the “Register Selected Plugins” button.
      pluginregistration-newplugin-loaded
       
    8. Once complete you will be shown a summary.
      pluginregistered
       
    9. Restart the IIS
    10. On the CRM server locate the “Microsoft CRM Asynchronous Processing Service” from the Services list in administrative tools. Restart the service.
    11. Make sure steps i and j are completed in order!
    12. If you then look in your CRM your new steps should be available in the custom menu.
    1. If this was an update then any existing CRM workflows that use your updated assembly must be unpublished, the custom step removed, the custom step re-added and the workflow republished before changes will take effect

Creating the Assemblies

  1. Create a “Workflow Activity Library” project.
  2. Add an “Activity” for each workflow step.
  3. Create a namespace for the workflows to be in and ensure to add steps/activities to it.
  4. The initial code will have to have the following structure [NOTES] are highlighted:
    Imports Microsoft.Crm.Sdk
    Imports Microsoft.Crm.Workflow [STANDARD IMPORTS]
     
    Namespace Simple [NAMESPACE DEFINED]
     
        <CrmWorkflowActivity("Approve Company Record v1.1", "Custom")> _ [NAME OF THE WORKFLOW AS IT WILL APPEAR IN CRM, “CUSTOM” IS THE NAME OF THE MENU THAT THE ITEM WILL BE A MEMBER OF, USUALLY NO NEED TO CHANGE THIS]
        Public Class ApproveCompany : Inherits SequenceActivity [MUST INHERIT SEQUENCEACTIVITY]
     
            Public Shared requestIdProperty As DependencyProperty = DependencyProperty.Register("requestId", GetType(Lookup), GetType(ApproveCompany)) [DEPENDENCY PROPERTY REFERS TO THE GUID OF THE OBJECT THE WORKFLOW WILL BE EXECUTED ON, THE LAST GETTYPE SHOULD HAVE THE NAME OF YOUR OWN CLASS WITHIN]
     
            <CrmInput("COMPANY ID")> _ [NAME AS IT WILL APPEAR WITHIN “PROPERTIES OF THE WORKFLOW]
            <CrmReferenceTarget("account")> _ [NAME OF ENTITY WITHIN CRM, MUST BE ORIGINAL PARENT NAME, I.E. ORGANISATION IS ACCOUNT]
            Public Property requestId() As Lookup
                Get
                    Return CType(MyBase.GetValue(requestIdProperty), Lookup)
                End Get
                Set(ByVal value As Lookup)
                    MyBase.SetValue(requestIdProperty, value)
                End Set
            End Property
     
            Protected Overrides Function Execute(ByVal executionContext As ActivityExecutionContext) As ActivityExecutionStatus [EXECUTE FUNCTION IS MANDATORY]
                 
    Return MyBase.Execute(executionContext) [MUST RETURN THIS]
     
            End Function
     
     
        End Class
     
    End Namespace
  5. It is best to have all code within the execute function stored within a Try and Catch
  6. Do NOT use global variables, later rollups of CRM do not allow this.
  7. Ensure the project is securely signed, is a simple process, just go to properties of the project, go to the signing tab and then check the box that says “Sign the assembly”. Select “New” from the drop list and create a signature, there is no need to apply a password.
  8. Can use web references but ensure that the initialisations of these are not global and contained within a Try/Catch.
  9. Can have other functions/subs within the class called from the execute method.

Appendices

A.1 Adding an assembly to the GAC

Locate the assembly you wish to add to the GAC (ie Microsoft.crm.sdk.dll) In another window go to the following location – C:\Windows\assembly Drag the assembly you wish to the C:\Windows\assembly folder.

A.2 Troubleshooting

  • If the assembly will not register from your remote machine, try registering it on the server CRM is present on. There are sometimes issues with permissions that are not obvious.
  • Ensure when registering a Dependency Property that the 3 attribute for registration contains the GetType of the class you are trying to use it in
    e.g.
    Public Shared requestIdProperty As DependencyProperty = DependencyProperty.Register("requestId", GetType(Lookup), GetType(HelpRequestCreate)) – from HelpRequestCreate.vb
  • Double check the assembly is only using signed references. You can still compile and load an assembly successfully when there are, but it will not work in the CRM.
  • Ensure you have the correct permissions.
  • If you want to check the assembly has been updated then you can throw an error with a specific message that will be more sensible when reading its full detail (see A.3)
    e.g.
    Throw New ApplicationException(String.Format("SEND EMAIL: Exception occurred in sendNewRequestNetworkActivityEmail. ContactId: {0}. Exception: {1}", GlobalscotID, appEx.Message.ToString), appEx)
  • If you wish to see the value of certain fields at runtime – to check for null pointers etc, a quicker way than trying remote debugging is to write the value of a parameter to a text file
    e.g.
    Dim logPath As String = "C:\Test\Log.txt"
    My.Computer.FileSystem.WriteAllText(logPath, "RegardingGUID=" & activity.RegardingGUID, True)

A.3 Show Full Error Messages

  • To see errors within the CRM further to the “An Error has occurred. Try this action again. If the problem continues, check the Microsoft Dynamics CRM Community for solutions ...” then select the “Advanced Find” option from the main CRM screen
    • Create a new search
    • Have it look for System Jobs
    • Have it filter on “System Job Type” where it is equal to “Workflow”
    • Have it also filter on “Status Reason” where it equals “Failed” or “Waiting”
    • Edit Columns and add in columns “Message” and “Message Name”
    • Hit find – this will then show you a list of errors that have occurred within the CRM and a more detailed message for each.
  • Another way of doing this is to use the following SQL query on the _MSCRM database:
SELECT [Name]
      ,[PostponeUntil]
      ,[WorkflowState]
      ,[IsWaitingForEvent]
      ,[ErrorCode]
      ,[StatusCode]
      ,[Sequence]
      ,[RequestId]
      ,[WorkflowIsBlocked]
      ,[ModifiedOn]
      ,[Message]
      ,[StartedOn]
      ,[StateCode]
      ,[CompletedOn]
      ,[RetryCount]
      ,[CreatedOn]
  FROM GlobalScotDev_MSCRM.[dbo].[AsyncOperationBase]
  WHERE  DAY(CreatedOn) = 18 AND MONTH(CreatedOn) = 5 AND    YEAR(CreatedOn) = 2012 AND Name = 'WORKFLOWNAME'
   
  ORDER BY StartedOn DESC

 


About the Author

James CTwo is our blogging alter ego for the Dynamics CRM and Web experts here at C2. We have a passion for anything CRM, Web Design or Social Media. We love writing about it! Find us on YouTube & Twitter.

comments powered by Disqus

Our White Papers

Discover the content that matters to you on business transformation. Explore how you can drive customer engagement, empower your team, optimise your businesses and revolutionise your products with the next digital revolution. For more information visit our white paper library.

Library

C2 Newsletter

Our newsletter is sent on a quarterly basis, offering detailed insights into all aspects of business transformation with Microsoft cloud technologies. We also promote upcoming events and special offers throughout the year. Sign up to get involved today.

Dynamics 365 Office 365 Power BI Silver Partner