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


jmuldrumAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AlexFMCommented:
Write required environment variable directlly to Registry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
using Registry .NET class.
0
AlexFMCommented:
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");


0
jmuldrumAuthor Commented:
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
0
AlexFMCommented:
Agree, this is not clean. Use this only if there is no othe ways.
I can think about following ways:
1) Use HKEY_CURRENT_USER instead of HKEY_LOCAL_MACHINE (user instead of system environment variable)
2) Delete it when you don't need it more
3) You can write small application which runs your own application using CreateProcess API. It allows to redefine environment variables for created process.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jmuldrumAuthor Commented:
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
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.