Set ProcessStartInfo.EnvironmentVariables when Verb="runas"

user844541 picture user844541 · Aug 6, 2012 · Viewed 8.6k times · Source

I am developing a C# application.

I need to create and pass variables to a new process and I am doing it using ProcessStartInfo.EnvironmentVariables.

The new process must run elevated so I am using Verb = "runas"

var startInfo =  new ProcessStartInfo(command)
{
    UseShellExecute = true,
    CreateNoWindow = true,
    Verb = "runas"
};
foreach (DictionaryEntry entry in enviromentVariables)
{
    startInfo.EnvironmentVariables.Add(entry.Key.ToString(), entry.Value.ToString());
}

The problem is that according to the msdn documentation:

You must set the UseShellExecute property to false to start the process after changing the EnvironmentVariables property. If UseShellExecute is true, an InvalidOperationException is thrown when the Start method is called.

but the runas variable requires UseShellExecute=true

Is there a way to do both: run process as elevated and also set the environment variables?

EDIT

I will try to rephrase my question...

Is there a way to pass arguments securly to another process so only the other process will be able to read the arguments.

Answer

rene picture rene · Aug 6, 2012

It works but on the downside is that it also shows a second command prompt, the enviroment vars are only set in the context of the started process so the settings are not propagating to the whole box.

    static void Main(string[] args)
    {
        var command = "cmd.exe";
        var environmentVariables = new System.Collections.Hashtable();
        environmentVariables.Add("some", "value");
        environmentVariables.Add("someother", "value");

        var filename = Path.GetTempFileName() + ".cmd";
        StreamWriter sw = new StreamWriter(filename);
        sw.WriteLine("@echo off");
        foreach (DictionaryEntry entry in environmentVariables)
        {
            sw.WriteLine("set {0}={1}", entry.Key, entry.Value);
        } 
        sw.WriteLine("start /w {0}", command);
        sw.Close();
        var psi = new ProcessStartInfo(filename) {
            UseShellExecute = true, 
            Verb="runas"
        };
        var ps =  Process.Start(psi);
        ps.WaitForExit();
        File.Delete(filename);
    }