private void LoadAssembly(CrmPluginAssembly assembly, bool checkExisting) { bool loadTypeId = (m_currentAssembly != null && !checkExisting && m_registeredPluginList != null); bool checkRecord = (checkExisting && m_currentAssembly != null && m_registeredPluginList != null); //Loop through and add the data to the form trvPlugins.LoadNodes(new ICrmTreeNode[] { assembly }); foreach (var currentPlugin in assembly.Plugins.Values) { if (loadTypeId && !m_registeredPluginList.Any(x => x.TypeName.ToLowerInvariant() == currentPlugin.TypeName.ToLowerInvariant())) { m_registeredPluginList.Add(currentPlugin); } if (!checkRecord || m_registeredPluginList.Any(x => x.TypeName.ToLowerInvariant() == currentPlugin.TypeName.ToLowerInvariant())) { trvPlugins.CheckNode(currentPlugin.PluginId, true); } else { trvPlugins.CheckNode(currentPlugin.PluginId, false); chkSelectAll.Checked = false; } } }
private CrmPluginAssembly RetrieveAssemblyProperties(Assembly assembly, string path) { if (assembly == null) { throw new ArgumentNullException("assembly"); } var pluginAssembly = new CrmPluginAssembly(null) { AssemblyId = Guid.NewGuid(), SourceType = CrmAssemblySourceType.Disk }; var fileInfo = new FileInfo(path); pluginAssembly.ServerFileName = fileInfo.Name; var name = assembly.GetName(); string cultureLabel; if (name.CultureInfo.LCID == System.Globalization.CultureInfo.InvariantCulture.LCID) { cultureLabel = "neutral"; } else { cultureLabel = name.CultureInfo.Name; } pluginAssembly.Name = name.Name; pluginAssembly.Version = name.Version.ToString(); pluginAssembly.Culture = cultureLabel; byte[] tokenBytes = name.GetPublicKeyToken(); if (null == tokenBytes || 0 == tokenBytes.Length) { pluginAssembly.PublicKeyToken = null; } else { pluginAssembly.PublicKeyToken = string.Join(string.Empty, tokenBytes.Select(b => b.ToString("X2"))); } return(pluginAssembly); }
public void LoadFromComponents(List <CrmComponent> components, IOrganizationService service) { foreach (var component in components) { if (component.ComponentType == EnumTypes.ComponentType.Entity) { RetrieveEntityRequest request = new RetrieveEntityRequest { EntityFilters = EntityFilters.All, MetadataId = component.ObjectId }; RetrieveEntityResponse response = (RetrieveEntityResponse)service.Execute(request); AddEntity(new EntityMetadataInfo(response.EntityMetadata)); } else if (component.ComponentType == EnumTypes.ComponentType.PluginAssembly) { var e = service.Retrieve("pluginassembly", component.ObjectId, new ColumnSet(true)); var name = e.GetAttributeValue <string>("name"); var crmAssembly = new CrmPluginAssembly(name); var qe = new QueryByAttribute("plugintype"); qe.ColumnSet = new ColumnSet(true); qe.AddAttributeValue("pluginassemblyid", e.Id); var pts = service.RetrieveMultiple(qe).Entities; var ns = $"{name}."; foreach (var pt in pts) { var typeName = pt.GetAttributeValue <string>("typename")?.Replace(ns, ""); crmAssembly.AddPlugin(new CrmPlugin() { Name = typeName }); } AddAssembly(crmAssembly); } else if (component.ComponentType == EnumTypes.ComponentType.SDKMessageProcessingStep) { var e = service.Retrieve("sdkmessageprocessingstep", component.ObjectId, new ColumnSet(true)); var name = e.GetAttributeValue <string>("name"); } } foreach (var component in components) { if (component.ComponentType == EnumTypes.ComponentType.Attribute) { var rootComponent = components.Where(x => x.Id == component.RootSolutionComponentId).FirstOrDefault <CrmComponent>(); AddAttribute(component, rootComponent); } else if (component.ComponentType == EnumTypes.ComponentType.EntityRelationship) { var rootComponent = components.Where(x => x.Id == component.RootSolutionComponentId).FirstOrDefault <CrmComponent>(); AddManyToOneRelationship(component, rootComponent); AddManyToManyRelationship(component, rootComponent); } } IsLoaded = true; }
private void AddAssembly(CrmPluginAssembly crmPluginAssembly) { PluginAssemblies.Add(crmPluginAssembly); }
/// <summary> /// Assembly is Uploaded if it is database. /// We dont do Smart updates /// </summary> /// <param name="org"></param> /// <param name="pathToAssembly"></param> /// <param name="assembly"></param> public static void UpdateAssembly(CrmOrganization org, string pathToAssembly, CrmPluginAssembly assembly, params PluginType[] type) { if (org == null) { throw new ArgumentNullException("org"); } else if (assembly == null) { throw new ArgumentNullException("assembly"); } PluginAssembly ptl = (PluginAssembly)assembly.GenerateCrmEntities()[PluginAssembly.EntityLogicalName]; //If the assembly path is not set, then the content does not need to be updated if (!string.IsNullOrEmpty(pathToAssembly) && assembly.SourceType == CrmAssemblySourceType.Database) { ptl.Content = Convert.ToBase64String(File.ReadAllBytes(pathToAssembly)); } if (null != type && 0 != type.Length) { ptl.pluginassembly_plugintype = type; } org.OrganizationService.Update(ptl); OrganizationHelper.RefreshAssembly(org, assembly); }
public static Guid RegisterAssembly(CrmOrganization org, string pathToAssembly, CrmPluginAssembly assembly) { if (org == null) { throw new ArgumentNullException("org"); } else if (assembly == null) { throw new ArgumentNullException("assembly"); } else if (assembly.SourceType == CrmAssemblySourceType.Database && pathToAssembly == null) { throw new ArgumentNullException("pathToAssembly", "Cannot be null when SourceType is Database"); } PluginAssembly ptl = (PluginAssembly)assembly.GenerateCrmEntities()[PluginAssembly.EntityLogicalName]; if (assembly.SourceType == CrmAssemblySourceType.Database) { ptl.Content = Convert.ToBase64String(File.ReadAllBytes(pathToAssembly)); } return(org.OrganizationService.Create(ptl)); }
public PluginRegistrationForm(CrmOrganization org, MainControl orgControl, CrmPluginAssembly assembly) { if (org == null) { throw new ArgumentNullException("org"); } else if (orgControl == null) { throw new ArgumentNullException("orgControl"); } InitializeComponent(); m_org = org; m_orgControl = orgControl; m_progRegistration = new ProgressIndicator(ProgressIndicatorInit, ProgressIndicatorComplete, ProgressIndicatorAddText, ProgressIndicatorSetText, ProgressIndicatorIncrement, null); m_currentAssembly = assembly; trvPlugins.CrmTreeNodeSorter = orgControl.CrmTreeNodeSorter; //Check if this is a known assembly if (null == assembly) { //If this is a known assembly, check for the default isolation mode for each authentication type if (null != org.ConnectionDetail) { // TODO: Come back //switch (org.ConnectionDetail.GetDiscoveryService().ServiceConfiguration.AuthenticationType) //{ // case Microsoft.Xrm.Sdk.Client.AuthenticationProviderType.ActiveDirectory: // radIsolationNone.Checked = true; // break; // default: // radIsolationSandbox.Checked = true; // break; //} } } else { m_registeredPluginList = new List <CrmPlugin>(); LoadAssembly(assembly, false); switch (assembly.IsolationMode) { case CrmAssemblyIsolationMode.Sandbox: radIsolationSandbox.Checked = true; break; case CrmAssemblyIsolationMode.None: radIsolationNone.Checked = true; break; default: throw new NotImplementedException("IsolationMode = " + assembly.IsolationMode.ToString()); } switch (assembly.SourceType) { case CrmAssemblySourceType.Database: radDB.Checked = true; break; case CrmAssemblySourceType.Disk: radDisk.Checked = true; break; case CrmAssemblySourceType.GAC: radGAC.Checked = true; break; default: throw new NotImplementedException("SourceType = " + assembly.SourceType.ToString()); } txtServerFileName.Text = assembly.ServerFileName; Text = string.Format("Update Assembly: {0}", assembly.Name); btnRegister.Text = "Update Selected Plugins"; } EnableRegistrationControls(); }
public static void SetupAssemblyPlugins( this CrmPluginAssembly pluginAssembly, Assembly assembly, IReadOnlyCollection <XElement> unsecureConfigItems, IEnumerable <SdkMessage> messages, IEnumerable <SdkMessageFilter> messageFilters) { Version sdkVersion = null; var types = assembly .GetExportedTypes() .Where( t => !t.IsAbstract && t.IsClass && (t.Name.EndsWith("Plugin") || t.Name.EndsWith("Activity"))); foreach (var t in types) { CrmPluginType type; CrmPluginIsolatable isolatable; var xrmPlugin = t.GetInterface(typeof(IPlugin).FullName); if (xrmPlugin != null) { type = CrmPluginType.Plugin; isolatable = CrmPluginIsolatable.Yes; if (sdkVersion == null) { sdkVersion = xrmPlugin.Assembly.GetName().Version; pluginAssembly.SdkVersion = new Version(xrmPlugin.Assembly.GetName().Version.Major, xrmPlugin.Assembly.GetName().Version.Minor); } pluginAssembly.SdkVersion = new Version(sdkVersion.Major, sdkVersion.Minor); } else if (t.IsSubclassOf(typeof(Activity))) { type = CrmPluginType.WorkflowActivity; isolatable = CrmPluginIsolatable.No; } else { throw new Exception("Class is not plugin or workflow"); } var plugin = new CrmPlugin { TypeName = t.FullName, PluginType = type, AssemblyId = pluginAssembly.AssemblyId, AssemblyName = pluginAssembly.Name, Isolatable = isolatable, FriendlyName = Guid.NewGuid().ToString() }; if (type == CrmPluginType.WorkflowActivity) { var attr = t.GetCustomAttribute <WorkflowActivityAttribute>(); plugin.WorkflowActivityGroupName = " " + attr.WorkflowActivityGroupName; plugin.Name = " " + attr.Name; } var pluginEntityType = t.BaseType?.GetGenericArguments().LastOrDefault(); if (pluginEntityType == null) { // note: be sure - it is workflow:) pluginAssembly.AddPlugin(plugin); continue; } var splitted = t.FullName?.Split('.').Reverse().Take(2).ToArray(); var typeName = splitted?[0].Replace("Plugin", string.Empty); plugin.Name = $" {splitted?[1]}: {typeName}"; var stepMethods = t.GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(m => m.DeclaringType == t).ToArray(); foreach (var stepMethod in stepMethods) { var pluginStepAttrs = stepMethod.GetCustomAttributes <PluginStepAttribute>(); var filteringAttributes = stepMethod.GetCustomAttribute <FilteringAttributesAttribute>(); foreach (var pluginStepAttr in pluginStepAttrs) { var step = new CrmPluginStep { AssemblyId = plugin.AssemblyId, PluginId = plugin.Id, DeleteAsyncOperationIfSuccessful = pluginStepAttr.DeleteAsyncOperationIfSuccessful, Deployment = CrmPluginStepDeployment.ServerOnly, Enabled = pluginStepAttr.Enabled, Name = RegistrationHelper.GenerateStepName(typeName, pluginStepAttr.PluginMessageName, pluginStepAttr.EntityLogicalName.ToLowerInvariant(), null), Rank = pluginStepAttr.Rank, Stage = (CrmPluginStepStage)pluginStepAttr.Stage, Mode = pluginStepAttr.ExecutionMode == PluginExecutionMode.Asynchronous ? CrmPluginStepMode.Asynchronous : CrmPluginStepMode.Synchronous, MessageId = messages.First(m => m.Name == pluginStepAttr.PluginMessageName).Id }; var filter = messageFilters.FirstOrDefault( f => f.SdkMessageId.Id == step.MessageId && f.PrimaryEntityLogicalName == pluginStepAttr.EntityLogicalName.ToLowerInvariant()); if (filter == null) { throw new Exception($"{pluginStepAttr.EntityLogicalName} entity doesn't registered yet"); } step.MessageEntityId = filter.Id; if (filteringAttributes != null) { step.FilteringAttributes = filteringAttributes.ToString(); } var unsecureItem = unsecureConfigItems.FirstOrDefault(it => it.Attribute("key").Value == pluginStepAttr.UnsecureConfig); if (unsecureItem != null) { var value = unsecureItem.Attribute("value").Value; step.UnsecureConfiguration = value == $"#{{{pluginStepAttr.UnsecureConfig}}}" ? unsecureItem.Attribute("default").Value : value; } foreach (var p in stepMethod.GetParameters().Where(p => p.ParameterType == pluginEntityType)) { var imageParameters = p.GetCustomAttribute <ImageParametersAttribute>(); if (imageParameters == null) { continue; } CrmPluginImage image; switch (p.Name) { case "preEntityImage": image = CreateImage(step, imageParameters.ToString(), pluginStepAttr.PluginMessageName, CrmPluginImageType.PreImage); step.AddImage(image); break; case "postEntityImage": image = CreateImage(step, imageParameters.ToString(), pluginStepAttr.PluginMessageName, CrmPluginImageType.PostImage); step.AddImage(image); break; } } plugin.AddStep(step); } } pluginAssembly.AddPlugin(plugin); } }
public static void SetupAssemblyPlugins( this CrmPluginAssembly pluginAssembly, Version sdkVersion, XDocument config, IEnumerable <SdkMessage> messages, IEnumerable <SdkMessageFilter> messageFilters) { XNamespace ns = "http://schemas.microsoft.com/crm/2011/tools/pluginregistration"; var pluginElements = config.Root.Element(ns + "Solutions").Element(ns + "Solution").Element(ns + "PluginTypes").Elements(ns + "Plugin"); foreach (var pluginElement in pluginElements) { CrmPluginType type; CrmPluginIsolatable isolatable; var typeName = pluginElement.Attribute("TypeName").Value; if (typeName.EndsWith("Plugin")) { type = CrmPluginType.Plugin; isolatable = CrmPluginIsolatable.Yes; if (sdkVersion != null) { pluginAssembly.SdkVersion = new Version(sdkVersion.Major, sdkVersion.Minor); } } else if (typeName.EndsWith("Activity")) { type = CrmPluginType.WorkflowActivity; isolatable = CrmPluginIsolatable.No; } else { throw new Exception("Class is not plugin or workflow"); } var plugin = new CrmPlugin { TypeName = typeName, PluginType = type, AssemblyId = pluginAssembly.AssemblyId, AssemblyName = pluginAssembly.Name, Isolatable = isolatable, FriendlyName = pluginElement.Attribute("FriendlyName").Value }; if (type == CrmPluginType.WorkflowActivity) { plugin.WorkflowActivityGroupName = " " + pluginElement.Attribute("FriendlyName").Value; plugin.Name = " " + pluginElement.Attribute("Name").Value; pluginAssembly.AddPlugin(plugin); continue; } var splitted = typeName.Split('.').Reverse().Take(2).ToArray(); var pluginName = splitted[0].Replace("Plugin", string.Empty); plugin.Name = $" {splitted[1]}: {pluginName}"; foreach (var pluginStepEl in pluginElement.Element(ns + "Steps").Elements(ns + "Step")) { var step = new CrmPluginStep { AssemblyId = plugin.AssemblyId, PluginId = plugin.Id, DeleteAsyncOperationIfSuccessful = false, // ToDo: implement for ugly config Deployment = CrmPluginStepDeployment.ServerOnly, Enabled = true, // ToDo: implement for ugly config Name = pluginStepEl.Attribute("Name").Value, Rank = int.Parse(pluginStepEl.Attribute("Rank").Value), Stage = pluginStepEl.Attribute("Stage").Value == "PreInsideTransaction" ? CrmPluginStepStage.PreOperation : CrmPluginStepStage.PostOperation, // ToDo: CrmPluginStepStage.PreValidation Mode = pluginStepEl.Attribute("Mode").Value == PluginExecutionMode.Asynchronous.ToString().ToLowerInvariant() ? CrmPluginStepMode.Asynchronous : CrmPluginStepMode.Synchronous, MessageId = messages.First(m => m.Name == pluginStepEl.Attribute("MessageName").Value).Id, Description = pluginStepEl.Attribute("Description").Value }; var filter = messageFilters.FirstOrDefault( f => f.SdkMessageId.Id == step.MessageId && f.PrimaryEntityLogicalName == pluginStepEl.Attribute("PrimaryEntityName").Value.ToLowerInvariant()); if (filter == null) { throw new Exception($"{pluginStepEl.Attribute("PrimaryEntityName").Value} entity doesn't registered yet"); } step.MessageEntityId = filter.Id; var attr = pluginStepEl.Attribute("FilteringAttributes"); if (!string.IsNullOrEmpty(attr?.Value)) { step.FilteringAttributes = attr.Value; } var unsecureItem = pluginStepEl.Attribute("CustomConfiguration").Value; if (!string.IsNullOrEmpty(unsecureItem)) { step.UnsecureConfiguration = unsecureItem; } foreach (var imageEl in pluginStepEl.Element(ns + "Images").Elements(ns + "Image")) { var image = CreateImage(step, imageEl, pluginStepEl); if (image != null) { step.AddImage(image); } } plugin.AddStep(step); } pluginAssembly.AddPlugin(plugin); } }
public PluginRegistrationForm(CrmOrganization org, MainControl orgControl, CrmPluginAssembly assembly, List <PluginAssemblyFileMapping> mapping) { if (org == null) { throw new ArgumentNullException("org"); } else if (orgControl == null) { throw new ArgumentNullException("orgControl"); } InitializeComponent(); m_org = org; m_orgControl = orgControl; m_progRegistration = new ProgressIndicator(ProgressIndicatorInit, ProgressIndicatorComplete, ProgressIndicatorAddText, ProgressIndicatorSetText, ProgressIndicatorIncrement, null); m_currentAssembly = assembly; m_mapping = mapping; radIsolationSandbox.Checked = org.ConnectionDetail.UseOnline; trvPlugins.CrmTreeNodeSorter = orgControl.CrmTreeNodeSorter; //Check if this is a known assembly if (null == assembly) { //If this is a known assembly, check for the default isolation mode for each authentication type if (null != org.ConnectionDetail) { // TODO: Come back //switch (org.ConnectionDetail.GetDiscoveryService().ServiceConfiguration.AuthenticationType) //{ // case Microsoft.Xrm.Sdk.Client.AuthenticationProviderType.ActiveDirectory: // radIsolationNone.Checked = true; // break; // default: // radIsolationSandbox.Checked = true; // break; //} } } else { m_registeredPluginList = new List <CrmPlugin>(); LoadAssembly(assembly, false); switch (assembly.IsolationMode) { case CrmAssemblyIsolationMode.Sandbox: radIsolationSandbox.Checked = true; break; case CrmAssemblyIsolationMode.None: radIsolationNone.Checked = true; break; default: throw new NotImplementedException($"IsolationMode = { assembly.IsolationMode.ToString() }"); } switch (assembly.SourceType) { case CrmAssemblySourceType.Database: radDB.Checked = true; break; case CrmAssemblySourceType.Disk: radDisk.Checked = true; break; case CrmAssemblySourceType.GAC: radGAC.Checked = true; break; default: throw new NotImplementedException($"SourceType = {assembly.SourceType.ToString()}"); } txtServerFileName.Text = assembly.ServerFileName; var mappedFileName = mapping.FirstOrDefault(m => m.PluginAssemblyName == assembly.Name)?.FilePath; if (!string.IsNullOrEmpty(mappedFileName) && File.Exists(mappedFileName)) { AssemblyPathControl.FileName = mappedFileName; AssemblyPathControl_PathChanged(AssemblyPathControl, new EventArgs()); btnLoadAssembly_Click(btnLoadAssembly, new EventArgs()); } Text = $"Update Assembly: {assembly.Name}"; btnRegister.Text = "Update Selected Plugins"; } EnableRegistrationControls(); }
private void Process(CrmPluginAssembly assembly, string mergedPluginAssemblyPath) { // ToDo: use DataFlow var currentAssembly = AssemblyHelper.LoadAssemblyFromDB(assembly.Name); var createAssembly = currentAssembly == null; var pluginsForRegister = new List <CrmPlugin>(); var pluginsForRemove = new List <CrmPlugin>(); var pluginsForUpdate = new List <(CrmPlugin plugin, CrmPlugin existed)>(); if (createAssembly) { pluginsForRegister.AddRange(assembly.CrmPlugins); } else { CrmPlugin GetCorrelated(CrmPluginAssembly a, CrmPlugin plugin) => a.CrmPlugins.FirstOrDefault(p => p.TypeName == plugin.TypeName); pluginsForRegister.AddRange( from plugin in assembly.CrmPlugins where GetCorrelated(currentAssembly, plugin) == null select plugin); pluginsForRemove.AddRange( from plugin in currentAssembly.CrmPlugins where GetCorrelated(assembly, plugin) == null select plugin); pluginsForUpdate.AddRange( from plugin in assembly.CrmPlugins let existed = GetCorrelated(currentAssembly, plugin) where existed != null select(plugin, existed)); } if (createAssembly) { try { assembly.IsolationMode = CrmAssemblyIsolationMode.None; assembly.AssemblyId = AssemblyHelper.CreateAssemblyInDB(mergedPluginAssemblyPath, assembly); } catch (Exception ex) { throw new Exception("ERROR: Error occurred while registering the plugin assembly", ex); } } else { UnregisterPlugins(pluginsForRemove); assembly.IsolationMode = currentAssembly.IsolationMode; assembly.AssemblyId = currentAssembly.AssemblyId; var workflows = (from plugin in currentAssembly.CrmPlugins where plugin.PluginType == CrmPluginType.WorkflowActivity select new PluginType { Id = plugin.Id, WorkflowActivityGroupName = plugin.WorkflowActivityGroupName }).ToArray(); AssemblyHelper.UpdateAssemblyInDB(mergedPluginAssemblyPath, assembly, workflows); } RegisterPlugins(pluginsForRegister); UpdatePlugins(pluginsForUpdate); }