private void GeneratorJsWebApi(string entity, int i, int count) { if (GeneratorJson.usetypescriptdeclaration == "true") { var fileTypeScriptDeclaration = $"{CurrentDirectory}\\{GeneratorJson.rootfolder}\\{entity}.d.ts"; var lines = File.ReadAllLines(fileTypeScriptDeclaration); var json = lines[lines.Length - 1]; var comment = SimpleJson.DeserializeObject <CommentIntellisense>(json.Substring("//".Length).Replace("'", "\"")); var parts = GeneratorJson.rootnamespace.Split(".".ToCharArray()); var projectName = parts.Length > 1 ? parts[1] : parts[0]; var jsWebApi = new JsWebApi(CrmServiceClient.OrganizationServiceProxy, projectName, entity, comment.IsDebugWebApi, comment.JsForm, comment.IsDebugForm); jsWebApi.GeneratorCode(); var old = File.ReadAllText(fileTypeScriptDeclaration).Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); var @new = jsWebApi.WebApiCodeTypeScriptDeclaration.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); if (old != @new) { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + count.ToString().Length + "}", "", i) + ": Processing ", CliLog.ColorGreen, entity, ".d.ts"); if (Utility.CanWriteAllText(fileTypeScriptDeclaration)) { File.WriteAllText(fileTypeScriptDeclaration, jsWebApi.WebApiCodeTypeScriptDeclaration, System.Text.Encoding.UTF8); } } else { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + count.ToString().Length + "}", "", i) + ": No change ", CliLog.ColorGreen, entity, ".d.ts"); } var fileWebApi = $"{CurrentDirectory}\\{GeneratorJson.rootfolder}\\{entity}.webapi.js"; old = File.ReadAllText(fileWebApi).Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); @new = jsWebApi.WebApiCode.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); if (old != @new) { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + count.ToString().Length + "}", "", i) + ": Processing ", CliLog.ColorGreen, entity, ".webapi.js"); if (Utility.CanWriteAllText(fileWebApi)) { File.WriteAllText(fileWebApi, jsWebApi.WebApiCode, System.Text.Encoding.UTF8); } } else { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + count.ToString().Length + "}", "", i) + ": No change ", CliLog.ColorGreen, entity, ".webapi.js"); } } else { var fileIntellisense = $"{CurrentDirectory}\\{GeneratorJson.rootfolder}\\{entity}.intellisense.js"; var lines = File.ReadAllLines(fileIntellisense); var json = lines[lines.Length - 1]; var comment = SimpleJson.DeserializeObject <CommentIntellisense>(json.Substring("//".Length).Replace("'", "\"")); var parts = GeneratorJson.rootnamespace.Split(".".ToCharArray()); var projectName = parts.Length > 1 ? parts[1] : parts[0]; var jsWebApi = new JsWebApi(CrmServiceClient.OrganizationServiceProxy, projectName, entity, comment.IsDebugWebApi, comment.JsForm, comment.IsDebugForm); jsWebApi.GeneratorCode(); var old = File.ReadAllText(fileIntellisense).Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); var @new = jsWebApi.WebApiCodeIntellisense.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); if (old != @new) { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + count.ToString().Length + "}", "", i) + ": Processing ", CliLog.ColorGreen, entity, ".intellisense.js"); if (Utility.CanWriteAllText(fileIntellisense)) { File.WriteAllText(fileIntellisense, jsWebApi.WebApiCodeIntellisense, System.Text.Encoding.UTF8); } } else { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + count.ToString().Length + "}", "", i) + ": No change ", CliLog.ColorGreen, entity, ".intellisense.js"); } var fileWebApi = $"{CurrentDirectory}\\{GeneratorJson.rootfolder}\\{entity}.webapi.js"; old = File.ReadAllText(fileWebApi).Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); @new = jsWebApi.WebApiCode.Replace(" ", string.Empty).Replace("\r\n", string.Empty).Replace("\t", string.Empty); if (old != @new) { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + count.ToString().Length + "}", "", i) + ": Processing ", CliLog.ColorGreen, entity, ".webapi.js"); if (Utility.CanWriteAllText(fileWebApi)) { File.WriteAllText(fileWebApi, jsWebApi.WebApiCode, System.Text.Encoding.UTF8); } } else { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + count.ToString().Length + "}", "", i) + ": No change ", CliLog.ColorGreen, entity, ".webapi.js"); } } }
private Entity RegisterAssembly(FileInfo assemblyFilePath, Assembly assembly, IEnumerable <Type> plugins) { var firstType = GetAttributes(plugins, typeof(CrmPluginRegistrationAttribute).Name).FirstOrDefault(); if (firstType == null) { var message = "Plugin Assembly don't have any type: CrmPluginRegistrationAttribute"; CliLog.WriteLine(CliLog.COLOR_ERROR, message); throw new Exception(message); } var firstTypeAttribute = firstType.CreateFromData() as CrmPluginRegistrationAttribute; var assemblyProperties = assembly.GetName().FullName.Split(",= ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); var assemblyName = assembly.GetName().Name; var fetchData = new { name = assemblyProperties[0] }; var fetchXml = $@" <fetch> <entity name='pluginassembly'> <attribute name='pluginassemblyid' /> <attribute name='content' /> <filter type='and'> <condition attribute='name' operator='eq' value='{fetchData.name}'/> </filter> </entity> </fetch>"; var rows = CrmServiceClient.RetrieveMultiple(new FetchExpression(fetchXml)); Guid pluginAssemblyId = Guid.Empty; var existingContent = string.Empty; if (rows.Entities.Count > 0) { var entity = rows.Entities[0]; pluginAssemblyId = entity.Id; existingContent = entity.GetAttributeValue <string>("content"); } string content = Convert.ToBase64String(File.ReadAllBytes(assemblyFilePath.FullName)); if (content == existingContent) { return(null); } var plugin = new Entity("pluginassembly"); plugin["content"] = content; plugin["name"] = assemblyProperties[0]; plugin["culture"] = assemblyProperties[4]; plugin["version"] = assemblyProperties[2]; plugin["publickeytoken"] = assemblyProperties[6]; plugin["sourcetype"] = new OptionSetValue(0); // database plugin["isolationmode"] = firstTypeAttribute.IsolationMode == IsolationModeEnum.Sandbox ? new OptionSetValue(2) : // 2 = sandbox new OptionSetValue(1); // 1 = none if (pluginAssemblyId == Guid.Empty) { CliLog.WriteLine(CliLog.COLOR_GREEN, "Registering Assembly: ", CliLog.COLOR_CYAN, $"{assemblyProperties[0]}"); pluginAssemblyId = CrmServiceClient.Create(plugin); plugin["pluginassemblyid"] = pluginAssemblyId; } else { CliLog.WriteLine(CliLog.COLOR_BLUE, "Updating Assembly: ", CliLog.COLOR_CYAN, $"{assemblyProperties[0]}"); plugin["pluginassemblyid"] = pluginAssemblyId; CrmServiceClient.Update(plugin); } return(plugin); }
private void RegisterPluginSteps(Entity pluginTypeEntity, TypeInfo plugin) { var pluginAttributes = plugin.GetCustomAttributesData().Where(a => a.AttributeType.Name == typeof(CrmPluginRegistrationAttribute).Name); if (pluginAttributes.Count() == 0) { return; } foreach (var pluginAttribute in pluginAttributes) { var attribute = pluginAttribute.CreateFromData(); if (attribute.Message.ToLower() == "update") { if (string.IsNullOrEmpty(attribute.FilteringAttributes)) { var message = "Update Message should have FilteringAttributes value"; CliLog.WriteLine(CliLog.COLOR_ERROR, message); throw new Exception(message); } } var step = new Entity("sdkmessageprocessingstep"); step["name"] = attribute.Name; step["configuration"] = attribute.UnSecureConfiguration; step["description"] = attribute.Description; step["mode"] = new OptionSetValue(attribute.ExecutionMode == ExecutionModeEnum.Asynchronous ? 1 : 0); step["rank"] = attribute.ExecutionOrder; step["stage"] = new OptionSetValue((int)attribute.Stage); if (attribute.DeleteAsyncOperation) { step["asyncautodelete"] = attribute.DeleteAsyncOperation; } int supportDeployment = 0; if (attribute.Server == true && attribute.Offline == true) { supportDeployment = 2; // Both } else if (!attribute.Server == true && attribute.Offline == true) { supportDeployment = 1; // Offline only } else { supportDeployment = 0; // Server Only } step["supporteddeployment"] = new OptionSetValue(supportDeployment); step["plugintypeid"] = new EntityReference("plugintype", Guid.Parse(pluginTypeEntity["plugintypeid"].ToString())); var sdkMessageFilterId = GetSdkMessageFilterId(attribute.EntityLogicalName, attribute.Message); if (sdkMessageFilterId != null) { step["sdkmessagefilterid"] = sdkMessageFilterId; } var sdkMessageId = GetSdkMessageId(attribute.EntityLogicalName, attribute.Message); if (sdkMessageId != null) { step["sdkmessageid"] = sdkMessageId; } if (attribute.FilteringAttributes.Length > 0) { step["filteringattributes"] = attribute.FilteringAttributes.Replace(" ", ""); } var fetchData = new { plugintypeid = pluginTypeEntity["plugintypeid"].ToString(), name = attribute.Name, sdkmessageidname = attribute.Message }; var fetchXml = $@" <fetch> <entity name='sdkmessageprocessingstep'> <attribute name='sdkmessageprocessingstepid' /> <filter type='and'> <condition attribute='plugintypeid' operator='eq' value='{fetchData.plugintypeid}'/> <condition attribute='name' operator='eq' value='{fetchData.name}'/> <condition attribute='sdkmessageidname' operator='eq' value='{fetchData.sdkmessageidname}'/> </filter> </entity> </fetch>"; var rows = CrmServiceClient.RetrieveMultiple(new FetchExpression(fetchXml)); Guid sdkMessageProcessingStepId = Guid.Empty; if (rows.Entities.Count > 0) { sdkMessageProcessingStepId = rows.Entities[0].Id; step["sdkmessageprocessingstepid"] = sdkMessageProcessingStepId; CliLog.WriteLine(CliLog.COLOR_BLUE, $"\t\tUpdating Step: ", CliLog.COLOR_CYAN, $"{attribute.Name}"); CrmServiceClient.Update(step); } else { CliLog.WriteLine(CliLog.COLOR_GREEN, $"\t\tRegistering Step: ", CliLog.COLOR_CYAN, $"{attribute.Name}"); sdkMessageProcessingStepId = CrmServiceClient.Create(step); step["sdkmessageprocessingstepid"] = sdkMessageProcessingStepId; } AddStepToSolution(step); if (attribute?.Image1Attributes?.Length > 0 || attribute?.Image2Attributes?.Length > 0) { GetPluginStepImages(attribute, sdkMessageProcessingStepId); } } }
public void Run() { CliLog.WriteLine(CliLog.ColorGreen, new string('*', CliLog.StarLength)); CliLog.WriteLine(CliLog.ColorGreen, "START WEBRESOURCE TASKS"); CliLog.WriteLine(CliLog.ColorGreen, new string('*', CliLog.StarLength)); var files = WebResourceFiles; if (!files.Any()) { throw new Exception("No webresource files found. Please check PL.DynamicsCrm.DevKit.Cli.json file !!!"); } if (WebResourceJson.solution.Length == 0 || WebResourceJson.solution == "???") { throw new Exception("No solution found in webresource profile. Please check PL.DynamicsCrm.DevKit.Cli.json file !!!"); } if (WebResourceJson.prefix.Length == 0 || WebResourceJson.prefix == "???") { throw new Exception("No prefix found in webresource profile. Please check PL.DynamicsCrm.DevKit.Cli.json file !!!"); } var isSupportWebResourceDependency = IsSupportWebResourceDependency; var dependencies = new List <Dependency>(); if (isSupportWebResourceDependency) { dependencies = MergeDependencies(WebResourceJson.dependencies, files); foreach (var dependency in dependencies) { var check = dependency.dependencies.Where(x => x.StartsWith("???_/")).Any(); if (check) { throw new Exception("Found ???_/ in webresource dependencies. Please check PL.DynamicsCrm.DevKit.Cli.json file !!!"); } var check2 = dependency.webresources.Where(x => x.StartsWith("???_/")).Any(); if (check2) { throw new Exception("Found ???_/ in webresource dependencies. Please check PL.DynamicsCrm.DevKit.Cli.json file !!!"); } } } var totalWebResources = files.Count; CliLog.WriteLine(CliLog.ColorGreen, "Found: ", CliLog.ColorCyan, totalWebResources, CliLog.ColorGreen, " webresources"); var i = 1; foreach (var webResourceFile in files) { DeployWebResource(webResourceFile, i, totalWebResources); i++; } if (isSupportWebResourceDependency) { CliLog.WriteLine(CliLog.ColorGreen, "Found: ", CliLog.ColorCyan, dependencies.Count, CliLog.ColorGreen, " dependencies"); var j = 1; foreach (var dependency in dependencies) { UpdateDependency(dependency, j, dependencies.Count); j++; } } if (WebResourcesToPublish.Count > 0) { PublishWebResources(); } CliLog.WriteLine(CliLog.ColorGreen, new string('*', CliLog.StarLength)); CliLog.WriteLine(CliLog.ColorGreen, "END WEBRESOURCE TASKS"); CliLog.WriteLine(CliLog.ColorGreen, new string('*', CliLog.StarLength)); }
private void DeployWebResource(WebResourceFile webResourceFile, int current, int totalWebResources) { var len = totalWebResources.ToString().Length; if (webResourceFile.uniquename.StartsWith("/")) { webResourceFile.uniquename = webResourceFile.uniquename.Substring(1); } var fetchData = new { name = webResourceFile.uniquename, name2 = webResourceFile.uniquename.Substring(0, webResourceFile.uniquename.LastIndexOf('.')) }; var fetchXml = $@" <fetch> <entity name='webresource'> <attribute name='content' /> <attribute name='webresourceid' /> <attribute name='name' /> <attribute name='iscustomizable' /> <filter type='or'> <condition attribute='name' operator='eq' value='{fetchData.name}'/> <condition attribute='name' operator='eq' value='{fetchData.name2}'/> </filter> </entity> </fetch>"; var rows = CrmServiceClient.RetrieveMultiple(new FetchExpression(fetchXml)); var content = string.Empty; var webResourceId = Guid.Empty; if (rows.Entities.Count > 0) { if (rows.Entities.Count == 1) { var entity = rows.Entities[0]; var iscustomizable = entity.GetAttributeValue <BooleanManagedProperty>("iscustomizable"); if (iscustomizable?.Value == false) { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + len + "}", "", current) + ": ", CliLog.ColorRed, "Update webresource failed: ", CliLog.ColorGreen, webResourceFile.uniquename); return; } webResourceId = entity.Id; content = entity?["content"]?.ToString(); } else { foreach (var row in rows.Entities) { if (row.GetAttributeValue <string>("name") != fetchData.name) { continue; } var iscustomizable = row.GetAttributeValue <BooleanManagedProperty>("iscustomizable"); if (iscustomizable?.Value == false) { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + len + "}", "", current) + ": ", CliLog.ColorRed, "Update webresource failed: ", CliLog.ColorGreen, webResourceFile.uniquename); return; } webResourceId = row.Id; content = row?["content"]?.ToString(); break; } } } var fileContent = Convert.ToBase64String(File.ReadAllBytes(webResourceFile.file)); if (fileContent == content) { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + len + "}", "", current) + ": ", CliLog.ColorRed, "No Change ", CliLog.ColorGreen, webResourceFile.file.Substring(CurrentDirectory.Length + 1)); return; } var webResource = new Entity("webresource") { ["name"] = webResourceFile.uniquename, ["displayname"] = webResourceFile.displayname, ["description"] = webResourceFile.version, ["content"] = fileContent }; var webResourceFileInfo = new FileInfo(webResourceFile.file); var fileType = WebResourceWebResourceType.ScriptJScript; switch (webResourceFileInfo.Extension.ToLower().TrimStart('.')) { case "html": case "htm": fileType = WebResourceWebResourceType.WebpageHtml; break; case "js": fileType = WebResourceWebResourceType.ScriptJScript; break; case "png": fileType = WebResourceWebResourceType.PngFormat; break; case "gif": fileType = WebResourceWebResourceType.GifFormat; break; case "jpg": case "jpeg": fileType = WebResourceWebResourceType.JpgFormat; break; case "css": fileType = WebResourceWebResourceType.StyleSheetCss; break; case "ico": fileType = WebResourceWebResourceType.IcoFormat; break; case "xml": fileType = WebResourceWebResourceType.DataXml; break; case "xsl": case "xslt": fileType = WebResourceWebResourceType.StyleSheetXsl; break; case "xap": fileType = WebResourceWebResourceType.SilverlightXap; break; case "resx": fileType = WebResourceWebResourceType.StringResx; break; case "svg": fileType = WebResourceWebResourceType.SvgFormat; break; } webResource["webresourcetype"] = new OptionSetValue((int)fileType); if (fileType == WebResourceWebResourceType.StringResx) { var fileName = webResourceFileInfo.Name.Substring(0, webResourceFileInfo.Name.Length - webResourceFileInfo.Extension.Length); var arr = fileName.Split(".".ToCharArray()); if (int.TryParse(arr[arr.Length - 1], out var languagecode)) { var req = new RetrieveProvisionedLanguagesRequest(); var res = (RetrieveProvisionedLanguagesResponse)CrmServiceClient.Execute(req); if (res.RetrieveProvisionedLanguages.Contains(languagecode)) { webResource["languagecode"] = languagecode; } else { throw new Exception($"Language code not found: {languagecode}"); } } } if (webResourceId == Guid.Empty) { CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + len + "}", "", current), ": ", CliLog.ColorRed, "Creating", CliLog.ColorGreen, " WebResource ", CliLog.ColorCyan, webResourceFile.file, CliLog.ColorGreen, " to ", CliLog.ColorCyan, webResourceFile.uniquename); webResourceId = CrmServiceClient.Create(webResource); webResource["webresourceid"] = webResourceId; } else { webResource["webresourceid"] = webResourceId; CliLog.WriteLine(CliLog.ColorCyan, string.Format("{0,0}|{1," + len + "}", "", current), ": ", CliLog.ColorRed, "Updating", CliLog.ColorBlue, " WebResource ", CliLog.ColorCyan, webResourceFile.file, CliLog.ColorGreen, " to ", CliLog.ColorCyan, webResourceFile.uniquename); CrmServiceClient.Update(webResource); } WebResourcesToPublish.Add(webResourceId); AddWebResourceToSolution(webResource); return; }
private static bool IsValid(CommandLineArgs arguments) { if (arguments.Connection.Length == 0) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/conn: missing"); return(false); } if (arguments.Json.Length == 0) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/json: missing"); return(false); } var jsonFile = Path.Combine(CurrentDirectory, arguments.Json); if (!File.Exists(jsonFile)) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/json: PL.DynamicsCrm.DevKit json missing [{jsonFile}]"); return(false); } var json = SimpleJson.DeserializeObject <CliJson>(File.ReadAllText(jsonFile)); if (arguments.Type.Length > 0) { var types = new List <string>() { TaskType.plugins.ToString(), TaskType.workflows.ToString(), TaskType.webresources.ToString() }; if (!types.Contains(arguments.Type)) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/type: should be: plugins or workflows or webresources"); return(false); } } else { PluginJson = json.plugins.Where(x => x.profile == arguments.Profile).FirstOrDefault(); WorkflowJson = json.workflows.Where(x => x.profile == arguments.Profile).FirstOrDefault(); WebResourceJson = json.webresources.Where(x => x.profile == arguments.Profile).FirstOrDefault(); } if (arguments.Profile.Length == 0) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/profile: missing"); return(false); } if (arguments.Version.Length == 0) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/version: missing"); return(false); } if (arguments.Type == TaskType.plugins.ToString()) { PluginJson = json.plugins.Where(x => x.profile == arguments.Profile).FirstOrDefault(); if (PluginJson == null) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/profile: not found profile: {arguments.Profile}"); return(false); } } else if (arguments.Type == TaskType.workflows.ToString()) { WorkflowJson = json.workflows.Where(x => x.profile == arguments.Profile).FirstOrDefault(); if (WorkflowJson == null) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/profile: not found profile: {arguments.Profile}"); return(false); } } else if (arguments.Type == TaskType.webresources.ToString()) { WebResourceJson = json.webresources.Where(x => x.profile == arguments.Profile).FirstOrDefault(); if (WebResourceJson == null) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/profile: not found profile: {arguments.Profile}"); return(false); } } if (!IsConnectedDynamics365(arguments.Connection)) { CliLog.WriteLine(CliLog.COLOR_ERROR, $"/conn: Cannot connect to Dynamics 365 with your Connection String: {arguments.Connection}"); return(false); } CliLog.WriteLine(CliLog.COLOR_YELLOW, "Connected ", CliLog.COLOR_MAGENTA, "Dynamics CRM!"); return(true); }