PostBuild does not work in Visual Studio

IDE: Visual Studio 2019/Water
Version: Elements Version 11.0.0.2655 (develop) built on bajor, 20210730-130829. Commit d616582.
Target (If relevant): .NET Core
Description: When using Visual Studio and trying to compile a project with a PostBuild tag, the build fails. In Water, the same project works just fine.

Expected Behavior: The project compiles and the post build script runs.

Actual Behavior: The project compiles only in Water. In Visual Studio, it fails with the following error:

Build started...
1>------ Build started: Project: SwiftGameCode, Configuration: Debug AnyCPU ------
1>Unhandled Exception:The element <PostBuild> beneath element <Project> is unrecognized.  C:\Users\Terrain\Documents\Code\Unity\ElementsUnityTest\SwiftGameCode\SwiftGameCode.elements
1>Error: The element <PostBuild> beneath element <Project> is unrecognized.  C:\Users\Terrain\Documents\Code\Unity\ElementsUnityTest\SwiftGameCode\SwiftGameCode.elements
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

Steps:

  1. Create a new elements project
  2. Add a PostBuild script in the project file
  3. Build it in Water, and then in Visual Studio

Additionally, if i put it in a PropertyGroup, the build succeeds in Visual Studio but the script does not run. Visual Studio will complain if i put a Platform on the PostBuild tag in a PropertyGroup.

Here’s the elements project minus unity imports. Since i encountered this while just testing to see if i could use elements with Unity, i can also provide the full unity project and code files if you cannot reproduce with just the elements project.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
  <PropertyGroup>
    <ProductVersion>3.5</ProductVersion>
    <ProjectGuid>{8D01DCB2-3D13-4B22-AC05-E402DAD36E7C}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AssemblyName>SwiftGameCode</AssemblyName>
    <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
    <TargetFramework>.NETCore</TargetFramework>
    <Mode>Echoes</Mode>
    <Name>SwiftGameCode</Name>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <Optimize>False</Optimize>
    <OutputPath>.\Bin\Debug\</OutputPath>
    <ConditionalDefines>DEBUG;TRACE;</ConditionalDefines>
    <GeneratePDB>True</GeneratePDB>
    <GenerateMDB>True</GenerateMDB>
    <EnableAsserts>True</EnableAsserts>
    <CpuType>anycpu</CpuType>
    <EnableUnmanagedDebugging>False</EnableUnmanagedDebugging>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <OutputPath>.\Bin\Release</OutputPath>
    <CpuType>anycpu</CpuType>
    <EnableUnmanagedDebugging>False</EnableUnmanagedDebugging>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Silver">
      <Private>True</Private>
    </Reference>
    <Reference Include="Echoes">
      <Private>True</Private>
    </Reference>
    <!-- ... more imports ... -->
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Class1.swift" />
    <Compile Include="Properties\AssemblyInfo.swift" />
  </ItemGroup>
  <Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Elements\RemObjects.Elements.targets" />
  <PostBuild>
    copy "$(OutputPath)\*.dll" "..\Assets\"
  </PostBuild>
</Project>

This project file was originally created with dotnet new classlib and then i used ebuild --convert to convert it to an elements project. That’s because i couldn’t figure out how to create a new class library project in elements directly (it was complaining that there was no main method).

Make sure you have EBuild-style cross-platform compatible scripts; see Pre- and Post-Build Scripts for details. If you edit these in VS, they should automatically be added the correct way.

What do you mean by this? “cross-platform compatible scripts”? Specifying a Platform attribute on the PostBuild tag? If i do that, i get the same error. If i wrap it in a PropertyGroup (which as i noted in my post, allows the project to build in VS without running the script), i then get this error:

Build started...
1>------ Build started: Project: SwiftGameCode, Configuration: Debug AnyCPU ------
1>Unhandled Exception:The attribute "Platform" in element <PostBuild> is unrecognized.  C:\Users\Terrain\Documents\Code\Unity\ElementsUnityTest\SwiftGameCode\SwiftGameCode.elements
1>Error: The attribute "Platform" in element <PostBuild> is unrecognized.  C:\Users\Terrain\Documents\Code\Unity\ElementsUnityTest\SwiftGameCode\SwiftGameCode.elements
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

(here’s the end of the project file i changed to get that error)

  <PropertyGroup>
    <PostBuild Platform="Windows">
      copy "$(OutputPath)\*.dll" "..\Assets\"
    </PostBuild>
  </PropertyGroup>
</Project>

And what do you mean by editing it in VS? Like this? I don’t see a “Build Events” tab in the project properties.

The page you linked doesn’t help me solve my issue.

I think this might be the relevant part:

For backward compatibility with MSBuild, the <PreBuildEvent> or <PostBuildEvent> element names may be used instead.

I also tried a PostBuildEvent. My code compiles but the command does not run. Neither with VS or Water.

  <PropertyGroup>
    <PostBuildEvent>
      copy "$(OutputPath)\*.dll" "..\Assets\"
    </PostBuildEvent>
  </PropertyGroup>
</Project>

Can you send me a testcase? I cannot reproduce this here:

This is a minimal elements project which reproduces the same issue for me.
SwiftGameCode.zip (2.5 KB)

  <PropertyGroup>
    <PostBuildEvent>echo "Hello"</PostBuildEvent>
  </PropertyGroup>
  <Import Project="$(MSBuildExtensionsPath)\RemObjects Software\Elements\RemObjects.Elements.targets" />
</Project>```

vs

echo "Hello" ```

These should not be inside a PropertyGroup, as far as I know.

If i put it at the top level, it works in Water. In Visual Studio, i get the following output:

Build started...
1>------ Build started: Project: SwiftGameCode, Configuration: Debug AnyCPU ------
1>Unhandled Exception:The element <PostBuildEvent> beneath element <Project> is unrecognized.  C:\Users\Terrain\Documents\Code\Swift\TestNoPostBuild\SwiftGameCode\SwiftGameCode.elements
1>Error: The element <PostBuildEvent> beneath element <Project> is unrecognized.  C:\Users\Terrain\Documents\Code\Swift\TestNoPostBuild\SwiftGameCode\SwiftGameCode.elements
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

The reason i had the PostBuildEvent in a PropertyGroup is because that’s necessary in a csproj (or rather, that’s what another project i know works does, not sure if it’s actually necessary), and it did actually get the project to compile in Visual Studio, so i assumed that was more correct than not having it in a PropertyGroup.

FWIW, for tomorrow’s build, i’m adding support for finding this inside an <ItemDefinitionGroup>; which I never heard of before, but apparently is a thing MSBuild supports. I’ll add support for <PropertyGroup> b but according to all in find online, that’s not where they are supposed to go.

  <ItemDefinitionGroup>
    <PostBuildEvent>echo "Hello"</PostBuildEvent>
  </ItemDefinitionGroup>

according to all in find online, that’s not where they are supposed to go.

In Visual Studio, if you create a C# project from the “Class Library (.NET Framework)” built in template, and then add a post build event as described here, VS will add it in a PropertyGroup at the end of the csproj. I’ll try again on tomorrow’s build then ig.