Error in VS2010 debug mode after a .NET 4.0 migration

Topics: Prism v2 - WPF 3.5, Prism v2 - WPF 4
Jan 20, 2011 at 12:14 PM
Edited Jan 21, 2011 at 7:46 AM

Hi,

I work in a WPF .NET 4.0 project with PRISM 2.0.1.0. After a migration from VS2008 / .NET 3.5 to VS2010 / .NET 4.0, i've got an error only under Visual Studio in debug or release mode. When I execute my application in the /bin folder (.exe), everything works fine.

My error occurs during modules loading phase in bootstapper. I use a DirectoryModuleCatalog to load dynamically all modules containing in a /Modules subdirectory. 

Here is my code :

        protected override IModuleCatalog GetModuleCatalog()
        {
            return new DirectoryModuleCatalog() { ModulePath = @".\Modules" }; 
        }

My stack strace under Visual Studio 2010 : 

System.BadImageFormatException was unhandled
  Message=Could not load file or assembly 'file:///C:\TNSlot1\S\S - D\src\Host\P.S.Host\bin\Debug\P.S.Host.vshost.exe' or one of its dependencies. Tentative de chargement d'un programme de format incorrect.
  Source=mscorlib
  FileName=file:///C:\TNSlot1\S\S - D\src\Host\P.S.Host\bin\Debug\P.S.Host.vshost.exe
  FusionLog==== Pre-bind state information ===
LOG: User = CA-P\nm
LOG: Where-ref bind. Location = C:\TNSlot1\S\S - D\src\Host\P.S.Host\bin\Debug\P.S.Host.vshost.exe
LOG: Appbase = file:///C:/TNSlot1/S/S - D/src/Host/P.S.Host/bin/Debug/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This is an inspection only bind.
LOG: Using application configuration file: C:\TNSlot1\S\S - D\src\Host\P.S.Host\bin\Debug\P.S.Host.exe.config
LOG: Using host configuration file: 
LOG: Using machine configuration file from c:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Attempting download of new URL file:///C:/TNSlot1/S/S - D/src/Host/P.S.Host/bin/Debug/P.S.Host.vshost.exe.
ERR: Failed to complete setup of assembly (hr = 0x8007000b). Probing terminated.

  StackTrace:
       at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
       at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
       at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks)
       at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
       at System.Reflection.Assembly.ReflectionOnlyLoadFrom(String assemblyFile)
       at Microsoft.Practices.Composite.Modularity.DirectoryModuleCatalog.InnerModuleInfoLoader.LoadAssemblies(IEnumerable`1 assemblies) in C:\Projets\My Source Codes\PRISM 2.2\CAL\Desktop\Composite\Modularity\DirectoryModuleCatalog.Desktop.cs:line 183
       at Microsoft.Practices.Composite.Modularity.DirectoryModuleCatalog.InnerModuleInfoLoader.LoadAssemblies(IEnumerable`1 assemblies)
       at Microsoft.Practices.Composite.Modularity.DirectoryModuleCatalog.InnerLoad() in C:\Projets\My Source Codes\PRISM 2.2\CAL\Desktop\Composite\Modularity\DirectoryModuleCatalog.Desktop.cs:line 86
       at Microsoft.Practices.Composite.Modularity.ModuleCatalog.Load() in C:\Projets\My Source Codes\PRISM 2.2\CAL\Desktop\Composite\Modularity\ModuleCatalog.cs:line 175
       at Microsoft.Practices.Composite.Modularity.ModuleCatalog.Initialize() in C:\Projets\My Source Codes\PRISM 2.2\CAL\Desktop\Composite\Modularity\ModuleCatalog.cs:line 343
       at Microsoft.Practices.Composite.Modularity.ModuleManager.Run() in C:\Projets\My Source Codes\PRISM 2.2\CAL\Desktop\Composite\Modularity\ModuleManager.cs:line 69
       at Microsoft.Practices.Composite.UnityExtensions.UnityBootstrapper.InitializeModules() in C:\Projets\My Source Codes\PRISM 2.2\CAL\Desktop\Composite.UnityExtensions\UnityBootstrapper.cs:line 236
       at Microsoft.Practices.Composite.UnityExtensions.UnityBootstrapper.Run(Boolean runWithDefaultConfiguration) in C:\Projets\My Source Codes\PRISM 2.2\CAL\Desktop\Composite.UnityExtensions\UnityBootstrapper.cs:line 112
       at Microsoft.Practices.Composite.UnityExtensions.UnityBootstrapper.Run() in C:\Projets\My Source Codes\PRISM 2.2\CAL\Desktop\Composite.UnityExtensions\UnityBootstrapper.cs:line 69
       at P.S.Host.App.RunBootstrapper() in C:\TNSlot1\S\S - D\src\Host\P.S.Host\App.xaml.cs:line 67
       at P.S.Host.App.OnStartup(StartupEventArgs e) in C:\TNSlot1\S\S - D\src\Host\P.S.Host\App.xaml.cs:line 48
       at System.Windows.Application.<.ctor>b__1(Object unused)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       at System.Threading.ExecutionContext.runTryCode(Object userData)
       at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.Run()
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()
       at P.S.Host.App.Main() in C:\TNSlot1\S\S - D\src\Host\P.S.Host\obj\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
       at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
       at System.Activator.CreateInstance(ActivationContext activationContext)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

