Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I conditionally run my program in 64 bit or 32 bit mode based on external resources?

There are a few questions (and unwanted answers) all over the forums about Microsoft.ACE.OLEDB.12.0 provider not being registered on the local machine, like this one. The gist of the problem, how I understand it, is that the application will look for the provider on the same platform as what the application is running on. So if your computer is 64 bit and the provider 32 bit, then there will be a mismatch if you don't compile the application to run in 32 bit mode.

Most answers effectively deal with this by installing the appropriate data components for the current platform. Other suggestions are to compile for whichever platform the data components are available.

I am developing an app using PCs running Windows 7, 8 and 10, all 64 bit, depending on where I am, but some have older versions of Office and others newer versions. This causes me to have to change the platform for which I compile depending on the PC I currently work on. While this is no problem for me, personally, I foresee this causing headaches for the end users not being able to run the program.

Trying to avoid asking users to install other components on their computers; is there a way I can tell the program to check the platform availability of the database provider and then run in that mode? Might it be possible to create 32 bit and 64 bit extensions of the database module and load the appropriate one regardless of the mode the main program is running in?

EDIT:

I just tried to compile my database extensions on different platforms Whichever one that is not the same platform as the application causes an exception when being loaded saying that I am attempting to load an assembly from a different platform. So I guess I'm out of luck with my option 2...

like image 598
ChP Avatar asked Oct 30 '22 01:10

ChP


1 Answers

You can use CorFlags utility to modify your executable on target machine, after you will detect which mode it needs to run.

First ensure that your main exe is compiled under any cpu with Prefer 32 bit flag not set. Now when application is started you need to check if we are in 64-bit process or not, and also check your dependencies (this I won't cover - I don't work with OLEDB). If you found mismatch (say you are running in 64-bit process but your dependencies are 32-bit) - you need to run external process to modify your main executable and then restart it. Easiest way to do it is via simple cmd script, like this (in this example my main exe is called ConsoleApplication3.exe):

:start
start /wait "" "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\CorFlags.exe" ConsoleApplication3.exe /32BIT+
if errorlevel 1 (
    goto start
)
start "" ConsoleApplication3.exe

Note that this is just example and if something goes wrong it will fall into endless loop, adjust to your requirements. What this script does is just updates your exe using CorFlags tool to run in 32-bit mode, then starts your main exe.

Right after starting your application, you might do the following check:

static void Main() {
    if (Environment.Is64BitProcess) {
        // here you also check if you have dependency mismatch, and then:
        Console.WriteLine("Running in 64-bit mode. Press any key to fix");
        Console.ReadKey();
        // run script (here we assume script is in the same directory as main executable, and is called fix-mode.cmd
        var process = new Process() {
            StartInfo = new ProcessStartInfo("cmd.exe", "/c call fix-mode.cmd")
        };
        process.Start();                
        // here you should exit your application immediatly, so that CorFlags can update it (since it cannot do that while it is running)
    }
    else {
        // after restart by our script - we will get here
        Console.WriteLine("Running in 32bit mode");
    }
}

Note that this tool (CorFlags) is available only with Visual Studio so you may want to pack it together with your application (might be not available on remote machine).

like image 60
Evk Avatar answered Nov 15 '22 04:11

Evk