none
.NET CLR on Vista 64-bit loading a 64-bit DLL in a 32-bit process space RRS feed

  • Question

  • I have an installer executable which is 32-bit that creates and invokes methods within a .NET assembly. This .NET assembly is targetted for 32-bit platform. Also, specifically it has a dependency on the .NET System.Data.dll. The problem is that when the System.Data.dll is loading during the run of my installer executable, the .NET CLR loads the 64-bit version of mscoree.dll, which I believe is a dependency for the System.Data.dll assembly. Obviously this causes a BadImageFormatException in my executable. My question now is that "How do I force the assembly loader in the CLR to load only 32-bit dependencies for the installer executable?"  
    • Moved by YiChun Chen Monday, February 8, 2010 9:37 AM CLR issue (From:Visual Studio Setup and Installation)
    Friday, February 5, 2010 9:58 PM

Answers

  • The problem is that by the time System.data.ni.dll and system.data.dll are loaded, on Vista 64-bit an assumption is made that they were accessed from a 64-bit executable since both of these DLLs were compiled with "Any CPU" set as target platform. Based on this assumption, the 64-bit version of the CLR runtime engine, mscoree.dll is loaded. Obviously, this results in a BadImageFormatException been thrown.
    CLR will never try to load 64-bit assembly in 32-bit process. Even though the DLLs are marked as "Any CPU". Something else (a native component) had to force loading of the 64-bit assemblies into the process. Noone should really do this, so it is a bug in that native component which tries it.

    Sure all this under assemption that you didn't discover a rare bug in .NET (which is unlikely, but possible).

    -Karel
    • Marked as answer by SamAgain Friday, February 12, 2010 11:41 AM
    Thursday, February 11, 2010 9:06 PM
    Moderator

