private static void BuildEvents_OnBuildProjConfigDone(string Project, string ProjectConfig, string Platform, string SolutionConfig, bool Success) { Dte.Events.BuildEvents.OnBuildProjConfigDone -= BuildEvents_OnBuildProjConfigDone; if (!Success || !ProjectUniqueName.EndsWith(Project)) { return; } Dte.StatusBar.Text = "Build project report succeeded!"; #if DEBUG ProjectUniqueName = @"C:\src\github\phuocle\Dynamics-Crm-DevKit\test\TestReport\Test.Abc.Report.2015\Test.Abc.Report.2015.rptproj"; #endif var xml = File.ReadAllText(ProjectUniqueName); var xdoc = XDocument.Parse(xml); //Fist check for project VS2015 var node = (from x in xdoc?.Descendants("Project")?.Descendants("Configurations")?.Elements("Configuration") where x?.Element("Name")?.Value == ProjectConfig select x)?.FirstOrDefault(); var outputPath = node?.Descendants("Options")?.FirstOrDefault()?.Element("OutputPath")?.Value; //if null, then check for project VS2017 if (outputPath == null) { var nodes = (from x in xdoc?.Root.Elements() where x?.Name?.LocalName == "PropertyGroup" select x); foreach (var n in nodes) { if (n.Elements().Where(x => x?.Name?.LocalName == "FullPath" && x?.Value == "Debug").Any()) { outputPath = n.Elements().Where(x => x?.Name?.LocalName == "OutputPath").FirstOrDefault()?.Value; break; } } } if (outputPath == null) { throw new Exception("Cannot read the Output directory of the current report project"); } var folderOutput = Path.Combine(Path.GetDirectoryName(ProjectUniqueName), outputPath); var fileName = Path.GetFileName(Dte.SelectedItems.Item(1).ProjectItem.FileNames[0]); var deployFile = Path.Combine(folderOutput, fileName); if (!File.Exists(deployFile)) { throw new Exception($"Cannot find deployable report: {deployFile}"); } Dte.StatusBar.Text = "Connecting to Dynamics 365"; var check = SharedGlobals.GetGlobal("CrmService", Dte); if (check == null) { var activeDocument = Dte.ActiveDocument; var solutionFullName = Dte.Solution.FullName; var fInfo = new FileInfo(solutionFullName); var devKitCrmConfigFile = $"{fInfo.DirectoryName}\\PL.DynamicsCrm.DevKit.json"; Dte.StatusBar.Text = "Reading PL.DynamicsCrm.DevKit.json config"; if (Config == null) { Config = DevKitCrmConfigHelper.GetDevKitCrmConfig(Dte); } var defaultConnection = Config.CrmConnections.Where(conn => conn.Name == Config.DefaultCrmConnection).FirstOrDefault(); if (defaultConnection == null) { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! Connection to Dynamics 365 failed !!! "; MessageBox.Show("Default Crm connection not found!", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } try { var uri = new Uri(defaultConnection.Url); var clientCredentials = new ClientCredentials(); clientCredentials.UserName.UserName = defaultConnection.UserName; clientCredentials.UserName.Password = TryDecryptPassword(defaultConnection.Password); check = new OrganizationServiceProxy(uri, null, clientCredentials, null); SharedGlobals.SetGlobal("CrmService", check, Dte); Dte.StatusBar.Text = " !!! Connected Dynamics 365 !!! "; } catch { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! Connection to Dynamics 365 failed !!! "; MessageBox.Show("Connecting to Dynamics 365 failed!", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } else { Dte.StatusBar.Text = " !!! Connected Dynamics 365 !!! "; } var crmService = (OrganizationServiceProxy)SharedGlobals.GetGlobal("CrmService", Dte); var fetchData = new { ismanaged = "0", filename = fileName }; var fetchXml = $@" <fetch> <entity name='report'> <attribute name='reportid' /> <filter type='and'> <condition attribute='ismanaged' operator='eq' value='{fetchData.ismanaged/*0*/}'/> <condition attribute='filename' operator='eq' value='{fetchData.filename/*ReportTemplate.rdl*/}'/> </filter> </entity> </fetch>"; var rows = crmService.RetrieveMultiple(new FetchExpression(fetchXml)); if (rows.Entities.Count == 0) { throw new Exception("Please deploy this report first by Dynamics 365"); } if (rows.Entities.Count != 1) { throw new Exception($"Found {rows.Entities.Count} reports file name: {fileName} in the system. Cannot deploy."); } Dte.StatusBar.Text = "Deploying Report ..."; var update = new Entity("report", rows.Entities[0].Id); update["bodytext"] = File.ReadAllText(deployFile); crmService.Update(update); Dte.StatusBar.Text = " !!! Deploy Report succeeded !!! "; Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); }
private static void ExecuteWebResource(AsyncPackage package) { Dte.StatusBar.Animate(true, vsStatusAnimation.vsStatusAnimationDeploy); var activeDocument = Dte.ActiveDocument; var solutionFullName = Dte.Solution.FullName; var fInfo = new FileInfo(solutionFullName); var devKitCrmConfigFile = $"{fInfo.DirectoryName}\\PL.DynamicsCrm.DevKit.json"; Dte.StatusBar.Text = "Reading PL.DynamicsCrm.DevKit.json config"; if (Config == null) { Config = DevKitCrmConfigHelper.GetDevKitCrmConfig(Dte); } var defaultConnection = Config.CrmConnections.Where(conn => conn.Name == Config.DefaultCrmConnection).FirstOrDefault(); Dte.StatusBar.Text = "Connecting to Dynamics 365"; if (defaultConnection == null) { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! Connection to Dynamics 365 failed !!! "; MessageBox.Show("Default Crm connection not found!", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (Config.SolutionPrefix == null) { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! Connection to Dynamics 365 failed !!! "; MessageBox.Show("PL.DynamicsCrm.DevKit.json config not found SolutionPrefix data", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var check = SharedGlobals.GetGlobal("CrmService", Dte); if (check == null) { try { var uri = new Uri(defaultConnection.Url); var clientCredentials = new ClientCredentials(); clientCredentials.UserName.UserName = defaultConnection.UserName; clientCredentials.UserName.Password = TryDecryptPassword(defaultConnection.Password); check = new OrganizationServiceProxy(uri, null, clientCredentials, null); SharedGlobals.SetGlobal("CrmService", check, Dte); } catch { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! Connection to Dynamics 365 fail !!! "; MessageBox.Show("Connection to Dynamics 365 fail!", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } var crmService = (OrganizationServiceProxy)SharedGlobals.GetGlobal("CrmService", Dte); Dte.StatusBar.Text = " !!! Connected Dynamics 365 !!! "; var fileName = activeDocument.FullName; var parts = fileName.Split("\\".ToCharArray()); var condition = string.Empty; for (var i = 1; i < parts.Length; i++) { var value = $"{Config.SolutionPrefix}/{parts[i]}/"; for (var j = i + 1; j < parts.Length; j++) { value += $"{parts[j]}/"; } if (value.EndsWith("/")) { value = value.TrimEnd("/".ToCharArray()); } if (value.StartsWith("/")) { value = value.Substring(1); } condition += $"<condition attribute='name' operator='ends-with' value='{value}'/>"; } var fetchXml = $@" <fetch> <entity name='webresource'> <attribute name='name' /> <filter type='or'> {condition} </filter> </entity> </fetch>"; var rows = crmService.RetrieveMultiple(new FetchExpression(fetchXml)); if (rows.Entities.Count == 0) { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! WebResource not found !!! "; MessageBox.Show("WebResource not found!", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } var webResourceId = rows.Entities[0].Id; try { var emRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true } }; var requests = new OrganizationRequestCollection(); var publishXml = "<importexportxml><webresources>"; var webResource = new Entity("webresource") { Id = webResourceId }; var content = File.ReadAllText(fileName); webResource["content"] = EncodeString(content); var request = new UpdateRequest { Target = webResource }; requests.Add(request); publishXml += "<webresource>{" + webResource.Id + "}</webresource>"; publishXml += "</webresources></importexportxml>"; var pubRequest = new PublishXmlRequest { ParameterXml = publishXml }; requests.Add(pubRequest); emRequest.Requests = requests; Dte.StatusBar.Text = "Updating & publishing WebResource ... "; var emResponse = (ExecuteMultipleResponse)crmService.Execute(emRequest); var wasError = false; foreach (var responseItem in emResponse.Responses) { if (responseItem.Fault == null) { continue; } wasError = true; } if (wasError) { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! Deploy WebResource failed !!! "; MessageBox.Show("Deploy WebResource failed.", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } else { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! Deploy WebResource succeeded !!! "; return; } } catch (FaultException <OrganizationServiceFault> ) { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! Deploy WebResource failed !!! "; MessageBox.Show("Deploy WebResource failed.", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } catch { Dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); Dte.StatusBar.Text = " !!! Deploy WebResource failed !!! "; MessageBox.Show("Deploy WebResource failed.", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } }
private void MenuItemCallback(object sender, EventArgs e) { var dte = (EnvDTE.DTE) this.ServiceProvider.GetService(typeof(EnvDTE.DTE)); dte.StatusBar.Animate(true, vsStatusAnimation.vsStatusAnimationDeploy); var activeDocument = dte.ActiveDocument; var solutionFullName = dte.Solution.FullName; var fInfo = new FileInfo(solutionFullName); var devKitCrmConfigFile = $"{fInfo.DirectoryName}\\PL.DynamicsCrm.DevKit.json"; dte.StatusBar.Text = "Read PL.DynamicsCrm.DevKit.json config"; var config = DevKitCrmConfigHelper.GetDevKitCrmConfig(dte); var defaultConnection = config.CrmConnections.Where(conn => conn.Name == config.DefaultCrmConnection).FirstOrDefault(); if (defaultConnection == null) { ShowError("Default Crm connection not found!"); goto CLEAR_STATUS; } if (string.IsNullOrEmpty(config.SolutionPrefix)) { ShowError("PL.DynamicsCrm.DevKit.json config not found SolutionPrefix data"); goto CLEAR_STATUS; } dte.StatusBar.Text = "Connecting ..."; var check = SharedGlobals.GetGlobal("CrmService", dte); if (check == null) { try { var uri = new Uri(defaultConnection.Url); var clientCredentials = new ClientCredentials(); clientCredentials.UserName.UserName = defaultConnection.UserName; clientCredentials.UserName.Password = defaultConnection.Password; check = new OrganizationServiceProxy(uri, null, clientCredentials, null); SharedGlobals.SetGlobal("CrmService", check, dte); } catch { ShowError("Connecting Fail!"); goto CLEAR_STATUS; } } var crmService = (OrganizationServiceProxy)SharedGlobals.GetGlobal("CrmService", dte); dte.StatusBar.Text = "Connected ..."; var fileName = activeDocument.FullName; var parts = fileName.Split("\\".ToCharArray()); var condition = string.Empty; for (var i = 1; i < parts.Length; i++) { var value = $"{config.SolutionPrefix}/{parts[i]}/"; for (var j = i + 1; j < parts.Length; j++) { value += $"{parts[j]}/"; } if (value.EndsWith("/")) { value = value.TrimEnd("/".ToCharArray()); } condition += $"<condition attribute='name' operator='ends-with' value='{value}'/>"; } var fetchXml = $@" <fetch> <entity name='webresource'> <attribute name='name' /> <filter type='or'> {condition} </filter> </entity> </fetch>"; var rows = crmService.RetrieveMultiple(new FetchExpression(fetchXml)); if (rows.Entities.Count == 0) { ShowError("Web resource not found!"); goto CLEAR_STATUS; } var webResourceId = rows.Entities[0].Id; try { ExecuteMultipleRequest emRequest = new ExecuteMultipleRequest { Requests = new OrganizationRequestCollection(), Settings = new ExecuteMultipleSettings { ContinueOnError = false, ReturnResponses = true } }; OrganizationRequestCollection requests = new OrganizationRequestCollection(); string publishXml = "<importexportxml><webresources>"; Entity webResource = new Entity("webresource") { Id = webResourceId }; string content = File.ReadAllText(fileName); webResource["content"] = EncodeString(content); UpdateRequest request = new UpdateRequest { Target = webResource }; requests.Add(request); publishXml += "<webresource>{" + webResource.Id + "}</webresource>"; publishXml += "</webresources></importexportxml>"; PublishXmlRequest pubRequest = new PublishXmlRequest { ParameterXml = publishXml }; requests.Add(pubRequest); emRequest.Requests = requests; dte.StatusBar.Text = "Updating & publishing web resource..."; ExecuteMultipleResponse emResponse = (ExecuteMultipleResponse)crmService.Execute(emRequest); bool wasError = false; foreach (var responseItem in emResponse.Responses) { if (responseItem.Fault == null) { continue; } wasError = true; } if (wasError) { ShowError("Error Updating And Publishing Web Resources To CRM. See the Output Window for additional details."); goto CLEAR_STATUS; } else { dte.StatusBar.Text = "Updated And Published Web Resource"; goto CLEAR_STATUS; } } catch (FaultException <OrganizationServiceFault> crmEx) { ShowError("Error Updating And Publishing Web Resource To CRM: " + crmEx.Message + Environment.NewLine + crmEx.StackTrace); goto CLEAR_STATUS; } catch (Exception ex) { ShowError("Error Updating And Publishing Web Resource To CRM: " + ex.Message + Environment.NewLine + ex.StackTrace); } CLEAR_STATUS: dte.StatusBar.Clear(); dte.StatusBar.Animate(false, vsStatusAnimation.vsStatusAnimationDeploy); }