0

I have a .NET Framework 4.6 WPF application. The problem is that if I start the application on Windows 7 with .NET Framework < 4.6 I get a pretty generic crash message that the application has stopped working.

Is there a way to prevent the application from starting if the required .NET version is not installed and instead display a more meaningful message stating that the application requires a certain .NET version to run?

My app.config file:

<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
  </startup>
</configuration>

It seems that the sku attribute is ignored and windows tries to start the application using the latest version of the .NET Framework that is present on the user's computer.

The application is deployed as a single file application with no installer, thus I cannot create a separate bootstrapper application that would check .NET version.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
MartinK
  • 45
  • 8
  • 3
    typically this check is done by the installer for the app – pm100 Feb 01 '18 at 18:03
  • Is there a reason you're not using an installer? I feel like that would be by far the easiest way. – Broots Waymb Feb 01 '18 at 18:06
  • yes, the application doesn't and cannot have an installer, due to customer request. – MartinK Feb 01 '18 at 18:07
  • 1
    Then you're probably going to need to create a second launcher program or something. Obviously if your main program isn't even launching, it's not going to be of use to you. But even then, your customer might just keep trying to launch the main app directly. – Broots Waymb Feb 01 '18 at 18:07
  • The application must be deployed as a single exe file, this was another request from the customer. – MartinK Feb 01 '18 at 18:11
  • 1
    Then I honestly don't know what you're really going to be able to do apart from either a) helping them install the right .NET version or b) Compiling the program under the framework version they have installed. If either of those aren't possible, your customer is kind of shooting themselves in the foot... – Broots Waymb Feb 01 '18 at 18:12
  • Anyway, what is then the point having `sku` attribute in the `supportedRuntime` tag if its value is ignored and the application starts even if the specified .NET version is not installed? – MartinK Feb 01 '18 at 18:16
  • @MartinK - Being that [.NET Framework 4.5+](https://www.hanselman.com/blog/NETVersioningAndMultiTargetingNET45IsAnInplaceUpgradeToNET40.aspx) are all in-place upgrades, the latest installed .NET Framework version 4+ will always be used. There is no way to override this behavior because this is baked into the design. However, something seems off because I believe you are supposed to be getting a message indicating to install at least your targeted runtime version instead of a crash. – NightOwl888 Feb 01 '18 at 18:18
  • "So an app compiled for .NET 4.5 could run on a computer with only .NET 4.0 installed. However, it would get a runtime exception if you tried to use any APIs that didn't exist in 4.0." From https://stackoverflow.com/questions/21566528/what-happens-if-i-remove-the-auto-added-supportedruntime-element – Broots Waymb Feb 01 '18 at 18:23
  • not sure if this would work, but... use @BrootsWaymb launcher app, but have you app complied as a DLL assembly and run it from the laucher as a EXE (I think you can do this). So...you only have 1 EXE that always run. it starts does it's check and then starts the "hidden app". – kenny Feb 01 '18 at 18:55
  • Maybe crazy, but if they only have NTFS drives, perhaps you can hide the second EXE in a NTFS Stream https://learn.microsoft.com/en-us/sysinternals/downloads/streams – kenny Feb 01 '18 at 19:02

1 Answers1

0

If you want your application's users to be able to use your application with .NET Framework 4.0+ installed on the target machine, you must target .NET Framework 4.0 in your application's build settings.

<PropertyGroup>
    ...
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    ...
</PropertyGroup>

It is not possible to run an application targeting .NET Framework 4.6 on a machine with only .NET Framework 4.0 installed (at least not if you use any of the APIs that have been added after .NET Framework 4.0).

Since all versions of .NET Framework above version 4.0 are in-place upgrades, the target system will always use the latest version, anyway. So, targeting .NET framework 4.0 will give you the desired behavior.

However, do note that some APIs are not available in .NET Framework 4.0 that are in 4.6, so you might need to make some changes or compromise and target .NET Framework 4.5. Keep in mind, .NET Framework 4, 4.5, and 4.5.1 are no longer officially supported by Microsoft. Targeting .NET Framework 4.5 will give you most of the APIs missing from 4.0, and will allow the user to use any version of .NET Framework 4.5+ on their system.

<PropertyGroup>
    ...
    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
    ...
</PropertyGroup>
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • Yeah, to that last point, my assumption would be that the app is using some APIs available in what is being targeted, but not available in the version of .NET on the customer's system. – Broots Waymb Feb 01 '18 at 18:33
  • Using an older .NET Framework version is a good idea. Not for the main application though, due to large amount of 4.6 dependencies. I can however create a small bootstrapper app in .NET Framework 4.0 that would check the installed .NET version. I would then merge the bootstrapper and the main application into a single file using FodyCostura. – MartinK Feb 02 '18 at 00:19