All replies

  • Hi Edo,

    I am moving this thread from Base "Visual Studio Setup and Installation" forum to the "Common Language Runtime" forum, since the issue is related to CLR. There are more CLR experts in the "Common Language Runtime" forum.

    Thanks

    Best regards,
    Yichun Chen
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, February 8, 2010 9:35 AM
  • I think your .NET assembly is not really targetting 32-bit platform. Verify that in Visual Studio (or on compiler command line), or use corflags.exe tool.

    Each process is either 32-bit or 64-bit. If you run managed executable, it will run by default in 64-bit process (when you use 'Any CPU' in VS), unless you explicitly target x86 platform.
    Once you have a process, then you can load only assemblies of that bitness (or 'Any CPU' assemblies as they can run on both platforms).

    -Karel

    Monday, February 8, 2010 5:36 PM
    Moderator
  • Hi Karel,
       My .NET assembly is explicitly targeting 32-bit platform. Let me clarify that the issue is with System.Data.ni.dll assembly. After, the CLR loads this assembly, it attempts to load mscoree.dll, which I believe is a dependency for System.data.ni.dll. But it loads it from the System32 folder on my 64-bit machine. This is where a mix match in bitness is introduced, and the badImageformatexception is thrown. Bear in mind that System.data.ni.dll is of the right bitness but its dependency, mscoree.dll is not. Please, could you let me know how to get the CLR to load mscoree.dll from the SysWoW64 folder?

    Here is a pasted snapshot from process monitor window, showing what I'm trying to explain above:

    11:52:50.3345373 AM    setup.exe    4808    QueryOpen    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    FAST IO DISALLOWED   
    11:52:50.3347558 AM    setup.exe    4808    CreateFile    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.3348730 AM    setup.exe    4808    QueryBasicInformationFile    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    CreationTime: 4/24/2009 10:15:05 AM, LastAccessTime: 4/24/2009 10:15:05 AM, LastWriteTime: 7/27/2008 11:03:15 AM, ChangeTime: 2/5/2010 12:50:58 PM, FileAttributes: A
    11:52:50.3349277 AM    setup.exe    4808    CloseFile    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS   
    11:52:50.3353466 AM    setup.exe    4808    CreateFile    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    Desired Access: Generic Read, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.3354935 AM    setup.exe    4808    CreateFileMapping    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    FILE LOCKED WITH ONLY READERS    SyncType: SyncTypeCreateSection, PageProtection:
    11:52:50.3357760 AM    setup.exe    4808    CreateFileMapping    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    SyncType: SyncTypeOther
    11:52:50.3374829 AM    setup.exe    4808    Load Image    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    Image Base: 0x64e70000, Image Size: 0x2d4000
    11:52:50.3375632 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    Name: \Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll
    11:52:50.3378493 AM    setup.exe    4808    CreateFile    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    Desired Access: Generic Read, Disposition: Open, Options: Synchronous IO Non-Alert, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.4115640 AM    setup.exe    4808    Load Image    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    Image Base: 0x81b0000, Image Size: 0x2d4000
    11:52:50.4115942 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    Name: \Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll
    11:52:50.4116898 AM    setup.exe    4808    CreateFile    C:\Windows\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll    SUCCESS    Desired Access: Generic Read, Disposition: Open, Options: Synchronous IO Non-Alert, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.4329048 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4329474 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4333011 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4333432 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4357917 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4380412 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4406348 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4411727 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4417266 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4428585 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll    SUCCESS    Name: \Windows\Microsoft.NET\Framework\v2.0.50727\mscorrc.dll
    11:52:50.4432619 AM    setup.exe    4808    QueryOpen    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    FAST IO DISALLOWED   
    11:52:50.4433360 AM    setup.exe    4808    CreateFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.4433800 AM    setup.exe    4808    QueryBasicInformationFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    CreationTime: 2/8/2010 11:05:53 AM, LastAccessTime: 2/8/2010 11:05:53 AM, LastWriteTime: 2/8/2010 11:05:54 AM, ChangeTime: 2/8/2010 11:05:54 AM, FileAttributes: A
    11:52:50.4433988 AM    setup.exe    4808    CloseFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS   
    11:52:50.4435259 AM    setup.exe    4808    CreateFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    Desired Access: Read Data/List Directory, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: n/a, ShareMode: Read, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.4435704 AM    setup.exe    4808    CreateFileMapping    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    FILE LOCKED WITH ONLY READERS    SyncType: SyncTypeCreateSection, PageProtection:
    11:52:50.4436739 AM    setup.exe    4808    CreateFileMapping    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    SyncType: SyncTypeOther
    11:52:50.4438834 AM    setup.exe    4808    Load Image    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    Image Base: 0x6cc50000, Image Size: 0x785000
    11:52:50.4439145 AM    setup.exe    4808    CloseFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS   
    11:52:50.4440196 AM    setup.exe    4808    QueryOpen    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    FAST IO DISALLOWED   
    11:52:50.4440905 AM    setup.exe    4808    CreateFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.4441284 AM    setup.exe    4808    QueryBasicInformationFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    CreationTime: 2/8/2010 11:05:53 AM, LastAccessTime: 2/8/2010 11:05:53 AM, LastWriteTime: 2/8/2010 11:05:54 AM, ChangeTime: 2/8/2010 11:05:54 AM, FileAttributes: A
    11:52:50.4441471 AM    setup.exe    4808    CloseFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS   
    11:52:50.4442505 AM    setup.exe    4808    CreateFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    Desired Access: Read Data/List Directory, Execute/Traverse, Synchronize, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: n/a, ShareMode: Read, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.4442885 AM    setup.exe    4808    CreateFileMapping    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    FILE LOCKED WITH ONLY READERS    SyncType: SyncTypeCreateSection, PageProtection:
    11:52:50.4443657 AM    setup.exe    4808    CreateFileMapping    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    SyncType: SyncTypeOther
    11:52:50.4443998 AM    setup.exe    4808    CloseFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS   
    11:52:50.4445459 AM    setup.exe    4808    Load Image    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    Image Base: 0x6cc50000, Image Size: 0x785000
    11:52:50.4445923 AM    setup.exe    4808    QueryNameInformationFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    Name: \Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll
    11:52:50.4446733 AM    setup.exe    4808    CreateFile    C:\Windows\assembly\NativeImages_v2.0.50727_32\System\87f0066e657b362400985e3ad6d28c5a\System.ni.dll    SUCCESS    Desired Access: Generic Read, Disposition: Open, Options: Synchronous IO Non-Alert, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.4540415 AM    setup.exe    4808    QueryOpen    C:\Windows\System32\mscoree.dll    FAST IO DISALLOWED   
    11:52:50.4541114 AM    setup.exe    4808    CreateFile    C:\Windows\System32\mscoree.dll    SUCCESS    Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
    11:52:50.4541967 AM    setup.exe    4808    QueryBasicInformationFile    C:\Windows\System32\mscoree.dll    SUCCESS    CreationTime: 4/24/2009 10:15:03 AM, LastAccessTime: 4/24/2009 10:15:03 AM, LastWriteTime: 7/27/2008 11:01:52 AM, ChangeTime: 12/9/2009 10:13:26 AM, FileAttributes: A
    11:52:50.4542149 AM    setup.exe    4808    CloseFile    C:\Windows\System32\mscoree.dll    SUCCESS   

    Monday, February 8, 2010 7:25 PM
  • Using process monitor to track the events that are taking place as my installer executable is been run,  I've figured out what was wrong. As stated above my installer executable,  which is 32-bit loads the 32-bit .NET assembly and uses functionalities - which are basically for managing databases within a server. The problem is that by the time System.data.ni.dll and system.data.dll are loaded, on Vista 64-bit an assumption is made that they were accessed from a 64-bit executable since both of these DLLs were compiled with "Any CPU" set as target platform. Based on this assumption, the 64-bit version of the CLR runtime engine, mscoree.dll is loaded. Obviously, this results in a BadImageFormatException been thrown.

    The solution that I came up with was to reference a class within the System.Data.dll assembly in the constructor of the class within my custom assembly that is been created. This forced the CLR, to jit the System.Data.dll assembly as a 32-bit native image.


    Thursday, February 11, 2010 8:10 PM
  • The problem is that by the time System.data.ni.dll and system.data.dll are loaded, on Vista 64-bit an assumption is made that they were accessed from a 64-bit executable since both of these DLLs were compiled with "Any CPU" set as target platform. Based on this assumption, the 64-bit version of the CLR runtime engine, mscoree.dll is loaded. Obviously, this results in a BadImageFormatException been thrown.
    CLR will never try to load 64-bit assembly in 32-bit process. Even though the DLLs are marked as "Any CPU". Something else (a native component) had to force loading of the 64-bit assemblies into the process. Noone should really do this, so it is a bug in that native component which tries it.

    Sure all this under assemption that you didn't discover a rare bug in .NET (which is unlikely, but possible).

    -Karel
    • Marked as answer by SamAgain Friday, February 12, 2010 11:41 AM
    Thursday, February 11, 2010 9:06 PM
    Moderator
  • Hi Karel,
        I really do not know the source of the error, whether it's the CLR, the OS or my 32-bit installshield installer executable, but, some component within this category caused a bitness mismatch that had taken me and my team almost 2 months of digging and seeking for a solution to the badimageformatexception. Well...I'm very glad it's over.
    Kind Regards

    -Osa E
    Friday, February 12, 2010 3:06 PM
  • I think your .NET assembly is not really targetting 32-bit platform. Verify that in Visual Studio (or on compiler command line), or use corflags.exe tool.

    Each process is either 32-bit or 64-bit. If you run managed executable, it will run by default in 64-bit process (when you use 'Any CPU' in VS), unless you explicitly target x86 platform.
    Once you have a process, then you can load only assemblies of that bitness (or 'Any CPU' assemblies as they can run on both platforms).

    -Karel


    Could you give more explanation on it? Could you provide some related articles? Thanks very much!
    Sunday, October 10, 2010 4:16 AM