7

I'm a software tester. I was given an executable to test on a given machine. In the test the executable behaved strangly which could not be explained by anybody.

After a lot of research and debugging I found the cause: The executable that was built for .NET target framework 4.6, but the machine was equipped with .NET 4.5. This produced some "MissingMethodExeception" for even trivial methods like "string.Format()". Some try-catch caught these exceptions, but treated them in wrong way because nobody had expected them to occur.

A likewise issue has been described here:

Method not found: 'System.String System.String.Format(System.IFormatProvider, System.String, System.Object)

My questions:

  1. Isn't Windows meant to warn me when I'm trying to run an executable that cannot be run properly since the necessary .NET version is not available?
  2. What is the best practise to deal with this problem in general?

(I would have expected something like a checkbox "Dont execute if target network is not available" in VisualStudio?!)

Community
  • 1
  • 1
  • The application would have run just fine on 4.5, if it hadn't used a method overload that was introduced in 4.6. – stuartd Jan 18 '17 at 14:04
  • @stuartd Yes, that's the issue here. OP is asking if there's a nice easy way for a 4.6 targeted application to flag when 4.6 isn't available. Having not seen this directly myself, I too would have expected it to just flag it up as saying it needed 4.6 installed. – James Thorpe Jan 18 '17 at 14:05
  • 1
    *By default*, Visual Studio does try to keep things aligned. However, it's possible to "lie" and say that you're okay with running against a lower framework version despite being compiled against a later one. Rick Strahl wrote about doing [just that](https://weblog.west-wind.com/posts/2017/Jan/09/Faking-out-the-NET-Runtime-Version), but did warn that it can easily produce runtime errors. – Damien_The_Unbeliever Jan 18 '17 at 14:05
  • Good question, i would like to learn the answer too. – er-han Jan 18 '17 at 14:09
  • @JamesThorpe why? Because it uses a method from a later version? What if the developers added an alternate code path for earlier versions? If you **must** specify a particular .Net framework version then you need to use an installer to verify it, and prompt for download if necessary. – stuartd Jan 18 '17 at 14:09
  • @stuartd Not because it uses a method from, but because it targets a later version. Evidently it's an area I need to go read some more about - the link to Rick Strahl's blog helps somewhat. – James Thorpe Jan 18 '17 at 14:15
  • @JamesThorpe as long as the target and actual framework have the same CLR and the app doesn't use any specific functionality from the later version then it will "just work" - that's one of the "features" of the framework. Breaking it just because you specify 4.6.2 and I have 4.6.1 would be a major pain. – stuartd Jan 18 '17 at 14:22
  • @stuartd: The code in question hasn't been touched in years. It calls System.String.Format (System.IFormatProvider, System.String, System.Object) which throws that MissingMethodException. So it does not use a method overload that was introduced in 4.6. (Or I'm missing something crucial here) –  Jan 18 '17 at 14:37
  • @KommissarFahrner I read some more of the question you linked to, and I see the problem, sorry about the misunderstanding. Sounds like you need to raise a bug to get the devs to [implement the workaround](http://stackoverflow.com/a/35196605/43846) – stuartd Jan 18 '17 at 14:40
  • related? http://stackoverflow.com/questions/2310701/determine-framework-clr-version-of-assembly – rene Jan 18 '17 at 17:36

2 Answers2

0

Isn't Windows meant to warn me ...

You'll certainly should get a warning, not from Windows but from the CLR. The dialog looks like this, clicking Yes automatically gets the required framework version deployed and installed on the machine. The CLR performs this check by looking for the [TargetFramework] attribute embedded in the assembly. As noted, run ildasm.exe to verify this attribute. With the expectation that it is either missing or has a low enough value so the dialog does not trigger.

What is the best practice to deal with this problem in general?

It is procedural mistake, the assembly was built wrong. You know with high confidence that the compiler used reference assemblies that are only appropriate for .NET version 4.6. That has to be traced back to the machine that built it, most likely to be a build server. It was not setup correctly, the kind of mishap that is so common when the build engineer cut corners by avoiding using a licensed copy of Visual Studio. Or by favoring freeware tooling, Jenkins is a common scourge.

Beyond getting the [TargetFramework] attribute wrong or missing, this particular mishap is particularly easy to induce. All it takes is using the assemblies in c:\windows\microsoft.net\framework as reference assemblies instead of the proper ones that require a targeting pack and are installed in the c:\program files (x86)\reference assemblies directory. This Q+A has more leads.

Fixing a build server tends to have lots of resistance points, best thing to do as a tester is to file a bug report. You also want to write one for the broken catch-em-all exception handling that made the problem so difficult to diagnose.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks for the information. I found out that the TargetFramework attribute is correctly set in the executable. But I also found out that the state of the system I've been testing on is kind of questionable: I have to install a Windows8.1 image with .NET 4.5. During the installation updates are downloaded including .NET 4.6, but they will not be completely installed until the next reboot. My problem occurs only before the next reboot (.NET 4.6 being installed), but I will get no dialog from the CLR although the TargetFramework attribute is there in the exe. –  Jan 23 '17 at 15:02
-1

To answer the questions:

  1. No Windows is not meant to warn you that the desired .Net Framework is not installed to run this executable. However, Windows will log the error or application crash information in Windows Event Logs.

Re second question...

  1. In general, executables are delivered, deployed or published using Installers. Installer can be configured/written such that they will warn user if .Net framework(required by the exe/dll) is not installed.
Azaz ul Haq
  • 1,635
  • 2
  • 18
  • 46