In VS console, we can see two lines at the end of execution : 

A first chance exception of type 'System.BadImageFormatException' occurred in mscorlib.dll
A first chance exception of type 'System.BadImageFormatException' occurred in Microsoft.Practices.Composite.dll

With the same code, everything is OK in debug mode under VS2008 and even after migration to VS2010. .NET 4.0 seems to make some troubleshoots but i'm not sure. 

Jan 20, 2011 at 7:06 PM

Hi,

You might find this article handy as it shows a possible cause for the issue you're experiencing. As explained in Cause Section: “…if your application is compiled to target a specific platform (x86 or x64), but attempts to load and execute an assembly that targets a different platform, the BadImageFormatException will occur…”

In the other hand, you might find the Appendix D: Upgrading from Previous Versions useful, as it could give you some hints regarding the migration process.

I hope you find this information useful.

Thanks,

Miguel Bronzovic
http://blogs.southworks.net/mbronzovic

 

Jan 20, 2011 at 7:06 PM

which version of Prism are you using?

Jan 20, 2011 at 8:33 PM

Thanks for your replies. 

I'm using PRISM 1.2.0.1 with Ent Lib 5 (for Unity).

I've try to make a sample program which just create a boostrapper and load a simple module by the DirectoryModuleCatalog. Same result, same error. Tomorrow (hour of Paris), I'm gonna see your documentation and make some tests.

One more information, when I load my module by a module catalog. All works fine, no problem with VS2010 in debug mode. That's very strange... 

If you have any additionnal information, will be great. :)

Best regards

 

Jan 20, 2011 at 10:06 PM

you sure?  I see PRISM 2.2 in your error output there, reason I ask is cause there are somethings that are very different in the current release v4 and the release you appear to be using.

Jan 21, 2011 at 7:45 AM

Excuse me mvermef, I was tired last evening. ^^

I use PRISM 2.0.1.0 and for Microsoft.Practices.Unity 2.0.50727.

Jan 21, 2011 at 12:05 PM
Edited Jan 21, 2011 at 1:07 PM

I think I've found the problem for VS2010. When the DirectoryModuleCatalog parses the execution directory (before the ModulePath) to load assemblies of .exe context first, the module try to load the vshost.exe files and this assembly loading crashes.

