创建 UWP 包

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

在本演练中,将创建一个具有本机 UWP 组件(包括 XAML 控件)的 NuGet 包,以便在托管项目和本机项目中使用。

先决条件

  1. Visual Studio 2017 或 Visual Studio 2015。 可以从 visualstudio.com 免费安装 2017 Community 版;也可以使用 Professional 和 Enterprise 版。

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

创建 UWP Windows 运行时组件

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

    Creating a new UWP Windows Runtime Component project

  2. 右键单击解决方案资源管理器中的项目,选择“添加新>项”,单击“Visual C++ > XAML”节点,选择“模板控件”,将名称更改为 AwesomeImageControl.cpp,然后单击“添加

    Adding a new XAML Templated Control item to the project

  3. 右键单击解决方案资源管理器中的项目,然后选择“属性”。在“属性”页中,展开“配置属性 > C/C++”,然后单击“输出文件”。 在右侧窗格中,将“生成 XML 文档文件”的值更改为“Yes”

    Setting Generate XML Documentation Files to Yes

  4. 现在,右键单击“解决方案”,选择“批生成”,选中对话框中的三个 Debug 框,如下所示。 这样可确保在生成时,将为 Windows 支持的每个目标系统生成一套完整的项目。

    Batch Build

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

注意

在本演练中,将使用包的 Debug 项目。 对于非调试包,请选中“批量生成”对话框中的 Release 选项,然后在以下步骤中引用生成的 Release 文件夹。

创建并更新 .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 运行时组件需要描述其所有公共可用类型的元数据,这使得其他应用和库可使用该组件。 该元数据包含在 .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(例如 .nupspec 文件中的 <Id> 元素)名称相同:

<?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>

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

<?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 Package Explorer showing the ImageEnhancer package

提示

.nupkg 文件实际上是具有其他扩展名的 ZIP 文件。 然后,也可通过将 .nupkg 更改为 .zip 来检查包内容,但将包上传到 nuget.org 之前,请记得恢复扩展名。

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