Search code examples
c#msbuildwindows-store-apps

Add dynamically generated file in MSBuild task to output and appx folders


I have created a build task that dynamically generates a file for the project it's used in. I've managed to get that file to be copied into the $(TargetDir), but not into the AppX folder. The reason I need it there is, that this build task is about unit tests and this file is needed inside the tests.

Sounds a bit confusing so I try to clarify a little:

I generate code in that task and compile that into an assembly which I add as a reference to the main assembly (in this case the test.dll). So what happens is that I do this after the "AfterCompile" target and my assembly gets generated into the obj\Debug folder. This is my Target:

<UsingTask TaskName="MyBuildTask" AssemblyFile="MyBuildTask.dll"/>

<Target 
    AfterTargets="AfterCompile"
    Name="MyBuildTarget">
    <MyBuildTask
        SolutionRoot="$(SolutionDir)"
        GeneratedAssemblyPath="$(IntermediateOutputPath)$(TargetName).Generated.dll"
        TestProjectPath="$(ProjectPath)"
        TestAssemblyPath="@(IntermediateAssembly)"
    >
        <Output TaskParameter="GeneratedFile" ItemName="GeneratedFile"/>
    </MyBuildTask>
    <ItemGroup>
        <Content Include="@(GeneratedFile)">
            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
            <DeploymentContent>true</DeploymentContent>
        </Content>
    </ItemGroup>
</Target>

One this, that I also don't want is, that this file now gets copied to \bin\Debug\obj\Debug.

I could obviously specify this statically, so that it's always copied to the output path root and then to the AppX folder, I only want to do this as my last solution if there is nothing else I can do.

So how do I get my file into this GetCopyToOutputDirectoryItems, which I presume is the list of items that are both for the output directory and the AppX package?


Solution

  • I've actually found after a consecutive 8 hours of further research about the topic and reading a lot through all the target files from both Microsoft.Common.targets and Microsoft.AppxPackage.targets the solution to my problem:

        <ItemGroup>
            <AppxPackagePayload Include="@(GeneratedAssemblyFullPath)" Condition="@(AppxPackagePayload) != '' Or @(AppxPackagePayload) != '*Undefined*'">
                <TargetPath>@(GeneratedFile)</TargetPath>
            </AppxPackagePayload>
        </ItemGroup>
    

    This adds the file to the AppxPackagePayload and thus it will be copied to the Appx package.

    PS: Since I was a little confused myself about this. @(GeneratedFile) and @(GeneratedAssemblyFullPath) are the outputs from my own build task and of type "string", like the names suggest. @(GeneratedFile) is just the file name, so it will be put into the root.