Force .NET application to run in 32bit process on 64bit OS

Introduction

Our clients install our product on different environments. Some of them have 32bit server OS others have pure 64bit environments. Due to the lack of a 64bit version of a driver we use we have to run certain tools in 32bit mode. But since we do not want to have multiple versions of our product we had to find a possibility to force a .NET (command line) tool to run as a 32bit process on a 64bit OS (e.g. Windows Server 2003/2008).

Solutions

Set the platform target

The simplest solution is to set the Platform Target to be x86 on the project properties (build register).

image

This will cause the compiler to set the 32Bit flag in the CLR header of the corresponding assembly. Every time we run this application no matter on what type of OS it will execute as a 32bit process. But this solution although simple and straight forward was not a viable solution for us since – as mentioned above – we want to have one and only one version of our product. Thus all components of our package have to be compiled with Platform Target set to Any CPU.

Run in the context of IIS

If the application is running in the context of IIS then we can instruct IIS to run the application in a 32bit process. Of course this solution is not the right one for a command line tool…

To run a web application in 32bit mode on an 64bit OS open the IIS Manager and navigate to the application pool that the application should run in. Select the application pool and select “Advance Settings…”. In the Advanced Settings dialog set the “Enable 32-Bit Applications” to true.

image

Use corflags.exe to set the bitness

You can flip the 32-bit flag on the assembly after-the-fact using a tool called CorFlags.exe, but that’s probably not a good idea for a long-term sustainable option. For the details about how to use CorFlags.exe see this link. E.g. to set the 32Bit flag open the Visual Studio command prompt, navigate to the directory where your assembly is and use this command

CorFlags.exe MyAssembly.exe /32Bit+

and to turn off  the 32Bit flag it would be

CorFlags.exe MyAssembly.exe /32Bit-

Create a shallow wrapper application

The solution we finally adapted was to build a shallow wrapper application whose platform target is set to x86 and which does nothing else than call the respective application. As already mentioned earlier the application is a command line tool and as such has an entry point defined as follows

public class Program
{
    public static int Main(string[] args)
    {
        // ...
    }
    
    // more code
}

Our wrapper application can now reference the wrapped application and execute it by using this code

class Program32
{
    static int Main(string[] args)
    {
        return Program.Main(args);
    }
}

Since the “bitness” of the starting assembly determines the “bitness” of the process the whole application will run in a 32bit process.

But as always, having a solution makes you want to have more. What if we could create a generic 32bit wrapper application that can call any (command line) tool and force it to run in a 32bit process?

Something like this:

RunAs32Bit.exe /assembly:MyAssembly.exe /params:"/connection:Oracle1 /user:joe /numThreads:4"

What we finally came up is as simple as this

static int Main(string[] args)
{
    // load the assembly
    var directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    var assemblyName = Path.Combine(directory, args[0].Substring(10));
    var assembly = Assembly.LoadFile(assemblyName);
 
    // find the entry point of the assembly
    var type = assembly.GetTypes().FirstOrDefault(t => t.GetMethod("Main") != null);
    var mi = type.GetMethod("Main");
 
    // call the entry point of the wrapped assembly and forward the command line parameters
    var arguments = args[1].Substring(8).Split(' ');
    var list = arguments.Where(a => a.Trim() != "").ToArray();
    return (int)mi.Invoke(type, new object[] { list });
}

Note that for brevity I omitted the code to validate the command line parameters.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Gabriel Schenker

Gabriel N. Schenker started his career as a physicist. Following his passion and interest in stars and the universe he chose to write his Ph.D. thesis in astrophysics. Soon after this he dedicated all his time to his second passion, writing and architecting software. Gabriel has since been working for over 12 years as an independent consultant, trainer, and mentor mainly on the .NET platform. He is currently working as chief software architect in a mid-size US company based in Austin TX providing software and services to the pharmaceutical industry as well as to many well-known hospitals and universities throughout the US and in many other countries around the world. Gabriel is passionate about software development and tries to make the life of developers easier by providing guidelines and frameworks to reduce friction in the software development process. Gabriel is married and father of four children and during his spare time likes hiking in the mountains, cooking and reading.
This entry was posted in How To, misc. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Kevin Rollins

    Thanks for this…really helped me out trying to get my 32 bit apps to run on my Windows 7 / IIS 7.5 dev box.

  • Campbell

    Brilliant Thank-you. I took it upon myself to simplify it slightly since we have to have it run under 2.0 framework, so all I do is assembly.EntryPoint.Invoke(null, null). Then inside the existing application (‘AnyCPU’) I put an ‘if (IntPtr.Size == 4)’ check around the Main function and a Process.Start(Path.GetDirectoryName(Application.ExecutablePath) + @”\my32bit.exe”) for the ELSE. Works a treat!

  • Shubh

    I’ve got it solved for Microsoft Visual Studio 2005 –> Running on Window 7 (64 bit)

    1. Go to your Project’s property page.
    2. In ‘Compile’ tab
    3. Under ‘Advance Compile Options….”
    4. Check for ‘Target CPU’ at the bottom.
    5. Select x64 and click OK.

    Boom !! Your application is on Air now :)

  • Shubh

    I’ve got it solved for Microsoft Visual Studio 2005 –> Running on Window 7 (64 bit)

    1. Go to your Project’s property page.
    2. In ‘Compile’ tab
    3. Under ‘Advance Compile Options….”
    4. Check for ‘Target CPU’ at the bottom.
    5. Select x64 and click OK.

    Boom !! Your application is on Air now :)

  • Ataris

    No Shubh. That would give you an application running as a 64 bit process… not forcing it to run as a 32 bit proces.

    … boom.

  • MK

    Great article … Thanks a million

  • Guest

    So I copy this code into VS C# and it won’t compile, 4 errors over 3 lines.

    in the var directory line, Path and Assembly give an error – doesn’t exist in the current context. In the next two lines, Path and Assembly again give that error for each.

    Hows a guy supposed to try out some code when the published code is incomplete?

    • gabrielschenker

      you have to add the appropriate using statements to the code to make it work:
      using System.IO;

    • Dr. Guest

      The author assumed that those interested in this code snippet have at least the most basic C# programming knowledge. Here: knowing that no C# code will compile without the required using directives. I’ll leave it as an exercize for you to find out which System.* assemblies need to be referenced.

    • Sravan

      https://sites.google.com/site/kishorenetblog/asp-net/corflags-exe

      Look at this site.. You will find the answer for you Query……

      Sravan
      Hyderabad

  • Mark

    I am somewhat new at C#, I used to VB.  I have created an executable based on this code, but it fails.  When it tries to Invoke the app ends out with an error:

    Unhandled Exception: System.NullReferenceException: Object Reference not set to an instance of an object.
    at ConsoleApplication1.Program.Main(String[] args)

    Any ideas?  Any help would be greatly appreciated.

  • http://twitter.com/nggn12345 ng

    Will RunAs32Bit allow me to run a GUI based .net Application as a 32-bit application?  I am trying to run something that keeps calling the 64bit odbc driver instead of correctly looking for the 32bit one.

    • Anonymous

      Yeah, should work as well.

      • http://isitpossibleto.net/ is it possible to…

        Ive been trying to launch a winforms .net app using this, and no luck so far.. it seems to not be finding the Main function in the app? 

    • elopezrios

      Hi, when a Process is created from an 32bit image it’s not possible to use 64bits assemblies. When a process is created from 64bits image, it can’t load a 32bits DLL. It’s a Windows restriction

  • http://isitpossibleto.net/ Is it possible to…

    I like this!

  • Blake Niemyjski

    Here is another implementation.