How to force compile an application for the target .NET Framework 4 for .NET Framework 4.6.1?

I did a lot of research and did not find a suitable answer. Here is the script.

I have an application that was compiled for the target .NET Framework 4. At runtime, I want this application to actually run in the .NET Framework 4.6.1. So far I have found two options.

  • Recompile the application in the .NET Framework 4.6.1
  • Add the / startup / supportedRuntime configuration item to app.config with version = "v4.0" sku = ". NETFramework, Version = v4.6.1"

Option 1 is undesirable, as this will require re-release of the software.

Option 2 does not do what I expect. It seems that it checks to see if CLR 4.0 (not Framework 4.0) is installed, and if you are not prompted to download the appropriate SKU to install it. After installation, the application is still running in the .NET Framework 4.0

As a test, and the reason this question is posted, I created a small console application that just does it

Console.WriteLine(System.Net.ServicePointManager.SecurityProtocol); 

If this is compiled against the .NET Framework 4, then the output will be

Ssl3, Tls

If this is compiled against the .NET Framework 4.6.1, then the output will be

Tls, Tls11, Tls12

+7
clr
source share
2 answers

I ... ask about the general case of forcing an application compiled using framework 4.0 using framework 4.6.1

Well, you already did this with the app.config file entry. It provides this function , the user cannot run the program without installing 4.6.1. All he needs to do is click the Yes button. Not that this is done very often, 4.6.1 should always be present on the machine when the user is responsible for updating his machine in Windows Update. If he intentionally does not do this, then β€œforcing” is unlikely to be well received.

But in fact, this is not about your question. You want your program to behave as it is installed in 4.6.1. This is a completely different kettle of fish. Please note that 2) does not work, you cannot easily fool the runtime. The compiler has embedded the TargetFrameworkAttribute attribute in the executable file, which is used at run time to determine how it should behave. Look at this with ildasm.exe, double-click the manifest to see it. Your app.config entry does not cancel it.

The biggest problem is that .NET 4.5 is quite fundamentally different with very disruptive changes both at runtime and in frame assemblies. Heavy enough to warrant a hit before version 5.0. But it always causes a lot of problems and suffering for customers, Microsoft pulled out every trick in the book to do 4.5 (and up), like 4.0 if it runs a program aimed at 4.0.

Not one trick. One of the main approaches was the referenced assemblies stored in the c: \ Program Files (x86) \ Reference Assemblies directory. They store targeting package files. You used the ones that were saved in C: \ Program Files (x86) \ Reference Assemblies \ Microsoft \ Framework.NETFramework \ v4.0 during the initial development of your program. If you reconfigure your project, you will use those stored in version 4.1. They are very different. And especially the SecurityProtocolType enumeration you are talking about is different, it has acquired two new meanings. This change is a violation , the .NET 4.0 program is prone to a heart attack, when it sees SecurityProtocolType.Tls12, it has no idea what this can mean. Creating a program with incorrect targeting package files can cause deeply cryptic exceptions .

And other tricks. Bug fixes made in .NET 4.0 release publications are selectively included depending on [TargetFrameworkAttribute], backward compatibility for bugs is important to ensure that the program does not observe changed behavior at runtime. And the CLR is filled to the brim with the help of on-off switches. I could point to the source code file in CoreCLR, but it's too scary to look :)

So no, it is not possible to make a program compiled for the target .NET 4.0 to behave as if it works on a higher version. The registry key and appcontext switch that you learned about are very specific only to the ServicePointManager.SecurityProtocol property. They exist simply because you are not the only client who wants to do this, TLS versions are very important. Just make sure that the new enumeration values ​​do not disable your program.

+8
source share

The specific definition of ServicePointManager.SecurityProtocol is completely unrelated to the general question about the structure of 4 vs 4.6.1, for which I am afraid there is no definitive answer, because this does not apply to the general case (all cases are probably specific if you will).

For a specific answer, this is described here: Mitigation: TLS Protocols

Starting with the .NET Framework 4.6, System.Net.ServicePointManager and System.Net.Security.SslStream classes are allowed to use one of the following three protocols: Tls1.0, Tls1.1, or Tls 1.2. SSL3.0 protocol and RC4 cipher are not supported.

If 4.6+ is installed, you can really change the behavior of your program without compiling it, as described in the article, just add this line to your .config files:

 <configuration> ... <runtime> ... <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false" /> </runtime> ... </configuration> 
+3
source share

All Articles