关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复258或者20170627可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me 。
在我们做项目的过程中,一般会涉及到多个Dynamics 365环境,一般包括一个开发环境、一个SIT环境,一个UAT环境和一个生产环境,经常涉及到解决方案从开发环境迁移到SIT环境,从开发环境迁移到UAT环境,从开发环境迁移到生产环境等等。一般手工操作是先更改解决方案版本,保存后发布解决方案,再导出解决方案,再导入解决方案到目标环境。一个解决方案还好,解决方案多了麻烦,容易手误或者漏操作,可以写个程序来做这些繁杂的事情吗?Follow me。
直接上代码,代码中有注释说明,注意我这里是导入到同一个环境,你使用我的代码的时候要改动到其他CRM环境,我这里的示例是迁移一个解决方案包,项目中很一般是迁移多个。我这里导出解决方案是放在电脑的下载文件夹中:
 public static IServiceManagement<IOrganizationService> sm;
static void Main(string[] args)
{
try
{
sm = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri("https://demo.luoyong.me/XRMServices/2011/Organization.svc"));
ClientCredentials credentials = new ClientCredentials();
credentials.UserName.UserName = "crmadmin@luoyong.me";
credentials.UserName.Password = "Pass";
using (var _serviceProxy = new OrganizationServiceProxy(sm, credentials))
{
_serviceProxy.Timeout = new TimeSpan(, , );//默认为两分钟,这里设置为20分钟
_serviceProxy.EnableProxyTypes();
Console.WriteLine("Dynamics 365中可见的解决方案列表:" + DateTime.Now.ToLongTimeString());
QueryExpression qe = new QueryExpression("solution");
qe.ColumnSet = new ColumnSet("uniquename", "friendlyname", "version", "solutionpackageversion", "ismanaged");
qe.Criteria.AddCondition("isvisible", ConditionOperator.Equal, true);
qe.AddOrder("uniquename", OrderType.Ascending);
var solutions = _serviceProxy.RetrieveMultiple(qe);
foreach(var item in solutions.Entities)
{
Console.WriteLine(string.Format("uniquename={0};friendlyname={1};version={2};solutionpackageversion={3};ismanaged={4}",
item.GetAttributeValue<string>("uniquename"),
item.GetAttributeValue<string>("friendlyname"),
item.GetAttributeValue<string>("version"),
item.GetAttributeValue<string>("solutionpackageversion"),
item.GetAttributeValue<bool>("ismanaged")));
Console.WriteLine(new String('-',));
}
Console.WriteLine("开始查询要导出的解决方案并更改版本信息" + DateTime.Now.ToLongTimeString());
var toExpSolutionUniqueName = "DemoSolution";
qe = new QueryExpression("solution");
qe.ColumnSet = new ColumnSet("version");
qe.Criteria.AddCondition("uniquename", ConditionOperator.Equal, toExpSolutionUniqueName);
qe.TopCount = ;
solutions = _serviceProxy.RetrieveMultiple(qe);
if(solutions.Entities.Count >= )
{
var solution = solutions.Entities[];
solution["version"] = string.Format("8.2.{0}.{1}", DateTime.Now.Month, DateTime.Now.Day);
_serviceProxy.Update(solution);
}
Console.WriteLine("开始发布所有自定义项" + DateTime.Now.ToLongTimeString());
PublishAllXmlRequest pubReq = new PublishAllXmlRequest();
_serviceProxy.Execute(pubReq);
Console.WriteLine("开始导出" + DateTime.Now.ToLongTimeString());
ExportSolutionRequest exportSolutionRequest = new ExportSolutionRequest();
exportSolutionRequest.Managed = false;
exportSolutionRequest.SolutionName = toExpSolutionUniqueName;
exportSolutionRequest.TargetVersion = "8.2";//Dynamics 365导出时候可以选择目标环境用什么版本
ExportSolutionResponse exportSolutionResponse = (ExportSolutionResponse)_serviceProxy.Execute(exportSolutionRequest);
byte[] exportXml = exportSolutionResponse.ExportSolutionFile;
string filename = string.Format("{0}_{1}.zip", toExpSolutionUniqueName, solutions.Entities[].GetAttributeValue<string>("version").Replace('.','_'));
File.WriteAllBytes(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments).Replace("Documents", "Downloads") + "\\" + filename, exportXml);
Console.WriteLine("开始导入" + DateTime.Now.ToLongTimeString());
byte[] fileBytes = File.ReadAllBytes(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments).Replace("Documents", "Downloads") + "\\" + filename);
ImportSolutionRequest impReq = new ImportSolutionRequest()
{
CustomizationFile = fileBytes,
PublishWorkflows = true
};
_serviceProxy.Execute(impReq);
Console.WriteLine("开始发布所有自定义项" + DateTime.Now.ToLongTimeString());
pubReq = new PublishAllXmlRequest();
_serviceProxy.Execute(pubReq);
Console.WriteLine("程序运行成功!");
Console.ReadKey();
}
}
catch (FaultException ex)
{
Console.WriteLine("程序出现异常:ex.Message=" + ex.Message);
Console.ReadKey();
}
}

展示效果如下图:展示效果如下图:

可能你会对PublishAllXmlRequest这个消息产生疑问,这个是发布哪个解决方案的所有自定义项,实验证明应该是发布所有解决方案的所有自定义项。在导出解决方案之前请执行下这个消息确保所有的自定义项都发布了,在导入解决方案之后也执行下这个消息导入后的解决方案生效。
Dynamics 365的一个新增功能是导出解决方案时候可以指定解决方案的版本,可以选择 8.0, 8.1或者8.2,我这个导出程序使用了默认的 8.2.
值得说明的是高级查找并不能查询解决方案这个实体,所以我这里用的是QueryExpression这种查询方法,而不是使用FetchXml来查询。当然两者是可以互相转换的。查看这个实体的元数据还是使用Dynamics 365提供的Metadata Browser这个解决方案吧。
 

为Dynamics 365写一个简单程序实现解决方案一键迁移的更多相关文章

  1. 写一个ajax程序就是如此简单

    写一个ajax程序就是如此简单 ajax介绍: 1:AJAX全称为Asynchronous JavaScript and XML(异步JavaScript和XML),指一种创建交互式网页应用的网页开发 ...

  2. (原创)如何使用boost.asio写一个简单的通信程序(一)

    boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...

  3. (原创)如何使用boost.asio写一个简单的通信程序(二)

    先说下上一篇文章中提到的保持io_service::run不退出的简单办法.因为只要异步事件队列中有事件,io_service::run就会一直阻塞不退出,所以只要保证异步事件队列中一直有事件就行了, ...

  4. Dynamics 365中的应用程序介绍

    本人微信和易信公众号:微软动态CRM专家罗勇 ,回复275或者20180630可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...

  5. 如何写一个简单的http服务器

    最近几天用C++写了一个简单的HTTP服务器,作为学习网络编程和Linux环境编程的练手项目,这篇文章记录我在写一个HTTP服务器过程中遇到的问题和学习到的知识. 服务器的源代码放在Github. H ...

  6. 如何写一个简单的shell

    如何写一个简单的shell 看完<UNIX环境高级编程>后我就一直想写一个简单的shell来作为练习,因为有事断断续续的写了好几个月,如今写了差不多来总结一下. 源代码放在了Github: ...

  7. 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

    这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...

  8. 学了C语言,如何利用CURL写一个下载程序?—用nmake编译CURL并安装

    在这一系列的前一篇文章学了C语言,如何为下载狂人写一个磁盘剩余容量监控程序?中,我们为下载狂人写了一个程序来监视磁盘的剩余容量,防止下载的东西撑爆了硬盘.可是,这两天,他又抱怨他的下载程序不好用,让我 ...

  9. 一步一步写一个简单通用的makefile(三)

    上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...

随机推荐

  1. zabbix监控redis

    导入监控模板 点击[configuration]-->[templates]-->[import],导入xml监控模板. 配置客户端key 在被监控的主机上,新建/etc/zabbix/z ...

  2. DelayQueue使用

    假设现有如下的使用场景: a) 关闭空闲连接.服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之. b) 缓存.缓存中的对象,超过了空闲时间,需要从缓存中移出. c) 任务超时处理.在网络协议滑 ...

  3. WPF 简易的跑马灯效果

    最近项目上要用到跑马灯的效果,和网上不太相同的是,网上大部分都是连续的,而我们要求的是不连续的. 也就是是,界面上就展示4项(展示项数可变),如果有7项要展示的话,则不断的在4个空格里左跳,当然,衔接 ...

  4. 以太坊RLP用法-go-ethereum学习

    RLP (递归长度前缀)提供了一种适用于任意二进制数据数组的编码,RLP已经成为以太坊中对对象进行序列化的主要编码方式.RLP的唯一目标就是解决结构体的编码问题:对原子数据类型(比如,字符串,整数型, ...

  5. Yii2.0中场景的使用小记

    熟悉Yii框架的人都知道,灵活的使用场景可以达到事半功倍的效果! 比如普通的数据的新增.修改,新增需要验证其中两个字段,而修改只需要验证其中一个字段:还有种情况,也是我们现在用到的,同一张表(同一个m ...

  6. 使用VideoView开发视频总结

    一.VideoView及其相关组件总结 在Android中,播放视频有2种方式,第一种方式是使用MediaPlayer结合SurfaceView来播放,通过MediaPlayer来控制视频的播放.暂停 ...

  7. python之 centos6.7下 python 3.5.2、Django-1.9 安装

    在linux6.5中已经自带了python 2 .python 2.6 ,并且yum程序使用的就是自带的python,所以系统自带的python不要随意卸载否则可能导致yum用不了. 测试环境:cen ...

  8. Vue.js 运行环境搭建详解(基于windows的手把手安装教学)及vue、node基础知识普及

    Vue.js 是一套构建用户界面的渐进式框架.他自身不是一个全能框架——只聚焦于视图层.因此它非常容易学习,非常容易与其它库或已有项目整合.在与相关工具和支持库一起使用时,Vue.js 也能完美地驱动 ...

  9. 初识Tensorboard

    1.什么是Tensorboard? PPT设计原则中有这样一条,叫"文不如表,表不如图",可见图表在表达中更为直观.明确.程序设计中也是一样,我们经常用图表来描述程序的结构和流程, ...

  10. 给Linux系统/网络管理员准备的Nmap命令的29个实用范例

    我将用两个不同的部分来涵盖大部分NMAP的使用方法,这是nmap关键的第一部分.在下面的设置中,我使用两台已关闭防火墙的服务器来测试Nmap命令的工作情况. 192.168.0.100 – serve ...