app.config "forced" (?) on .net 4.0.. is it needed? - .net-4.0

It seems that when upgrading a project to .net 4.0 in VS 2010 Beta 2,
a app.config file is generated, which roughly looks like this:
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
Is this file needed in case I want to have a .NET 4.0 only executable?
NOTE: Interestingly enough, this only happens in c# as opposed to f# projects.
I have successfully removed it without any visible (so far) side effects.
Can anyone elaborate on it's importance (if at all)

It's not so much about how the app behaves on your computer, but how it will behave on other computers, or when you install an updated dotnet runtime on your machine.
Basically, if you don't include this, the latest version of the dotnet runtime will be used to run your app. That might sound like a good thing, until some feature that you depend on becomes deprecated or a bug that you don't realize you're depending on gets fixed.
More usefully, when you have originally built an app to work with an older version of the dotnet framework, you can use this feature after you've tested it with newer versions to assert that, yes, it does work with the latest version.
Here's the horse's mouth text from MSDN:
If the version of the .NET Framework
that the application was built against
is present on the computer, the
application runs on that version.
If the version of the .NET Framework
that the application was built against
is not present and a configuration
file does not specify a version in a
Element, the
application runs on the latest version
of the .NET Framework that is present
on the computer.
If the version of the .NET Framework
that the application was built against
is not present and the configuration
file specifies a version in a
Element, the
application runs on the latest version
that is specified in the application
configuration file and is present on
the computer.

Related

How do I prevent installing nuget packages that aren't 100% .Net Core 2.0 compatible?

