views:

37

answers:

1

I have upgraded a C# WinForms application from Visual C# 2008 (framework 3.5) to 2010 (framework 4.0) and I'm getting runtime errors.

The application loads assemblies dynamically at runtime using Assembly.Load(filename). It is designed this way because depending on the users configuration it should load different implementations of the assembly located in different folders.

Everything works fine, except when the loaded dll has got embedded resources (bitmaps or xsd-datasets) then I get FileNotFoundException:

{"Could not find file 'FF.Fi_Stat.SKA.resources'.":null}

The assembly is called FF.Fi_Stat.SKA.dll. I do not understand this message because there are no external resources (only embedded ones) and no file with that name is generated by VS in the output directory. Any ideas?

--

More details:

This is how I load the assembly:

Assembly a = Assembly.LoadFile(assemblyFileName);

The actual loading of the assembly works, it is when I try to create an instance of a class inside the assembly that the exception occurs:

Type t = a.GetType("nameofclass");
Activator.CreateInstance(t);  //fails here

Here is the stack trace:

Exception has been thrown by the target of an invocation.
   at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   ...

The inner exception stack trace:

   at System.Reflection.RuntimeAssembly.InternalGetSatelliteAssembly(String name, CultureInfo culture, Version version, Boolean throwOnFileNotFound, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GetSatelliteAssembly(CultureInfo lookForCulture, StackCrawlMark& stackMark)
   at System.Resources.ManifestBasedResourceGroveler.GrovelForResourceSet(CultureInfo culture, Dictionary`2 localResourceSets, Boolean tryParents, Boolean createIfNotExists, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
   at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
   at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
   at System.Resources.ResourceManager.GetString(String name)
   at FF.Fi_Stat.SKA.RegForm.InitializeComponent()
   at FF.Fi_Stat.SKA.RegForm..ctor()

I now realize that the dll's that don't work has this line in InitializeComponent in common:

System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(RegForm));

However as I mentioned this was no problem with framework 3.5.

--

SOLUTION FOUND

I found out that the problem was related to how the dotnet framework tried to find localized resources and after I added the following line to AssemblyInfo.cs in my assemblies it started working again.

[assembly: NeutralResourcesLanguageAttribute("sv-SE", UltimateResourceFallbackLocation.MainAssembly)]
+1  A: 

You could try enabling logging in the the Fusion loader. I have had great success creating the DWORD value EnableLog in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion to 1. You will then get detailed loading error messages in the event log.

Martin Liversage
Thanks, I just tried this but I'm not sure how to use the information. I can see it tries to load the .resources-file of my dynamically loaded dll and not find it but it does not give any hint why it is considered a fatal error in this case, because I can also see that it tries to load non-existing .resources files of my statically linked assemblies without raising an exception about that.
Ville Krumlinde
The Fuslogvw.exe tool is the better mousetrap here, no need to hack the registry.
Hans Passant