Creating Dynamics CRM Plugin to execute external t

2020-05-01 09:47发布

问题:

I am experimenting with CRM Plugins. My end goal is to create a plugin that will run another program that just adds project credentials to an excel file. For my sample project, I essentially just followed https://docs.microsoft.com/en-us/powerapps/developer/common-data-service/tutorial-write-plug-in. The example provided here was excellent and taught me a lot about Plugins. The issue I am having is, whenever I try to execute code that was not involved in the tutorial, I get an error and the debug process doesn't even hit my break point. When I remove my personal code from the function, it works fine.

public class PostCreateContact : IPlugin
{

    public void Execute(IServiceProvider serviceProvider)
    {


        IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        //Process firstProc = new Process();
        //firstProc.StartInfo.FileName = "notepad++.exe";
        //firstProc.StartInfo.WorkingDirectory = "C:\\Program Files (x86)\\Notepad++\\notepad++.exe";
        //firstProc.EnableRaisingEvents = true;
        //firstProc.Start();
        if (context.InputParameters.Contains("Target")&& context.InputParameters["Target"] is Entity)
        {
            Entity entity = (Entity)context.InputParameters["Target"];
            try
            {
                Entity followup = new Entity("task");
                followup["subject"] = "Send e-mail to the new customer.";
                followup["description"] = "Follow up with the customer. Check if there are any new issues that need resolution.";
                followup["scheduledstart"] = DateTime.Now;
                followup["scheduledend"] = DateTime.Now.AddDays(2);
                followup["category"] = context.PrimaryEntityName;

                if (context.OutputParameters.Contains("id"))
                {
                    Guid regardingobjectid = new Guid(context.OutputParameters["id"].ToString());
                    string regardingobjectidType = "contact";
                    followup["regardingobjectid"] = new EntityReference(regardingobjectidType, regardingobjectid);
                    IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
                    service.Create(followup);
                }
            }
            catch (Exception ex)
            {
                throw new InvalidPluginExecutionException(ex.Message);
            }
        }
    }
}

The 5 lines of code that I have commented out are my personal code i mentioned. If I were to un-comment out those lines. The code will not hit my break point. My break point was set below the "public void Execute(IserviceProver servicerProvider)" line. Could someone explain to me why it immediately fails whenever I insert my own code to perform a non CRM related task?

Also, besides attempting to open up notepad++, attempting to throw a message box will not work either.

回答1:

The nature of plugins is that they operate on data within the Dynamics 365 system or they communicate with the outside world via HTTP or HTTPS. Writing to a local file is outside the realm of what plugins are designed to do.

One way to have a plugin communicate with the outside world is to write a an Azure-aware plugin.

If you're system is on-premise, registering your plugins outside the sandbox would provide greater flexibility, though writing to a local file, even if it were technically possible (which I don't believe it is) would still be a bad practice.

To send the user a file in a supported way you could create the file as a note attachment. Once you've done that you could simply email the user a link to that Note in Dynamics 365.

If you want the file to be available outside of Dynamics 365 you could trigger an Azure- aware plugin who's Azure-based listener would retrieve the Note attachment file, upload it to a cloud file service like SharePoint or OneDrive, then email the user a link to the file.

Since even sandboxed plugins can use HTTPS, you could ostensibly have a plugin upload the file directly to an external cloud host, but authentication might get thorny. And, depending on the upload speed and the size of the file you could run up against the sandbox's 2-minute timeout.

Standard practice these days is to assume that any on-prem system might move online someday, so design all code to operate in the sandbox.



回答2:

I'll tag on to Aron's excellent answer for those that are more visual learners. Below from a high point is what happens when you execute a normal CRUD operation in CRM:

The plugin itself is executing in steps 2 or 4, depending on how you've registered it, but regardless, it is executing in an online sandbox process that is isolated from all other processes on the machine in the cloud that is processing it. The sandbox puts additional restrictions on your code, once of which is disk access. You can not access any portion of the hard drive from a plugin, so attempting to read or write a file will fail. And trying to open up an application makes no sense, because even if it were allowed, it would open on some webserver in some webfarm in Microsoft's cloud, not on your local machine.