创建 UWP 包

Universal Windows Platform (UWP)为每个运行Windows 10的设备提供一个通用的应用平台。 在此模型中,UWP 应用可以调用所有设备通用的 WinRT API,以及特定于运行应用的设备系列(包括 Win32 和 .NET)的 API。

在本演练中,你将创建一个包含本机 UWP 组件(包括 XAML 控件)的 NuGet 包,该组件可在托管项目和本机项目中使用。

先决条件

  1. Visual Studio 2017 或 Visual Studio 2015。 从 visualstudio.com 免费安装 2017 社区版;还可以使用专业版和企业版。

  2. NuGet CLI。 从 nuget.exe 下载最新版本,并将其保存到您选择的位置(下载的是.exe本身)。 然后将该位置添加到 PATH 环境变量(如果尚未添加)。

创建 UWP Windows Runtime 组件

  1. 在 Visual Studio 中, 选择 File > New > Project,展开 Visual C++ > Windows > Universal 节点,选择Windows Runtime组件(通用Windows)模板,将名称更改为 ImageEnhancer,然后单击“确定”。 出现提示时,接受目标版本和最低版本的默认值。

    创建新的 UWP Windows Runtime 组件项目

  2. 右键单击Solution Explorer中的项目,选择 Add > New Item, 单击 Visual C++ > XAML 节点,选择 Templated Control,将名称更改为 AwesomeImageControl.cpp,然后单击 Add

    向项目添加新的 XAML 模板化控件项

  3. 右键单击Solution Explorer中的项目,然后选择Properties. 在“属性”页中,展开“配置属性> C/C++并单击Output Files。 在右侧窗格中,将 “生成 XML 文档文件 ”的值更改为“是”:

    将“生成 XML 文档文件”设置为“是”

  4. 立即右键单击 解决方案 ,选择 “批处理生成”,选中对话框中的三个“调试”框,如下所示。 这可确保在执行构建时,为 Windows 支持的每个目标系统生成一整套工件。

    批量构建

  5. 在“批处理生成”对话框中,单击“ 生成 ”以验证项目并创建 NuGet 包所需的输出文件。

注释

在本演练中,使用包的调试工件。 对于非调试包,请改为选中“批处理生成”对话框中的“发布”选项,并在后续步骤中引用生成的发布文件夹。

创建并更新 .nuspec 文件

若要创建初始 .nuspec 文件,请执行以下步骤。 接下来的部分将指导你完成其他必要的更新。

  1. 打开命令提示符并导航到包含 ImageEnhancer.vcxproj 的文件夹(这是解决方案文件下方的子文件夹)。

  2. 运行 NuGet spec 命令以生成 ImageEnhancer.nuspec (文件的名称取自文件的名称 .vcxproj ):

    nuget spec
    
  3. 在编辑器中打开 ImageEnhancer.nuspec 并更新它以匹配以下内容,并将YOUR_NAME替换为适当的值。 具体而言,该值 <id> 必须在 nuget.org 中是唯一的(请参阅 创建包中所述的命名约定)。 请注意,您还必须更新作者和描述标签,否则在打包过程中会出现错误。

    <?xml version="1.0"?>
    <package >
        <metadata>
        <id>ImageEnhancer.YOUR_NAME</id>
        <version>1.0.0</version>
        <title>ImageEnhancer</title>
        <authors>YOUR_NAME</authors>
        <owners>YOUR_NAME</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>Awesome Image Enhancer</description>
        <releaseNotes>First release</releaseNotes>
        <copyright>Copyright 2016</copyright>
        <tags>image enhancer imageenhancer</tags>
        </metadata>
    </package>
    

注释

对于为公共使用的包,请特别注意 <tags> 该元素,因为这些标记可帮助其他人找到包并了解它的作用。

将Windows元数据添加到包

Windows Runtime组件需要描述其所有公开可用的类型的元数据,从而使其他应用和库可以使用该组件。 此元数据包含在 .winmd 文件中,该文件是在编译项目时创建的,并且必须包含在 NuGet 包中。 会同时生成一个包含 IntelliSense 数据的 XML 文件,并应将其包含在内。

将以下 <files> 节点添加到 .nuspec 该文件:

<package>
    <metadata>
        ...
    </metadata>

    <files>
        <!-- WinMd and IntelliSense files -->
        <file src="..\Debug\ImageEnhancer\ImageEnhancer.winmd" target="lib\uap10.0"/>
        <file src="..\Debug\ImageEnhancer\ImageEnhancer.xml" target="lib\uap10.0"/>
    </files>
</package>

添加 XAML 内容

若要将 XAML 控件包含在组件中,需要添加具有控件的默认模板的 XAML 文件(由项目模板生成)。 这也在 <files> 部分中。

<?xml version="1.0"?>
<package >
    <metadata>
        ...
    </metadata>
    <files>
        ...

        <!-- XAML controls -->
        <file src="Themes\Generic.xaml" target="lib\uap10.0\Themes"/>

    </files>
</package>

添加本地实现的库

在组件中,ImageEnhancer 类型的核心逻辑位于本机代码中,它包含在为每个目标运行时(ARM、x86 和 x64)生成的各种 ImageEnhancer.dll 程序集中。 若要在包中包含这些内容,请在<files>节中引用它们,并注明它们关联的 .pri 资源文件:

