Unlike previous versions of the .NET Framework, the .NET Framework 4 does not allow an application that was built with previous versions of the .NET Framework to migrate forward and run on it if the previous version is not installed
They do, but you have to explicitly allow it to run using the .NET 4 runtime. As the framework has a new runtime, you have to opt in to allowing this if your application targetted an older version.
You can do this by having your app config specify the proper supportedRuntime variables, ie:
<configuration>
<startup>
<supportedRuntime version="v4.0"/>
<supportedRuntime version="v2.0.50727"/>
</startup>
</configuration>
Without this, the runtime does:
If the element is not present in the application configuration file, the version of the runtime used to build the application is used.
Because you built with CLR 2, only the 2.0 runtime is allowed, so it fails if the user doesn't have .NET 3.5sp1.