In the PRISM source code of DirectoryModuleCatalog.cs, we can see : 

 

        /// <summary>
        /// Drives the main logic of building the child domain and searching for the assemblies.
        /// </summary>
        protected override void InnerLoad()
        {
            if (string.IsNullOrEmpty(this.ModulePath))
                throw new InvalidOperationException(Resources.ModulePathCannotBeNullOrEmpty);

            if (!Directory.Exists(this.ModulePath))
                throw new InvalidOperationException(
                    string.Format(CultureInfo.CurrentCulture, Resources.DirectoryNotFound, this.ModulePath));

            AppDomain childDomain = this.BuildChildDomain(AppDomain.CurrentDomain);

            try
            {
                List<string> loadedAssemblies = new List<string>();

                var assemblies = (
                                     from Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()
                                     where !(assembly is System.Reflection.Emit.AssemblyBuilder)
                                           && !String.IsNullOrEmpty(assembly.Location)
                                     select assembly.Location
                                 );

                loadedAssemblies.AddRange(assemblies);

                Type loaderType = typeof (InnerModuleInfoLoader);

                if (loaderType.Assembly != null)
                {
                    var loader =
                        (InnerModuleInfoLoader)
                        childDomain.CreateInstanceFrom(loaderType.Assembly.Location, loaderType.FullName).Unwrap();
                    loader.LoadAssemblies(loadedAssemblies);
                    this.Items.AddRange(loader.GetModuleInfos(this.ModulePath));
                }
            }
            finally
            {
                AppDomain.Unload(childDomain);
            }
        }

 

The method LoadAssemblies crashes with a list of assemblies which contains the vshost.exe file.

I've try to replace this code by an assembly loading one by one and with an exclusion of vshost.exe file and all works fine : 

 

                    var loader =
                        (InnerModuleInfoLoader)
                        childDomain.CreateInstanceFrom(loaderType.Assembly.Location, loaderType.FullName).Unwrap();

                    foreach (var assemblyToLoad in loadedAssemblies)
                    {
                        try
                        {
                            if (!assemblyToLoad.EndsWith("vshost.exe"))
                            {
                                List<string> test = new List<string>();
                                test.Add(assemblyToLoad);
                                loader.LoadAssemblies(test);
                            }
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.StackTrace.ToString());
                        }
                    }
    
                    this.Items.AddRange(loader.GetModuleInfos(this.ModulePath));

 

What is the particularity of the vshost.exe file under VS2010 / .NET 4.0 ? Why this file is not correctly loaded with VS2010 / .NET 4.0?

Jan 21, 2011 at 4:50 PM

Hi,

The vshost.exe, as shown in the MSDN documentation “…is a feature in Visual Studio that improves debugging performance...”. It´s only purpose is just to help when debugging applications, so that is the reason why when you load your application from the bin folder, you don´t get any exception.

Therefore, one possibility would be that after the migration, some referenced assemblies didn´t update correctly. You could try cleaning and rebuilding your solution, and also removing the references of your projects and adding them again, so as to make sure that there are no old references to .NET 3.5 assemblies in your application, which could cause this kind of problem.

Let me know if this information helps you.

Thanks,

Miguel Bronzovic
http://blogs.southworks.net/mbronzovic

 

Jan 21, 2011 at 5:23 PM
Edited Jan 21, 2011 at 5:28 PM

I think the problem is a more generic.

I've download PRISM 4.0 source codes and I've tried to modify the Hello word sample with a DirectoryModuleCatalog. And same problem. :-)

Here is my sample if you want to try : http://dl.free.fr/i6FntlBGP

Developer
Jan 25, 2011 at 5:00 PM

Hi,

I've checked the sample you've uploaded, and I've found that if I run it as is, no exception is thrown, but if I replace the references to the compiled Prism assemblies I experience the exception you're mentioning.

After examining your solution, I've found that you weren't copying the latest build of your module into the Modules folder. Therefore, when you change the references to the compiled Prism assemblies to the projects, you experience that exception because you're trying to load a different version of the Microsoft.Practices.Prism assembly.

You could use a post build event to your module, so that it is copied to the Modules folder you are getting your modules from.

I hope you find this helpful.

Guido Leandro Maliandi
http://blogs.southworks.net/gmaliandi

Jan 26, 2011 at 8:05 AM
Edited Jan 26, 2011 at 8:06 AM

Hi,

Thanks a lot for your response.

I've already set a post build event to copy the last module version in the output dIrectory. For my sample, COPY $(ProjectName).* "$(SolutionDir)\HelloWorld.Desktop\$(OutputPath)Modules\". With this post build event, I get the same error.

I don't understand why. Maybe, my VS2010 configuration is corrupted (company configuration). When I try my sample at home (with my personnal VS2010, I don't have this error, very strange...).