【问题标题】:How to deploy Content generated in a Target to AppX package in a UWP app with MSBuild如何使用 MSBuild 将目标中生成的内容部署到 UWP 应用中的 AppX 包
【发布时间】:2017-12-27 19:52:42
【问题描述】:

我有一个在 Visual Studio 2017 中创建的 C# XAML UWP 项目,我有一些想要转换并部署到 AppX 包的资产。但是,如果不直接将转换后的资产添加到 AppXPackagePayload,我将无法部署它们。

我创建了一个简化的测试用例,其中包含一个普通的 C# XAML 应用程序和一个 RawData 文件夹中的几个文本文件。我希望将文本文件转换(暂时复制)并部署到我的 AppX 中的 Data 文件夹中。

在导入 Xaml.CSharp.targets 之前,我在我的 csproj 中添加了以下内容(我添加了 ConvertedData 项类型只是为了调试):

<ItemGroup>
    <RawData Include="RawData\**\*.*" />
</ItemGroup>
<Target Name="ConvertData" BeforeTargets="Compile" Inputs="@(RawData)" Outputs="Data\%(RawData.RecursiveDir)%(RawData.Filename)%(RawData.Extension)">
  <ItemGroup>
    <ConvertedData Include="Data\%(RawData.RecursiveDir)%(RawData.Filename)%(RawData.Extension)" />
    <Content Include="Data\%(RawData.RecursiveDir)%(RawData.Filename)%(RawData.Extension)" />
  </ItemGroup>
  <Message Importance="high" Text="Creating Data: @(RawData) -> Data\%(RawData.RecursiveDir)%(RawData.Filename)%(RawData.Extension)" />
  <Copy SourceFiles="%(RawData.Identity)" DestinationFiles="Data\%(RawData.RecursiveDir)%(RawData.Filename)%(RawData.Extension)" />
</Target>
<Target Name="DisplayContent" AfterTargets="ConvertData" BeforeTargets="Compile">
  <Message Importance="high" Text="RawData: @(RawData)" />
  <Message Importance="high" Text="ConvertedData: @(ConvertedData)" />
  <Message Importance="high" Text="Content: @(Content)" />
</Target>

构建时的日志输出是这样的:

1>  Creating Data: RawData\Hello.txt -> Data\Hello.txt
1>  Creating Data: RawData\World.txt -> Data\World.txt
1>  RawData: RawData\Hello.txt;RawData\World.txt
1>  ConvertedData: Data\Hello.txt;Data\World.txt
1>  Content: Properties\Default.rd.xml;Assets\LockScreenLogo.scale-200.png;Assets\SplashScreen.scale-200.png;Assets\Square150x150Logo.scale-200.png;Assets\Square44x44Logo.scale-200.png;Assets\Square44x44Logo.targetsize-24_altform-unplated.png;Assets\StoreLogo.png;Assets\Wide310x150Logo.scale-200.png;Data\Hello.txt;Data\World.txt

正如预期的那样。现在,我的项目文件夹中有一个 Data 文件夹,其中包含我的“转换后的”文本文件。但是,在部署应用程序时,Data 文件夹中的文件永远不会进入 AppX 文件夹,即使它们被列为内容。未在 Target 中生成的所有其他资产都会被部署。似乎在 Target 中创建的内容项没有添加到 AppXPackagePayload。

如果我将以下内容添加到目标的 ItemGroup:

<AppxPackagePayload Include="Data\%(RawData.RecursiveDir)%(RawData.Filename)%(RawData.Extension)">
  <TargetPath>Data\%(RawData.RecursiveDir)%(RawData.Filename)%(RawData.Extension)</TargetPath>
</AppxPackagePayload>

然后将 Data 文件夹中的项目部署到 AppX。但是,我觉得只需将我的项目添加到 Target 中的 Content 就足以部署它们。我做错了吗?

谢谢!

【问题讨论】:

  • 您是否尝试过重新加载项目?
  • 是的,很多次!实际上,在我上面概述的测试用例中,我直接编辑 csproj 文件,因此每次进行编辑时,Visual Studio 都会强制重新加载解决方案。我也试过重启VS。
  • 从 Nico 的评论开始,值得澄清的是,如果代码在外部 props 文件中而不是直接在 csproj 中,则必须关闭并重新加载整个解决方案才能查看 VS 中的任何更改。卸载和重新加载解决方案中的特定项目是不够的。

标签: msbuild uwp appx


【解决方案1】:

内容项的处理发生在编译之前,所以你应该替换

BeforeTargets="Compile"

BeforeTargets="AssignTargetPaths"

这应该可以解决问题。

【讨论】:

  • 是的,成功了!事后看来,我应该意识到它只是在错误的时间运行。谢谢!
  • 以防万一它对某人有用,我将我的示例项目放在 Github 上:https://github.com/jccaulfield/MSBuildTest
【解决方案2】:

我现在有一个可行的解决方案,它可以避免 Target 生成的内容项以及显式 AppXPackagePayload。这是因为我的 RawDataData 文件之间存在一对一的映射,因此我可以将所有内容项放在目标之外。它没有回答为什么 Target-generated Content 项目不部署(如果有人知道,我仍然想知道为什么会这样),但它确实以干净的方式解决了我的问题,因此对其他人有用:

<ItemGroup>
    <RawData Include="RawData\**\*.*">
      <Visible>True</Visible>
    </RawData>
</ItemGroup>
<ItemGroup>
    <Content Include="@(RawData-> 'Data\%(RecursiveDir)%(Filename)%(Extension)')">
      <Visible>True</Visible>
    </Content>
</ItemGroup>
<Target Name="ConvertData" BeforeTargets="Compile" Inputs="@(RawData)" Outputs="Data\%(RawData.RecursiveDir)%(RawData.Filename)%(RawData.Extension)">
  <Copy SourceFiles="%(RawData.Identity)" DestinationFiles="Data\%(RawData.RecursiveDir)%(RawData.Filename)%(RawData.Extension)" />
</Target>

现在我的 Data 文件在我的项目文件夹中创建,并正确部署到 AppX 文件夹。

【讨论】:

  • 这个答案实际上只是一种解决方法,它可以避免这个问题,并且可能对其他有类似问题的人有所帮助。我仍然希望有人能够帮助解决根本问题,即为什么我从目标发出的内容项没有被部署。
猜你喜欢
  • 2018-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 2016-01-20
  • 1970-01-01
  • 2015-01-06
相关资源
最近更新 更多