System.BadImageFormatException On Win 7 / IIS 7 (IIS 6 Works Fine)

319 views
Skip to first unread message

benjamin...@gmail.com

unread,
Jun 6, 2013, 6:10:58 PM6/6/13
to cs-s...@googlegroups.com

Hi Oleg,

CS-Script Evaluator has been working great for my project on Win Server 2003 / IIS 6 environment.

I recently started running it on Windows 7 and IIS 7 and came up against this System.BadImageFormatException when calling CSScript.Evaluator.ReferenceAssembly()

If I called my ConfigureCSharpEvaluator()  with "System.Web" in the nameSpaceReferenceList, then I can see it resolves to the physical assembly C:\Windows\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll but then the exception occurs when I try to ReferenceAssembly() below

The Windows Server 2003 system is 32-bit, but the Win 7 system is 64-bit - not sure if that effects anything.

Also IIS 7 has this "Integrated" pipeline mode for Application Pools. You can select "Classic" which I imagine is the same as IIS 6. Again, not sure if that will have an impact here.

My CS-Script version is the older 3.5.0

Here's my code:

        /// <summary>
        /// Adds all namespace and assembly references to CSScript evaluator
        /// </summary>
        /// <param name="nameSpaceReferenceList">List of namespace references e.g. System.Web</param>
        /// <param name="assemblyReferenceList">List of physical assembly references</param>
        private static void ConfigureCSharpEvaluator(List<string> nameSpaceReferenceList, List<string> assemblyReferenceList)
        {
            //Dereference all name space references to physical path assembly references.
            foreach (string nameSpaceReference in nameSpaceReferenceList)
            {
                foreach (string assembly in AssemblyResolver.FindGlobalAssembly(nameSpaceReference))
                {
                    assemblyReferenceList.Add(assembly);
                }
            }

            //Add all assembly references
            foreach (string assemblyReference in assemblyReferenceList)
            {
                CSScript.Evaluator.ReferenceAssembly(assemblyReference);  //**** System.BadImageFormatException here on Win 7 / IIS 7
            }
        }

Any thoughts?


Thanks,

Ben,

benjamin...@gmail.com

unread,
Jun 6, 2013, 6:14:14 PM6/6/13
to cs-s...@googlegroups.com, benjamin...@gmail.com
Exception Text was:

System.BadImageFormatException: Could not load file or assembly 'file:///C:\Windows\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll' or one of its dependencies. An attempt was made to load a program with an incorrect format.
File name: 'file:///C:\Windows\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll'
   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.LoadFrom(String assemblyFile)
   at CSScriptLibrary.Evaluator.ReferenceAssembly(String assembly)

benjamin...@gmail.com

unread,
Jun 6, 2013, 7:03:38 PM6/6/13
to cs-s...@googlegroups.com, benjamin...@gmail.com

OK some more information here and a workaround.

The exception does have something to do with 64-bit OS.

I found if I manually changed the path to GAC_64 like this:
C:\Windows\Microsoft.Net\assembly\GAC_64\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll

...then ReferenceAssembly() works fine.


The only automatic workaround I found was to set the 'Enable 32-bit Applications' flags to true in the Application Pool that was running my Web App within IIS 7:

I wonder if there's a way to have FindGlobalAssembly() locate the 64-bit Assembly if it's running on a 64-bit OS and not the 32-bit one?

Cheers,

Ben.

Oleg Shilo

unread,
Jun 7, 2013, 1:11:41 AM6/7/13
to cs-s...@googlegroups.com
Hi Ben,

You are correct BadImageFormatException is always an indication of the "platform target" incompatibility between the host and the referenced assembly.

You have already done all the investigation work :o) and it is clear that FindGlobalAssembly (for whatever reason) locates the wrong "CPU type" assembly. The problem is that FindGlobalAssembly uses Fusion.dll (COM interface) for locating the GAC assemblies and CS-Script has no control how the assembly probing is done. 

BTW your report about Fusion returning the wrong platform type assembly is the second so far

Another arguably more convenient work around is to avoid probing the System.Web.dll with Fusion. You can do this by loading the correct assembly into the host app AppDomain prior the execution of the script. By doing so the script engine will automatically reference (for the script compilation) the all assemblies already loaded by the host application. Thus FindGlobalAssembly will not be called to resolve System.Web.dll any more.    

Loading  System.Web.dll in the host app can by done just by referencing in you code any type implemented by this assembly.

If you do not want to share host AppDomain assemblies "Evaluator.Reset(referenceDomainAssemblies: false)"
then you can always pass the exact location of the correct assembly with "Evaluator.ReferenceAssembly(string assembly)" call

And the assembly path can be obtained as follows: 
 string systemWebDll = typeof(System.Web.HttpResponse).Assembly.Location;  

Cheers,
Oleg

--
You received this message because you are subscribed to the Google Groups "CS-Script" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cs-script+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Ben Wilson

unread,
Jun 7, 2013, 2:04:54 PM6/7/13
to cs-s...@googlegroups.com, osh...@gmail.com

Hi Oleg,

Thanks for the explanation.

In my case all the DLLs I want to reference for my dynamic compiled assembly are not known at build time so I couldn't use the typeof(System.Web.HttpResponse).Assembly.Location technique to locate the correct DLL.

What I did instead was to locate the (possibly incorrect) DLL path using CSScript.Evaluator.ReferenceAssembly() and then regex replace the \GAC_32\ with \GAC_64\ in the path returned. I have a flag which says whether or not to force 32 or 64 bit dynamic reference assemblies using the regex method. This way I can configure within web.config should this issue come up on a 64-bit system.

It works well for my situation but does feel a little hacky.

Thanks again for the help.

Cheers,

Ben.
Reply all
Reply to author
Forward
0 new messages