Link to home
Start Free TrialLog in
Avatar of jmuldrum
jmuldrum

asked on

Making .NET SetEnvironmentVariable call "stick" across .NET / COM

OK, I think the title sums up what I need. I am writing a C# application (.exe) which includes an old DLL written by another segment of my company. It is in VB and simplifies calls to a third party application. This application needs an environment variable set in order to run. I did this once
a couple of years ago in C++ / COM and had no problem. I set the env variable when my code started
and all subsequent calls to the third party application worked well with the env variable set.
Now on to C#. I have used the DllImportAttribute to bring in kernel32.dll and declared my SetEnvironmentVariable() method. All appears to be ok (no compile errors, sets the env variable as checked later by GetEnvironmentVariable()). But when I make my calls to the VB dll, the third party application fails (properly, cleanly, etc) because it doesn't see this environment variable. If I just set the environment variable through the Windows control panel, the code runs fine. I figure this has to do with the Application Domains / Process  model of .NET, but I can't figure out how to work around it.

Here is the DllImport, just so you can see some code, but I don't know what else could really help...

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]      
public static extern bool SetEnvironmentVariable(string lpname, string lpvalue);

I have made direct calls to the above, and I have followed the MSDN method and called the following method:

public static bool SetEnvironmentVariableEx(string evar, string eval) {
   try {
      // Get the write permission to set the environment variable.
      EnvironmentPermission ep = new EnvironmentPermission(EnvironmentPermissionAccess.Write,evar);
      environmentPermission.Demand();
      return SetEnvironmentVariable(evar, eval);
   }
   catch( Exception e) {
      Console.WriteLine("Exception:" + e.Message);
   }
      return false;
   }

And finally, the project requires the inclusion of COMSVCSLIB.dll and does not produce a library named InterOp.XXXX.dll as many of old COM dll's do. I am still uncertain about the details of Interop, so I am not sure why this is.


Thanks for any help
--j


Avatar of AlexFM
AlexFM

Write required environment variable directlly to Registry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
using Registry .NET class.
It should be something like this:

RegistryKey regkey;
String keyValue;

keyValue = "SYSTEM\CurrentControlSet\Control\Session Manager\Environment";
regkey = Registry.LocalMachine.OpenSubKey(keyValue, True);
regkey.SetValue("Variable name", "Variable value");


Avatar of jmuldrum

ASKER

Thanks for the quick response.... I will work on that in a few minutes, but how would this affect other applications running on the same machine which would use the same env. variable but with a different value?

--j
ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I had thought about usig CreateProcess(), but this little "experiment" will eventually make its way into an application which requires a lot of data be passed. I am connecting to a wrapper for MQSeries, so  moving this data across a process boundary is something I would rather not try to do unless no other way exist. Thanks for the info. I will try to test it this morning.
In the meantime, if anything else occurs to you, let me know

Thanks
--j