MS CRM 2011 导出Ribbon的定义
原创地址:http://www.cnblogs.com/jfzhu/archive/2013/02/15/2912860.html
转载请注明出处
SDK中有一个Export Ribbon Definations的例子,源代码也可以在sdk\samplecode\cs\client\ribbon\exportribbonxml中找到。SDK中的例子使用了ServerConnection.Configuration类,这个类对EMEA的CRM Online不太好用,总是连接失败。或许对北美的可以使用。
另外SDK中的例子将系统中所有Entity的Ribbon定义全部导出,有一点慢。我在这将该程序简化,使用Microsoft.Xrm.Client.Services.OrganizationService类(参见MS CRM 2011 如何从外部连接CRM),并且将只导出指定的一个Entity Ribbon定义。
简化后的程序如下:
using System; using Microsoft.Xrm.Client.Services; using Microsoft.Xrm.Client; using Microsoft.Crm.Sdk.Messages; using System.ServiceModel; using System.Configuration; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using System.IO; using System.IO.Packaging; namespace ExportRibbon { public class ExportRibbon { #region Class Level Members private OrganizationService _orgService; #endregion Class Level Members //Folder name for exported ribbon xml files. public String exportFolder = "ExportedRibbonXml"; public String entityName = "aw_vooraankondiging"; public void Run(String connectionString, bool promptforDelete) { try { // Establish a connection to the organization web service using CrmConnection. Microsoft.Xrm.Client.CrmConnection connection = CrmConnection.Parse(connectionString); // Obtain an organization service proxy. // The using statement assures that the service proxy will be properly disposed. using (_orgService = new OrganizationService(connection)) { //Create export folder for ribbon xml files if not already exist. if (!Directory.Exists(exportFolder)) Directory.CreateDirectory(exportFolder); RetrieveEntityRibbonRequest entRibReq = new RetrieveEntityRibbonRequest() { RibbonLocationFilter = RibbonLocationFilters.All }; entRibReq.EntityName = entityName; RetrieveEntityRibbonResponse entRibResp = (RetrieveEntityRibbonResponse)_orgService.Execute(entRibReq); System.String entityRibbonPath = Path.GetFullPath(exportFolder + "\\" + entityName + "Ribbon.xml"); File.WriteAllBytes(entityRibbonPath, unzipRibbon(entRibResp.CompressedEntityXml)); //Write the path where the file has been saved. Console.WriteLine(entityRibbonPath); } } // Catch any service fault exceptions that Microsoft Dynamics CRM throws. catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>) { // You can handle an exception here or pass it back to the calling method. throw; } } #region Public Methods //<snippetExportRibbonXml2> /// <summary> /// A helper method that decompresses the the Ribbon data returned /// </summary> /// <param name="data">The compressed ribbon data</param> /// <returns></returns> public byte[] unzipRibbon(byte[] data) { System.IO.Packaging.ZipPackage package = null; MemoryStream memStream = null; memStream = new MemoryStream(); memStream.Write(data, 0, data.Length); package = (ZipPackage)ZipPackage.Open(memStream, FileMode.Open); ZipPackagePart part = (ZipPackagePart)package.GetPart(new Uri("/RibbonXml.xml", UriKind.Relative)); using (Stream strm = part.GetStream()) { long len = strm.Length; byte[] buff = new byte[len]; strm.Read(buff, 0, (int)len); return buff; } } #endregion Public Methods #region Private Methods /// <summary> /// Gets web service connection information from the app.config file. /// If there is more than one available, the user is prompted to select /// the desired connection configuration by name. /// </summary> /// <returns>A string containing web service connection configuration information.</returns> private static String GetServiceConfiguration() { var connection = ConfigurationManager.ConnectionStrings["CrmConnection"]; return connection.ConnectionString; } #endregion Private Methods #region Main method /// <summary> /// Standard Main() method used by most SDK samples. /// </summary> /// <param name="args"></param> static public void Main(string[] args) { try { // Obtain connection configuration information for the Microsoft Dynamics // CRM organization web service. String connectionString = GetServiceConfiguration(); if (connectionString != null) { ExportRibbon app = new ExportRibbon(); app.Run(connectionString, true); } } catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine("Timestamp: {0}", ex.Detail.Timestamp); Console.WriteLine("Code: {0}", ex.Detail.ErrorCode); Console.WriteLine("Message: {0}", ex.Detail.Message); Console.WriteLine("Trace: {0}", ex.Detail.TraceText); Console.WriteLine("Inner Fault: {0}", null == ex.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault"); } catch (System.TimeoutException ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine("Message: {0}", ex.Message); Console.WriteLine("Stack Trace: {0}", ex.StackTrace); Console.WriteLine("Inner Fault: {0}", null == ex.InnerException.Message ? "Has Inner Fault" : "No Inner Fault"); } catch (System.Exception ex) { Console.WriteLine("The application terminated with an error."); Console.WriteLine(ex.Message); // Display the details of the inner exception. if (ex.InnerException != null) { Console.WriteLine(ex.InnerException.Message); FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> fe = ex.InnerException as FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>; if (fe != null) { Console.WriteLine("Timestamp: {0}", fe.Detail.Timestamp); Console.WriteLine("Code: {0}", fe.Detail.ErrorCode); Console.WriteLine("Message: {0}", fe.Detail.Message); Console.WriteLine("Trace: {0}", fe.Detail.TraceText); Console.WriteLine("Inner Fault: {0}", null == fe.Detail.InnerFault ? "Has Inner Fault" : "No Inner Fault"); } } } // Additional exceptions to catch: SecurityTokenValidationException, ExpiredSecurityTokenException, // SecurityAccessDeniedException, MessageSecurityException, and SecurityNegotiationException. finally { Console.WriteLine("Press <Enter> to exit."); Console.ReadLine(); } } #endregion Main method } }
导出Ribbon定义,要使用到RetrieveEntityRibbonRequest。另外RetrieveEntityRibbonResponse.CompressedEntityXml保存的是压缩(zip)数据,需要使用System.IO.Packaging.ZipPackage将数据解压缩。