1

We have a hybrid VB6/Net application in which the Net dll's are hooked up to the VB6 code using a Com Visible Net wrapper. This wrapper in its turn is activated using RegFreeCom with manifests. This setup is working for us for over 2 years. To reduce application startup time we precompile the Net dll's using NGen after installation. This takes easily a minute to complete. Now we have a new VB6 executable, with new dll's and new manifests, but it seems that the new dll's are not used when we install the program to the existing location, thereby replacing the dll's. A new installation to a different folder does use the new dll's. I checked both the program folders and the new dll's and manifestss are there in both locations. How is it possible that the new dll's are not picked up in the existing program location and Windows seems to keep using the pregenerated code from the previous version?

I did notice that NGenning completes in just a few seconds with the statement that the compiled images are up to date, which they obviously are not. Is changing the version number of the dll's not enough to trigger the creation of new images? Currently we do not digitally sign the dlls.

Dabblernl
  • 15,831
  • 18
  • 96
  • 148
  • When uninstalling the old dll, did you also remove its NGen cache? – Lex Li Feb 19 '15 at 09:14
  • Are you changing the version numbers of the DLLs? That's kind of a key part of using NGen, along with strong naming. – Luaan Feb 19 '15 at 09:17
  • @LexLi We do not uninstall the old dlls, we just overwrite them. – Dabblernl Feb 19 '15 at 10:17
  • @Luaan We do change the version number but do not use strong names – Dabblernl Feb 19 '15 at 10:18
  • @Dabblernl Really? NGen shouldn't work at all without a strong named assembly. In any case, yeah, that's probably the problem. The only way the CLR can verify the identity of the DLL is by its path in your case - you need to use a (unique) version and strong naming. You're just seeing another case of the good old DLL hell that strong naming (and .NET overall) was designed to solve :) – Luaan Feb 19 '15 at 10:21
  • I'm also quite surprised you're getting visible benefits from NGenning. Is your application preloading everything during startup? I've worked with many complex .NET applications and NGenning wasn't ever a significant performance boost - IL code is only compiled when it's needed, so unless you're writing old-school procedural code, it doesn't make much of a difference in practice. If your code is all composed of public static fields and huge init methods, on the other hand... – Luaan Feb 19 '15 at 10:25
  • @Luaan It is certainly so that the VB6 application pauses for a considerable amount of time the first time that any Net code is accessed. We used to remedy that by calling the most used Net functions at application start up. Now that the migration has progressed to a point that the Net code is larger than the VB6 code base, the time involved at application startup is unacceptable. – Dabblernl Feb 19 '15 at 10:49
  • "Overwriting" is always a bad action in this case. You should first [remove the NGen image](https://msdn.microsoft.com/en-us/library/6t9t5wcf(v=vs.110).aspx), and then delete the original file. After that you can install the new dll and NGen it. – Lex Li Feb 19 '15 at 12:32
  • @LexLi I will try the uninstall/install route. – Dabblernl Feb 19 '15 at 14:17
  • @LexLi First uninstalling then installing did the trick in so far that the images are generated for every new install. There was another problem though: the bussineslayer dll had been misplaced by a previous installer and got priority in the search path over the later ones. It does seem that the resolution of the dependencies does not look at the version numbers If you make the uninstall option your answer I will accept it.. – Dabblernl Feb 19 '15 at 23:16

2 Answers2

1

After calling NGen to process an assembly, .NET Framework leaves a cached version in the native image cache that the program tries to load by default, instead of your assembly. Thus, replacing the old assembly with a new one won't affect your program.

By calling NGen to uninstall the cached version, your new assembly can be seen by the program and everything starts to work.

More technical details can be found over the internet, such as

https://blogs.msdn.microsoft.com/clrcodegeneration/2010/04/27/ngen-getting-started-with-ngen-in-visual-studio/

Lex Li
  • 60,503
  • 9
  • 116
  • 147
  • This article doesn't seem to exist anymore unfortunately, microsoft documentation also points here. – SomeInternetGuy Mar 27 '18 at 12:03
  • @JamesLaPenn links won't live forever, so I summarized the core information as the answer already. Changed to another blog post, which provides similar background details. – Lex Li Mar 27 '18 at 13:27
1

There are too many possible mistakes you could have made, your question doesn't help narrow it down. You could have forgotten to update the type library reference in your VB6 project, a type library only supports a major.minor version number, a copy might exist in the GAC, there might be stray registry entries, your manifest might not be used at all, it could be a simple deployment oops, you might have incremented the wrong assembly attribute (like AssemblyFileVersion). Etcetera.

You need to use diagnostic tools to see what is really going on so you can narrow down the possible reasons:

  • The sxstrace.exe utility shows how the manifest is getting parsed.
  • The fuslogvw.exe utility shows you how assemblies are located. Configure it to log all binds in this case since you don't get a bind failure.
  • Also with fuslogvw.exe, you can see it binding the native images. Select the "Native Images" radio button in the Log Categories groupbox.
  • The SysInternals' Process Monitor utility is the weapon of choice to diagnose registry and file system mishaps. You'll see exactly how the VB6 app reads keys and locates files.
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536