Introduction
In my workplace I use Oracle database many times. Oracle makes new database versions, and new database clients. The problem is that (mostly in company environment) we use very old, legacy softwares. And a new problem presents itself: old legacy softwares cannot work with new clients, and in 64-bit environment this is a very big problem.
For example, when we start to use a 64-bit environment we can install 64-bit Oracle client easily, but old, 32-bit compiled programs will not work any more with 64-bit Oracle clients. Of course, we can install more clients. One machine can be have many Oracle clients: both 64-bit, and/or 32-bit versions. But in reality, many programs use the "default" Oracle client. So if we have three Oracle clients on our machine how can we change the default?
This program solves this problem. We cannot set one program to use a 64-bit client and another use a 32-bit client in same time with this program. To do this, the very best way is to use Oracle Instant Client, and compile our program with instant client DLLs. Then our program will be portable.
But we can't do this with legacy business applications. We have to change the default Oracle Client and this project gives a solution to do this. This program is not a rocket science, but very, very useful. In fact, this program is very simple because we only have to change registry settings, and change environment parameters. But I think it can be interesting because it has problems: How to compile something in 32-64 bit version, and in order to write registry the program must be run in Administrator mode. So it is simple, but not very simple.
Many years ago Oracle had an application like Oracle Home Selector, but it not works with newer versions and Oracle stopped support this application. Sad, but true.
Background
This article is useful to learn:
- How to read and write registry
- How to change environment parameters, and notify Windows about this
- How to run a program in elevated privileges I.E. as administrator
- How to complie a program into 32-64 bit environment.
Useful to know this interests:
How to compile a program into 64/32 bit version
If you want to use a program in "dual" mode (64/32) you have to install Visual Studio on a 64-bit machine. You cannot compile on 32-bit machine to 64 bit environment, but you can compile 32/64 mode on a 64-bit machine.
- On Visual Studio menu click on Project
- Click on appliaction properties (last)
- Click on build
- And set the platform to Any CPU and set reference paths to Any CPU
Let us see on the picture:
How to run a program as administrator?
For this you have to create a new manifest file, and set elevated execution level
- In Solution Explorer (on the right side usually) on project row right click, and ADD a New Item
- Choose Application Manifest File
- New manifest file opens automaticly
- Change the
requestedExecutionLevel level="asInvoker" uiAccess="false"
line into requestedExecutionLevel level="requireAdministrator" uiAccess="false"
Let us see on the picture:
- And last Click Projects and click application proerties (last)
- Choose Application tab
- Choose the manifest file generated before
Let us see on the picture:
Using the code
The program is very simple. First we read the Oracle registry settings, then modify the appropriate default client settings, and write back to registry. After that we modify some environmental parameters because some programs use them. After changing environment params, we notify the Windows about changing. That's all, not difficult. The best way to see my code and my comments.
First let see how to read registry
Microsoft.Win32.RegistryKey Key = null;
String subkey = @"SOFTWARE\ORACLE";
...
Key = Registry.LocalMachine.OpenSubKey(subkey, false);
...
foreach (string item in Key.GetSubKeyNames())
{
...
keyitem.name = (string)orakey.GetValue("ORACLE_HOME_NAME", null);
...
Key.Close();
Now let see how to WRITE registry. This is very similar to reading.
Microsoft.Win32.RegistryKey Key = null;
String subkey = @"SOFTWARE\ORACLE";
...
Key = Registry.LocalMachine.OpenSubKey(subkey, true);
...
...
Key.SetValue("DEFAULT_HOME", keyitem.name, RegistryValueKind.String);
...
Key.Close();
Can be interesting how to search select an item from a list of stucture. I used Lambda expression like this:
key_sturct keyitem = KEYS.FirstOrDefault(x => x.name == defaulthome);
Let's see how to change an environmental parameter. This can link to Machine (for every user) and User (only for logged in user). In this program we use Machine environment parameters.
Environment.SetEnvironmentVariable("ORACLE_HOME", keyitem.home, EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("NLS_LANG", keyitem.nls, EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("TNS_ADMIN", tnspath, EnvironmentVariableTarget.Machine);
And last, I show how to notify Windows. After changing environment variables we have to notify Windows, except our change will be not successful. This is something like this calling: "Hey Windows! I changed some parameters, please know about it!" Something like this. To tell the true, I found this Notify method somewhere on the 'net. Unfortunately I can't remember where, and I have used it for many years. It imports shell32.dll, and call notification method, with appropriate parameters.
static extern void SHChangeNotify(HChangeNotifyEventID wEventId, HChangeNotifyFlags uFlags, int dwItem1, int dwItem2);
...
....
SHChangeNotify(HChangeNotifyEventID.SHCNE_ASSOCCHANGED, HChangeNotifyFlags.SHCNF_IDLIST, 0, 0); ...
Points of Interest
I offer this program for Oracle Client users, who met Oraclient and 64-bit/32-bit incompatibility problems. I show how to run a program "as administrator" and explained how to compile a program for any CPU (32-64-bit)
History
1.0 Version