<?xml version="1.0"?>
<package >
    <metadata>
        ...
    </metadata>
    <files>
        ...

        <!-- DLLs and resources -->
        <file src="..\ARM\Debug\ImageEnhancer\ImageEnhancer.dll" target="runtimes\win10-arm\native"/>
        <file src="..\ARM\Debug\ImageEnhancer\ImageEnhancer.pri" target="runtimes\win10-arm\native"/>

        <file src="..\ARM64\Debug\ImageEnhancer\ImageEnhancer.dll" target="runtimes\win10-arm64\native"/>
        <file src="..\ARM64\Debug\ImageEnhancer\ImageEnhancer.pri" target="runtimes\win10-arm64\native"/>

        <file src="..\x64\Debug\ImageEnhancer\ImageEnhancer.dll" target="runtimes\win10-x64\native"/>
        <file src="..\x64\Debug\ImageEnhancer\ImageEnhancer.pri" target="runtimes\win10-x64\native"/>

        <file src="..\Debug\ImageEnhancer\ImageEnhancer.dll" target="runtimes\win10-x86\native"/>
        <file src="..\Debug\ImageEnhancer\ImageEnhancer.pri" target="runtimes\win10-x86\native"/>

    </files>
</package>

添加 .targets

接下来,可能使用 NuGet 包的 C++ 和 JavaScript 项目需要一个 .targets 文件来标识所需的程序集和 winmd 文件。 (C# 和Visual Basic项目自动执行此操作。通过将下面的文本复制到 ImageEnhancer.targets 中创建此文件,并将其保存在与 .nuspec 文件相同的文件夹中。 注意:此.targets文件的名称必须与包 ID 相同(例如文件中的<Id>.nupspec元素):

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <ImageEnhancer-Platform Condition="'$(Platform)' == 'Win32'">x86</ImageEnhancer-Platform>
        <ImageEnhancer-Platform Condition="'$(Platform)' != 'Win32'">$(Platform)</ImageEnhancer-Platform>
    </PropertyGroup>
    <ItemGroup Condition="'$(TargetPlatformIdentifier)' == 'UAP'">
        <Reference Include="$(MSBuildThisFileDirectory)..\..\lib\uap10.0\ImageEnhancer.winmd">
            <Implementation>ImageEnhancer.dll</Implementation>
        </Reference>
    <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)..\..\runtimes\win10-$(ImageEnhancer-Platform)\native\ImageEnhancer.dll" />
    </ItemGroup>
</Project>

然后在ImageEnhancer.targets文件中引用.nuspec

<?xml version="1.0"?>
<package >
    <metadata>
        ...
    </metadata>
    <files>
        ...

        <!-- .targets -->
        <file src="ImageEnhancer.targets" target="build\native"/>

    </files>
</package>

最终 .nuspec

您的最终 .nuspec 文件现在应如下所示:再次,将YOUR_NAME替换为一个适当的值。

<?xml version="1.0"?>
<package >
    <metadata>
    <id>ImageEnhancer.YOUR_NAME</id>
    <version>1.0.0</version>
    <title>ImageEnhancer</title>
    <authors>YOUR_NAME</authors>
    <owners>YOUR_NAME</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Awesome Image Enhancer</description>
    <releaseNotes>First Release</releaseNotes>
    <copyright>Copyright 2016</copyright>
    <tags>image enhancer imageenhancer</tags>
    </metadata>
    <files>
    <!-- WinMd and IntelliSense -->
    <file src="..\Debug\ImageEnhancer\ImageEnhancer.winmd" target="lib\uap10.0"/>
    <file src="..\Debug\ImageEnhancer\ImageEnhancer.xml" target="lib\uap10.0"/>

    <!-- XAML controls -->
    <file src="Themes\Generic.xaml" target="lib\uap10.0\Themes"/>

    <!-- DLLs and resources -->
    <file src="..\ARM\Debug\ImageEnhancer\ImageEnhancer.dll" target="runtimes\win10-arm\native"/>
    <file src="..\ARM\Debug\ImageEnhancer\ImageEnhancer.pri" target="runtimes\win10-arm\native"/>
    <file src="..\ARM64\Debug\ImageEnhancer\ImageEnhancer.dll" target="runtimes\win10-arm64\native"/>
    <file src="..\ARM64\Debug\ImageEnhancer\ImageEnhancer.pri" target="runtimes\win10-arm64\native"/>     
    <file src="..\x64\Debug\ImageEnhancer\ImageEnhancer.dll" target="runtimes\win10-x64\native"/>
    <file src="..\x64\Debug\ImageEnhancer\ImageEnhancer.pri" target="runtimes\win10-x64\native"/>
    <file src="..\Debug\ImageEnhancer\ImageEnhancer.dll" target="runtimes\win10-x86\native"/>
    <file src="..\Debug\ImageEnhancer\ImageEnhancer.pri" target="runtimes\win10-x86\native"/>

    <!-- .targets -->
    <file src="ImageEnhancer.targets" target="build\native"/>

    </files>
</package>

打包组件

完成 .nuspec 引用包中包含的所有文件后,即可运行以下命令 pack

nuget pack ImageEnhancer.nuspec

这将生成 ImageEnhancer.YOUR_NAME.1.0.0.nupkg。 在 NuGet 包资源管理器 等工具中打开此文件并展开所有节点,你将看到以下内容:

NuGet 包资源管理器中显示的 ImageEnhancer 包

小窍门

文件 .nupkg 只是具有不同扩展名的 ZIP 文件。 您还可以通过将 .nupkg 更改为 .zip 来检查包内容,但请记住在将包上传到 nuget.org 之前恢复文件扩展名。

若要使包可供其他开发人员使用,请按照有关 发布包的说明进行操作。