I understand that .Net Core 2 has a compatibility shim that allows it use Nuget packages that don't specifically target .Net Core/Standard 2. This gives it access to 70% of Nuget. Great - nice feature.
How do I prevent installing nuget packages that aren't fully compatible with .Net Core 2/.Net Standard 2? Or warn me at point of installing that it is being used with the shim?
I created a new .Net Core 2.0 project installed EF 6.1.3 (which I knew didn't work) and nothing prevented me or warned that it didn't target .Net Standard <=2 at the point of install.
I am happy to "run with scissors" but I kind of feel I should be getting a warning before I install MVC5 and EF 6.1.3 into a .Net Core 2 application. I would really like to prevent junior devs from installing unsupported packages etc.
I guess further to Matt Ward answer - my main point is - can it be detected that something is actually 100% compatible at install or are we always just in the situation where we need to make determination ourselves that package works "well enough". I hoped that there was a technical mechanism that detected missing coverage API coverage and could tell us that the nuget package may not operate as it did before. So I guess MS say 70% compatibility - I want to fail if I try to install the 30%
Installing Entity Framework 6.1.3 into a .NET Core 2.0 project there is a NU1701 warning in the Errors window about Entity Framework 6.1.3 being restored using .NET Framework 4.6.1 and that it may not be fully compatible.
You could turn the NU1701 warning into an error in the project so you could not install any NuGet package that does not explicitly support .NET Core 2.0. This can be done by adding the WarningAsErrors property to the project.
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<WarningsAsErrors>NU1701</WarningsAsErrors>
</PropertyGroup>
Then if you try to install Entity Framework 6.1.3 the restore will fail, the changes will be rolled back, and the NuGet package will not be installed.
You can also set the DisableImplicitAssetTargetFallback property to true which will prevent .NET 4.6.1 being added to the AssetTargetFallback property which is used when checking NuGet package compatibility with .NET Core 2.0 projects.
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<DisableImplicitAssetTargetFallback>true</DisableImplicitAssetTargetFallback>
</PropertyGroup>
If you wan to be 100% sure, run the package against .NET Portability Analyzer and .NET Standard 2.0 profile.
It won't tell you if the API will be called or not (and is in no way an automatic process), just if the Assembly contains any API which is not .NET Standard 2.0 compatible.
However, you can also only run your application against the Analyzer, as the .NET Portability Analyzer should be able to follow any references made from the application and check these too.
Update
You can als build this into your build server pipeline, to get a more automatic guarantees.
The .NET Portability Analyzer Docs.
Visual Studio is not required for this, just download it from https://github.com/Microsoft/dotnet-apiport/releases and run
From the docs:
Type the following command to analyze the current directory: \...\ApiPort.exe analyze -f .
To analyze a specific list of .dll files, type the following command: \...\ApiPort.exe analyze -f first.dll -f second.dll -f third.dll
Old Answer (may be useful in conjcution with Matt's answer)
Untested, but give it a try:
<!-- old dotnet tooling/.NET Core 1.x -->
<PackageTargetFallback>netstandard2.0;portable-net45+win8</PackageTargetFallback>
<!-- new dotnet tooling/.NET Core 2.0 -->
<AssetTargetFallback>netstandard2.0;portable-net45+win8</AssetTargetFallback>
Typically you want to have it like
<!-- old dotnet tooling/.NET Core 1.x -->
<PackageTargetFallback>$(PackageTargetFallback);dotnet5.6;portable-net45+win8</PackageTargetFallback>
<!-- new dotnet tooling/.NET Core 2.0 -->
<AssetTargetFallback>$(AssetTargetFallback);dotnet5.6;portable-net45+win8</AssetTargetFallback>
Where $(PackageTargetFallback) will tell MSBuild to keep the old values and append the values after that to it. But since $(PackageTargetFallback) probably (can't look/dig deeper in right now) have the .NET Framework moniker there, you'll override it with your own values.
Additionally
Given that PackageTargetFallback is now deprecated, one should use AssetTargetFallback instead.
As far as I know .Net portability analyzer tool can not 100% determine the platform that does not support installation, such as system.runtime.Loader, after tool analysis, 100% supports the framework platform, but it does not
Screenshot of analysis results:analyse System.Runtime.Loader

ASP.NET Core with .NET 4.6.2 and VS 2017 RC

Using Visual Studio 2017 (RC), I am trying to setup a project that uses ASP.NET Core, but with the .NET 4.6.2 library.
This is a supported configuration:
Visual Studio will then create a default project; but it doesn't run:
This is without changing a single line in the project: the VC2017 template just does not work.
I tried the following:
- Different versions of the .NET framework
- x86, x64, AnyCPU
- Clear the NuGet cache
- 'Repair' options on Visual Studio's installer.
My understanding is that the error is a x86/x64 mismatch. But since I didn't change a single file from the template, there has to be something else wrong.
Installing ASP.NET Core on .NET Core works perfectly, so the problem is limited to using the regular .NET framework.
Any ideas?
I have the same problem too. But I just found the solution.
In ".csproj" I change some things:
<PropertyGroup>
<TargetFramework>net462</TargetFramework>
<!--<RuntimeIdentifier>win7-x86</RuntimeIdentifier>-->
<RuntimeIdentifier>win10-x64</RuntimeIdentifier></PropertyGroup>
And I enable the 64-bit version of IIS Express.
I had problems like these when I restored stuff to a new laptop.
I mindlessly I copied files from my old profile directory to a directory with the same name, but that isn’t a profile directory on the new machine.
A part of this process involved a cloud backup service that my wife bought for me but that I never actually set up right. That also copied files to new locations without my paying attention to what was happening.
I still don’t know (yet) exactly how the machine keeps track of which versions of frameworks and tools to use in the various application directories, but I can report what I did that finally allowed me to create new .NET Core apps on the new machine.
I deleted everything in this directory that was older than today.
%USERPROFILE%.nuget\packages
Again, pretty mindless. I don’t know, (yet) if all that was necessary. Maybe just deleting one or two of the files/directories would have worked. Regardless, I was very happy to see that I could create and develop .NET Core apps on my new machine.

Creating a .NET application without the entire framework?

I am in the process of creating a lightweight application in vb.NET, and was wondering if it is possible to create an application that uses some of the dll's within the .NET 2.0 framework, without actually using the framework itself.
For instance, can I take the dlls from the .NET directory that the app will reference (and only those dlls that it references), put them into a folder inside the app's directory, and then just change the reference path to that new location? That way, when the app is installed on pc's without .net framework installed, the dlls can just be zipped and copied over to the newly installed app directory.
This may all sound a bit confusing, just let me know if you need any more info.
It is quite unlikely that you'll be able to do that.
There is this thing called .net framework client profile for creating lightweight .net apps that do not need the whole framework but you still need to have that installed.
I would recommend using something like Delphi if you need a standalone exe that does not depend on anything.
There is concept of Client Profile in .NET 3.5 and .NET 4.
That is subset of .NET, smallest necessary fraction of .NET that client must have in order to be able to run .NET applications targeting client profile.
There is more detailed overview of the features you may use when targeting client profile.
Unless you move to .Net 4 or above, you need full framework on the client computers. Having said that, which OS are you targeting? Newer MS OS often come with .Net framework installed already.

Why can't my .NET 4.5 project use a DLL compiled for .NET 4? (Both use EF 5)

I have an application that consists of a client-side application and a WebApi website.
My client-side stuff is targetting .NET 4 so that I don't have to insist that users install .NET 4.5. My website, however, is entirely under my control, so I'm targetting .NET 4.5.
There is one shared assembly, which I use for data access. It uses Entity Framework 5.
When I build the client application, the DLL used is version 4.4.xxx, whereas when I build the web application, the DLL is 5.0.xxx.
Up until now, I've been able to run the client application with no problems, and I've also been able to run the web application, again without problems.
However, I've now re-created my web application project from scratch (*), and suddenly I can't run it. I get a YSOD saying "Could not load file or assembly 'EntityFramework, Version=4.4.0.0 ..." at the point where my data-access assembly is first invoked.
Now, it's perfectly clear what that error means - it can't find the v4.4 DLL as used by the data-access assembly - but I don't understand why that's a problem with my new project when it wasn't a problem with my old project. As far as I can see, the same DLLs are referenced in each project.
(*) I should explain why I'm re-creating my project. I originally created the project in VS 2012 RC, and then later upgraded to the release version. Although this supposedly upgraded my project, I've had a few problems with it, and have also noticed some differences v. a newly-created project. So, to be on the safe side - and hopefully circumvent those other problems - I'm re-creating it from scratch.
So, my question: why is this suddenly a problem, and what can I do to resolve it?
Is the code depending on the assemblies set to require the exact version? If so, you will need a publisher policy for the EntityFramework assembly or bindingRedirect for the referencing application (web project).

WIX CustomAction loading CLR 4.0 instead of 2.0

I'm trying to write a c# custom action and using .Net 2, however I can't seem to get things to work. I believe the MSI is using the wrong CLR version. I see this in the log file a few lines above where the MSI is calling my CA (line line does not appear if I comment out my CA):
SFXCA: Binding to CLR version v4.0.30319.
My custom action does not appears to load (assuming since I do not see any of the logging messages). I am using Wiz 3.6.3014.0. Is this supported or does the Windows Installer just use the latest runtime available on the machine?
Thanks
When you use WiX to create a C# custom action project, it by default creates an XML file called CustomAction.config. The purpose of this file is to instruct sfxca.dll what version of the CLR to use when running your code. The default implementation of this file looks like:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<!--
Use supportedRuntime tags to explicitly specify the version(s) of the .NET Framework runtime that
the custom action should run on. If no versions are specified, the chosen version of the runtime
will be the "best" match to what Microsoft.Deployment.WindowsInstaller.dll was built against.
WARNING: leaving the version unspecified is dangerous as it introduces a risk of compatibility
problems with future versions of the .NET Framework runtime. It is highly recommended that you specify
only the version(s) of the .NET Framework runtime that you have tested against.
Note for .NET Framework v3.0 and v3.5, the runtime version is still v2.0.
In order to enable .NET Framework version 2.0 runtime activation policy, which is to load all assemblies
by using the latest supported runtime, #useLegacyV2RuntimeActivationPolicy="true".
For more information, see http://msdn.microsoft.com/en-us/library/bbx34a2h.aspx
-->
<supportedRuntime version="v4.0" />
<supportedRuntime version="v2.0.50727"/>
</startup>
<!--
Add additional configuration settings here. For more information on application config files,
see http://msdn.microsoft.com/en-us/library/kza1yk3a.aspx
-->
</configuration>
Basically it's a good practice for CA's written in .NET 2.0/3.0/3.5 ( all CLR 2.0 ) to be allowed to run against 4.0 because you could come across a machine that has only 4.0 installed. Generally your code should work against 4.0 and if it doesn't, I'd fix that.
Alternatively you could update the config file to only allow running on 2.0 and then put the needed checks into the installer to make sure that this version of the CLR is infact installed.