如何通过Package Deployer以更新而非升级方式部署CRM解决方案
使用Package Deployer以更新方式替代升级流程的可行方案
核心思路
Package Deployer默认会触发升级预备(Upgrade Preflight)和升级(Upgrade)流程,但可通过自定义代码扩展跳过默认逻辑,改用**解决方案更新(Update)**操作完成部署,适配多批量解决方案的场景。
具体实现步骤
1. 自定义Deployment类重写部署逻辑
创建或修改Package Deployer项目中的自定义Deployment类,继承DeploymentBase并重写Run方法,直接执行解决方案更新:
public class CustomBatchDeployment : DeploymentBase { public override void Run() { var crmService = CrmServiceClient; // 定义待部署的解决方案列表(按依赖顺序排序) var targetSolutions = new List<string> { "CoreSolution", "FeatureSolutionA", "FeatureSolutionB" }; foreach (var solUniqueName in targetSolutions) { // 读取本地解决方案包字节流 var solPackagePath = Path.Combine(Directory.GetCurrentDirectory(), $"Solutions/{solUniqueName}.zip"); var solPackageBytes = File.ReadAllBytes(solPackagePath); // 检查目标环境是否已存在该解决方案 var existingSolQuery = new QueryExpression("solution") { ColumnSet = new ColumnSet("solutionid"), Criteria = new FilterExpression { Conditions = { new ConditionExpression("uniquename", ConditionOperator.Equal, solUniqueName) } } }; var existingSol = crmService.RetrieveMultiple(existingSolQuery).Entities.FirstOrDefault(); if (existingSol != null) { // 执行解决方案更新操作 var updateRequest = new UpdateSolutionRequest { SolutionPackage = solPackageBytes, OverwriteUnmanagedCustomizations = true, PublishWorkflows = true }; crmService.Execute(updateRequest); } else { // 若不存在则执行首次导入(按需启用) var importRequest = new ImportSolutionRequest { SolutionPackage = solPackageBytes, OverwriteUnmanagedCustomizations = true }; crmService.Execute(importRequest); } } } }
2. 配置Package Deployer使用自定义类
修改项目的PackageDeployer.exe.config,指定自定义Deployment类的程序集信息:
<appSettings> <add key="DeploymentTypeName" value="YourProjectNamespace.CustomBatchDeployment, YourProjectAssembly" /> </appSettings>
3. 关键注意事项
- 版本约束:更新操作要求传入的解决方案包版本号必须高于目标环境中已存在的版本,否则会执行失败。
- 依赖顺序:多解决方案部署时,需按依赖层级排序(基础解决方案优先,依赖它的解决方案后置)。
- 权限要求:执行部署的CRM账号需具备导入解决方案权限(系统管理员/系统定制员角色默认拥有)。
- 测试验证:生产部署前需在测试环境验证更新逻辑,确认自定义项覆盖、工作流发布等行为符合预期。
轻量替代方案:PowerShell脚本配合SDK
若不想自定义Package Deployer项目,可直接用PowerShell调用Dynamics 365 SDK完成批量更新:
# 初始化CRM连接 $crmConn = Get-CrmConnection -ConnectionString "AuthType=OAuth;Url=https://yourorg.crm.dynamics.com;Username=admin@yourorg.com;Password=yourpass;AppId=yourAppId;RedirectUri=app://58145B91-0C36-4500-8554-080854F2AC97" # 待部署解决方案列表 $solutionList = @("CoreSolution.zip", "FeatureSolutionA.zip", "FeatureSolutionB.zip") foreach ($solFile in $solutionList) { $solPath = Join-Path $PSScriptRoot "Solutions/$solFile" $solBytes = [System.IO.File]::ReadAllBytes($solPath) $solUniqueName = $solFile -replace ".zip", "" # 检查解决方案是否存在 $existingSol = Get-CrmRecord -conn $crmConn -EntityLogicalName "solution" -FilterAttribute "uniquename" -FilterOperator "eq" -FilterValue $solUniqueName if ($existingSol) { # 执行更新 $updateReq = New-Object Microsoft.Crm.Sdk.Messages.UpdateSolutionRequest $updateReq.SolutionPackage = $solBytes $updateReq.OverwriteUnmanagedCustomizations = $true Invoke-CrmRequest -conn $crmConn -Request $updateReq } else { # 首次导入 $importReq = New-Object Microsoft.Crm.Sdk.Messages.ImportSolutionRequest $importReq.SolutionPackage = $solBytes $importReq.OverwriteUnmanagedCustomizations = $true Invoke-CrmRequest -conn $crmConn -Request $importReq } }
内容的提问来源于stack exchange,提问作者karthik
相关产品推荐
相关产品推荐

