Если вы будете удовлетворены ответом @Filburt, я могу предложить улучшить это решение.
Если вы посмотрите, как работает Build target по умолчанию:
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(BuildDependsOn)"
Returns="$(TargetPath)" />
Вы увидите, что единственный выход от цели сборки или перестроения - $ (TargetPath) .
$ (TargetPath) - это полный путь к сборке. Чтобы изменить это поведение, вы можете взломать процесс сборки. Но проще будет определить собственную цель в проекте B :
<Target
Name="BuildWithConfig"
DependsOnTargets="Clean;Build"
Returns="$(TargetPath);$(TargetPath).config" />
В A проекте просто определите AfterBuild target:
<Target Name="AfterBuild">
<MSBuild Projects="Executable_B.proj" Targets="BuildWithConfig">
<Output TaskParameter="TargetOutputs" ItemName="AssembliesBuilt" />
</MSBuild>
<Copy SourceFiles="@(AssembliesBuilt)" DestinationFolder="$(OutDir)\SubDirForB" SkipUnchangedFiles="true" />
</Target>
Это решение не требует создания собственного сценария сборки. Вы получите результат непосредственно в VS.