SolutionPackager 是一种工具,可以反转将Microsoft Dataverse压缩解决方案文件分解为多个 XML 文件和其他文件。 然后,您可以使用源代码管理系统轻松地管理这些文件。 以下部分介绍如何运行该工具,以及如何将该工具用于托管和非托管解决方案。
Important
SolutionPackager 工具不再是解包和打包解决方案的推荐方法。 SolutionPackager 工具的功能合并到 Power Platform CLI 中。 该pac solution命令包含许多谓词,包括unpack,packclone并sync包含 SolutionPackager 工具的相同基础功能。
在何处查找 SolutionPackager 工具
SolutionPackager 工具作为 Microsoft.CrmSdk.CoreTools NuGet 包的一部分分发。 要安装此程序,请执行以下步骤。
- 下载 NuGet 包。
- 将包文件扩展名从 .nupkg 重命名为 .zip。
- 提取压缩 (zip) 文件的内容。
在 <extracted-folder-name>/contents/bin/coretools 文件夹中找到 SolutionPackager.exe 可执行文件。 从 coretools 文件夹运行程序,或将该文件夹添加到您的 PATH 中。
SolutionPackager 命令行参数
SolutionPackager 是一个命令行工具,可以使用下表中标识的参数进行调用。
| 论点 | Description |
|---|---|
| /动作:{提取|打包} | 必填。 执行操作。 该操作可以是将解决方案 .zip 文件提取到文件夹,也可以将文件夹打包为 .zip 文件。 |
| /zipfile: <文件路径> | 必填。 解决方案 .zip 文件的路径和名称。 当解压缩时,文件必须存在并且能够读取。 打包时,文件将被替换。 |
| /folder: <文件夹路径> | 必填。 文件夹路径。 提取时,将创建此文件夹并填充组件文件。 打包时,此文件夹必须已经存在,并且包含以前提取的组件文件。 |
| /packagetype: {非托管|托管|两者皆可} | 可选。 要处理的包的类型。 默认值为 Unmanaged。 在大多数情况下,可以省略此参数,因为可以从 .zip 文件或组件文件内部读取包类型。 当解压缩并同时指定这两个属性时,托管和非托管解决方案 .zip 文件必须在同一个文件夹存在和处理。 压缩并同时指定两个文件时,托管和非托管解决方案 .zip 文件会从一个文件夹产生。 有关更多信息,请参见本文后面的使用托管和非托管解决方案一节。 |
| /allowWrite:{Yes|No} | 可选。 默认值为“是”。 此参数仅在提取期间使用。 指定 /allowWrite:No 时,该工具将执行所有作,但会阻止写入或删除任何文件。 提取操作可以在不重写或删除任何现有文件的情况下进行安全评估。 |
| /allowDelete:{Yes|No|Prompt} | 可选。 默认值为 Prompt。 此参数仅在提取期间使用。 当指定 /allowDelete:Yes 时,由 /folder 参数指定的文件夹中存在的任何不需要的文件都将被自动删除。 当指定 /allowDelete:No 时,删除不会发生。 指定 /allowDelete:Prompt 后,系统会通过控制台提示用户允许或拒绝所有删除作。 如果指定 /allowWrite:No,则不会发生删除操作,即使 /allowDelete:Yes 同样被指定。 |
| /clobber | 可选。 此参数仅在提取期间使用。 指定 /clobber 时,将覆盖或删除设置了 read-only 属性的文件。 如果未指定,则不会覆盖或删除具有只读属性的文件。 |
| /errorlevel: {Off|错误 |警告 |信息 |详细} | 可选。 默认值为“Info”。 此参数指示要输出的日志记录信息的级别。 |
| /map: <文件路径> | 可选。 包含文件映射指令的 .xml 文件的路径和名称。 在提取期间使用时,通常从 /folder 参数指定文件夹内部读取的文件会从映射文件指定的其他位置读取。 在包操作期间,不会写入与指令匹配的文件。 |
| /nologo | 可选。 在运行时禁止显示横幅。 |
| /log: <文件路径> | 可选。 日志文件的路径和名称。 如果该文件已存在,则会将新的日志记录信息附加到该文件中。 |
| @ <文件路径> | 可选。 包含工具的命令行参数的文件的路径和名称。 |
| /sourceLoc: <字符串> | 可选。 此参数会生成模板资源文件,并且仅在 extract 时有效。 可能的值为 auto或您要导出的语言的LCID/ISO代码。 当使用此参数时,提取给定区域设置的字符串资源作为 neutral .resx 文件。 如果指定 auto 开关,或只是长或短格式的开关,则会使用基础区域设置或解决方案。 您可以使用命令的简称:/src。 |
| /本地化 | 可选。 将所有字符串资源提取或合并到 .resx 文件中。 您可以使用命令的简称:/loc。 本地化选项支持 .resx 文件的共享组件。 详细信息:使用 RESX Web 资源 |
| /解决方案名称: <name> | 可选。 源文件夹包含多个解决方案 solutions/*/solution.yml时要打包或提取的解决方案的唯一名称。 检测到多个解决方案时需要这样做。 仅适用于 YAML 源代码管理格式。 可以使用命令的短格式:/sn。 |
| /remapPluginTypeNames | 可选。 在指定的情况下,插件的完全限定类型名称将根据解决方案中包含的程序集进行重新映射。 默认情况下,以 YAML 源代码管理格式启用。 可以使用命令的简短形式:/fp。 |
源代码管理文件格式
SolutionPackager 在提取和打包解决方案时支持两个文件夹布局。
XML 格式(旧版)
原始格式。 解决方案元数据存储在Other\Solution.xml和Other\Customizations.xml中,并将所有组件文件提取到与这些文件一起的平面文件夹层次结构中。 在提取 .zip 文件时,此格式是默认格式,无需更多配置。
YAML 源代码管理格式
此格式与 Dataverse Git 集成一起引入,将解决方案元数据存储为跨结构化文件夹层次结构分布的 YAML 文件。 这是在 Power Apps 中使用本机 Git 集成提交解决方案时编写的格式。
与 XML 格式的优缺点
- 在源代码管理中生成更加简洁、易读的逐组件差异
- 支持单个存储库文件夹中的多个解决方案
- 画布应用
.msapp文件和现代工作流仅支持此格式 - 默认启用插件类型名称重新映射
所需的文件夹结构
<rootFolder>/
├── solutions/
│ └── <SolutionUniqueName>/
│ ├── solution.yml (solution metadata)
│ ├── solutioncomponents.yml (paths to all component files)
│ ├── rootcomponents.yml (root-level components)
│ └── missingdependencies.yml (dependency info)
├── publishers/
│ └── <PublisherUniqueName>/
│ └── publisher.yml (publisher definition)
├── entities/ (entity components, if present)
├── workflows/ (classic workflows, if present)
├── modernflows/ (Power Automate cloud flows, if present)
├── canvasapps/ (canvas app .msapp files, if present)
└── [other component folders]/
Important
YAML 格式通过检测包含solutions/文件的*solution.yml子文件夹的存在而自动识别。
如果 YAML 清单文件(如 solution.yml、solutioncomponents.yml 等)放置在文件夹的根目录,而不是位于 solutions/<SolutionUniqueName>/ 下,该工具无法检测出 YAML 格式。 该工具回退到 XML 路径,并报告一种有关缺少Customizations.xml的误导性错误。 有关如何解决此问题的信息,请参阅 故障排除 。
详细信息: 解决方案 YAML 源代码管理格式参考
设置自动检测规则的格式
| 条件 | 使用的格式 |
|---|---|
solutions/*/solution.yml 找到 — 恰好是一个解决方案 |
YAML 格式,其中从文件夹中推断解决方案名称 |
solutions/*/solution.yml 已找到 —— 可用多种解决方案 |
YAML 格式,/SolutionName 参数是必需的 |
不存在 solutions/ 子目录 |
XML 格式(旧版) |
打包 YAML 格式文件夹
以下命令打包 YAML 格式文件夹。
SolutionPackager.exe /action:Pack /zipfile:MySolution.zip /folder:C:\repos\myrepo
从多解决方案文件夹打包
以下命令将指定解决方案打包到多解决方案文件夹中。
SolutionPackager.exe /action:Pack /zipfile:SolutionA.zip /folder:C:\repos\myrepo /SolutionName:SolutionA
使用 /map 命令参数
以下讨论详细介绍了 SolutionPackager 工具的 /map 参数的使用。
在自动构建系统中构建的文件,如 .xap Silverlight 文件和插件组件,通常不会检查源控制。 在与 SolutionPackager 工具不直接兼容的位置上,Web 资源也许已经存在于源控件中。 通过包含 /map 参数,可以指示 SolutionPackager 工具从备用位置读取和打包此类文件,而不是像通常那样从 Extract 文件夹内部读取和打包。 /map 参数必须指定包含映射指令的 XML 文件的名称和路径。 这些指令指示 SolutionPackager 通过文件的名称和路径来匹配文件,并指示查找匹配文件的备用位置。 以下信息同样适用于所有指令。
可以列出多个指令,包括匹配相同文件的指令。 文件中先列出的指令优先于后来列出的指令。
如果文件与任何指令匹配,则必须在至少一个备用位置找到该文件。 如果未找到其他匹配文件,SolutionPackager 将发出错误。
文件夹和文件路径可以是绝对路径,也可以是相对路径。 相对路径始终从由 /folder 参数指定的文件夹计算。
环境变量可以使用 %variable% 语法指定。
文件夹通配符“**”可用于表示“在任何子文件夹中”。 它只能用作路径的最后一部分,例如:“c:\folderA\**”。
文件名通配符只能以“*.ext”或“*.*”形式使用。 不支持其他模式。
这里描述了三种类型的指令映射,并提供了一个展示如何使用它们的示例。
文件夹映射
以下信息提供有关文件夹映射的详细信息。
Xml 格式
<Folder map="folderA" to="folderB" />
说明
与“folderA”匹配的文件路径将切换到“folderB”。
每一个子文件夹的层次结构必须准确匹配。
不支持文件夹通配符。
不能指定任何文件名。
Examples
<Folder map="folderA" to="folderB" /> <Folder map="folderA\folderB" to="..\..\folderC\" /> <Folder map="WebResources\subFolder" to="%base%\WebResources" />
文件到文件映射
以下信息提供有关文件到文件映射的更多详细信息。
Xml 格式
<FileToFile map="path\filename.ext" to="path\filename.ext" />
说明
匹配 map 参数的任何文件都从 to 参数中指定的名称和路径中读取。
对于 map 参数:
必须指定文件名。 路径是可选的。 如果未指定路径,则可以匹配任何文件夹中的文件。
不支持文件名通配符。
支持文件夹通配符。
对于
to参数:必须指定文件名和路径。
文件名可能与参数中
map的名称不同。不支持文件名通配符。
支持文件夹通配符。
Examples
<FileToFile map="assembly.dll" to="c:\path\folder\assembly.dll" />
<FileToFile map="PluginAssemblies\**\this.dll" to="..\..\Plugins\**\that.dll" />
<FileToFile map="Webresrouces\ardvark.jpg" to="%SRCBASE%\CrmPackage\WebResources\JPG format\aardvark.jpg" />
<FileToFile
map="pluginpackages\cr886_PluginPackageTest\package\cr886_PluginPackageTest.nupkg"
to="myplg\bin\Debug\myplg.1.0.0.nupkg" />
在上面的 NuGet 包示例中,如果文件已经存在于指定位置,cr886_PluginPackageTest.nupkg 不会被覆盖。
文件到路径映射
下面提供了有关文件到路径映射的详细信息。
Xml 格式
<FileToPath map="path\filename.ext" to="path" />
说明
与参数匹配 map 的任何文件都将从参数中指定的 to 路径中读取。
对于 map 参数:
必须指定文件名。 路径是可选的。 如果未指定路径,则可以匹配任何文件夹中的文件。
支持文件名通配符。
支持文件夹通配符。
对于 to 参数:
必须指定路径。
支持文件夹通配符。
不得指定文件名。
Examples
<FileToPath map="assembly.dll" to="c:\path\folder" />
<FileToPath map="PluginAssemblies\**\this.dll" to="..\..\Plugins\bin\**" />
<FileToPath map="*.jpg" to="%SRCBASE%\CrmPackage\WebResources\JPG format\" />
<FileToPath map="*.*" to="..\..\%ARCH%\%TYPE%\drop" />
示例映射
下面的 XML 代码示例显示了一个完整的映射文件,该文件使 SolutionPackager 工具能够从名为 CRMDevTookitSample 的 Developer Toolkit 项目中读取任何 Web 资源和两个默认生成的程序集。
<?xml version="1.0" encoding="utf-8"?>
<Mapping>
<!-- Match specific named files to an alternate folder -->
<FileToFile map="CRMDevTookitSamplePlugins.dll" to="..\..\Plugins\bin\**\CRMDevTookitSample.plugins.dll" />
<FileToFile map="CRMDevTookitSampleWorkflow.dll" to="..\..\Workflow\bin\**\CRMDevTookitSample.Workflow.dll" />
<!-- Match any file in and under WebResources to an alternate set of subfolders -->
<FileToPath map="WebResources\*.*" to="..\..\CrmPackage\WebResources\**" />
<FileToPath map="WebResources\**\*.*" to="..\..\CrmPackage\WebResources\**" />
</Mapping>
托管和非托管解决方案
Dataverse 压缩解决方案 (.zip) 文件可以按照此处所示的两种类型之一导出。
托管解决方案
准备导入到组织中的完整解决方案。 导入后,无法添加或删除组件,尽管可以选择允许进一步自定义。 建议在解决方案开发完成时执行此作。
非托管解决方案
一个开放式解决方案,对可以添加、删除或修改的内容没有限制。 在开发解决方案时,建议这样做。
压缩解决方案文件的格式将根据其类型(托管或非托管)而有所不同。 SolutionPackager 可以处理任一类型的压缩解决方案文件。 但是,该工具无法将一种类型转换为另一种类型。 唯一可以将解决方案文件转换为不同类型的方式(例如从非托管转换为托管)是将非托管解决方案 .zip 文件导入到 Dataverse 服务器,然后将解决方案导出为托管解决方案。
通过 /PackageType:Both 参数,SolutionPackager 能够将托管和非托管的解决方案 .zip 文件作为组合处理。 要执行此操作,必须将解决方案分别按每种类型导出两次,并按如下方式命名 .zip 文件。
非托管 .zip 文件:AnyName.zip
托管 .zip 文件:AnyName_managed.zip
该工具将假定托管 zip 文件与非托管文件位于同一文件夹中,并将这两个文件提取到一个文件夹中,从而保留托管和非托管组件存在差异。
在解决方案作为托管和非托管文件被提取之后,可以从同一文件夹压缩两个文件或分别压缩每个类型,使用 /PackageType 参数指定创建哪个类型。 当两个文件同时被指定时,可以使用上述命名惯例生产两个 .zip 文件。 如果在从双重托管和非托管文件夹打包时缺少 /PackageType 参数,则默认生成单个非托管 .zip 文件。
故障排除
使用Visual Studio编辑资源文件时显示的消息
如果使用 Visual Studio 编辑解决方案打包程序创建的资源文件,则重新打包时可能会收到类似这样的一条消息:"Failed to determine version id of the resource file <filename>.resx the resource file must be exported from the solutionpackager.exe tool in order to be used as part of the pack process." 这种情况发生是因为 Visual Studio 将资源文件的元数据标签替换为数据标签。
解决方法
在您喜欢的文本编辑器中打开资源文件,然后找到并更新以下标签:
<data name="Source LCID" xml:space="preserve"> <data name="Source file" xml:space="preserve"> <data name="Source package type" xml:space="preserve"> <data name="SolutionPackager Version" mimetype="application/x-microsoft.net.object.binary.base64">将节点名称从
<data>更改为<metadata>。例如,此字符串:
<data name="Source LCID" xml:space="preserve"> <value>1033</value> </data>更改为:
<metadata name="Source LCID" xml:space="preserve"> <value>1033</value> </metadata>这允许解决方案打包程序读取和导入资源文件。 仅在使用 Visual Studio 资源编辑器时观察到此问题。
错误:“找不到具有 YAML 文件夹的必需文件 ...\Other\Customizations.xml”
针对包含 YAML 文件的文件夹运行 SolutionPackager(或pac solution pack)时,会出现此错误,因为这些文件位于文件夹的根目录,而没有存放于所需的solution.yml子文件夹中。
原因: 该工具通过查找 solutions/ 包含 *solution.yml 文件的子文件夹来检测 YAML 源代码管理格式。 当该目录不存在时,该工具会以无提示方式回退到 XML(旧版)格式,并预期 Other\Customizations.xml。 生成的错误消息引用 XML 文件,但不提及 YAML,这具有误导性。
修复: 重新组织文件夹,使 YAML 清单文件位于正确的路径下:
<rootFolder>/
solutions/<YourSolutionUniqueName>/ ← move solution.yml here
solution.yml
solutioncomponents.yml
rootcomponents.yml
missingdependencies.yml
publishers/<YourPublisherUniqueName>/
publisher.yml
如果从 Git 集成提交或 pac solution clone 获取了文件夹,文件夹结构应已正确。 仅包含不带 solutions/ 子目录的顶级 YAML 文件的文件夹表示不完整的提取,并且无法直接打包。
警告:rootcomponents.yml中声明的组件没有源文件
当组件(如画布应用)在rootcomponents.yml中列出,但在预期的组件文件夹中(例如canvasapps/<schema-name>/)不存在相应的源文件时,将显示此警告。
影响: 该工具仍会成功(退出代码 0),并生成有效的 .zip 文件,但已声明的组件将从打包的解决方案中省略。
原因: 该文件夹由部分提取生成,或者该组件的源文件未包含在存储库中。 例如,仅提交了解决方案的清单文件,而不是画布应用本身。
修复: 请确保在 rootcomponents.yml 文件夹中声明的所有组件都有相应的源文件。 对于画布应用,.msapp 文件必须存在于 canvasapps/<schema-name>/ 下。 如果缺少任何文件,请从 Dataverse 重新导出完整解决方案,然后重新将其解压缩,或者用于 pac solution clone 获取完整的提取。