When targeting .NET Framework, we should generate an app.config file as part of build if the project doesn't specify one. Otherwise, an app targeting 4.x will run on older 4.x machines, and fail at runtime with strange missing method exceptions.
(It's probably okay to do this only for sdk-style projects, as traditional templates include an app.config)
We should do this regardless of whether it exists or not, similar to binding redirects.
@davkean Meaning if it exists, but has no <supportedRuntime> entry, then we add the entry? If so, I agree.
Yeah.
This is what I am thinking.
Add a task that will create yet another intermediate .config based on GenerateBindingRedirects's output(obj\Debug\net452\win7-x86\my.exe.config). And if GenerateBindingRedirects's intermeida .config file is generated, kick that out of $(AppConfigWithTargetPath) and replace it with the new .config with both binding redirect and supportedRuntime. PrepareForRun will copy $(AppConfigWithTargetPath) to bin
So it will be aftertargets=GenerateBindingRedirectsUpdateAppConfig beforeTargets=PrepareForRun
OR
I will directly change the result of GenerateBindingRedirects's intermediate output.
They all have to override something
talked to Daniel, we need to verify, if there is no app.config, GenerateBindingRedirects might not create. So we should create app.config before GenerateBindingRedirects
I tested, if there is no app.config, BindingRedirects will still be generated
@dsplaisted should I do the same thing for dll (full framework libraries). i think no

csproj:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworks>net45;net40;net40-client;netstandard1.5</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard1.5'">
<DefineConstants>$(DefineConstants);DESKTOP</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net40-client'">
<!-- TargetFrameworkInference does not support net40-client -->
<TargetFrameworkIdentifier>.NETFramework</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.5'">
<Reference Include="System.Windows.Forms" />
<PackageReference Include="Newtonsoft.Json" Version="6.0.4" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.5'">
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
</Project>
I don't think we need to create an app.config by default for libraries. If a library project does have an app.config defined, then we can still add the supportedRuntime to it.
if app.config is defined and if it is library then add supportedruntime. Sounds complicated. Maybe just do not generate it at all? full framework class library template won't have it
just skip the target if $(OutputType) != "Exe"
Careful with OutputType != Exe, there is also WinExe. We have another property to use for this, looking for its name.
$(HasRuntimeOutput)
Most helpful comment
Yeah.