Chase Florell
Chase Florell

Reputation: 47417

How to modify $env:VARIABLES from c# cmdlets?

I'm writing a cmdlet that changes the users TEMP directory. In this cmdlet I need to also update the $env:TEMP for the current Powershell Session.

The way I'm trying to do this is by running a command from within the C#.

Here's how I'm doing it.

First I create a one line command in the custom cmdlet

string.Format("$env:TEMP = {0}", TempPath).InvokeAsPowershellScript();

Then I do all the work in the extension method.

public static class ExtensionMethods
{
    public static void InvokeAsPowershellScript(this string script)
    {
        using (var ps = PowerShell.Create())
        {
            ps.AddScript(script);
            ps.Invoke();
            ps.Commands.Clear();
        }
    }
}

Unfortunately when I run the powershell, the temp directory variable doesn't get changed.

Import-Module "myCustomCommands.dll"
Set-TempDirectory "C:\Foo"
Write-Host $env:TEMP  # outputs 'C:\TEMP'

If you're interested, here's the full cmdlet

[Cmdlet(VerbsCommon.Set, "TempDirectory"),
Description("Permanently updates the users $env:TEMP directory")]
public class SetTempDirectoryCommand : Cmdlet
{
    private const string _regKey = "HKEY_CURRENT_USER\\Environment";
    private const string _regVal = "TEMP";

    [Parameter(Position = 0, Mandatory = true)]
    public string TempPath { get; set; }

    protected override void ProcessRecord()
    {
        if ((!TempPath.Contains(":\\") && !TempPath.StartsWith("~\\")) || TempPath.Contains("/"))
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("{0} is an invalid path", TempPath);
            Console.ResetColor();
        }
        else
        {
            if (TempPath.StartsWith("~\\"))
            {
                TempPath = TempPath.Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile));
            }

            if (!Directory.Exists(TempPath))
            {
                Directory.CreateDirectory(TempPath);
            }

            Console.WriteLine("Updating your temp directory to '{0}'.", TempPath);
            Registry.SetValue(_regKey,_regVal, TempPath);

            // todo: currently not working
            string.Format("$env:TEMP = {0}", TempPath).InvokeAsPowershellScript();

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Successfully updated your TEMP directory to '{0}'", TempPath);
            Console.ResetColor();
        }
    }
}

Upvotes: 1

Views: 820

Answers (1)

Keith Hill
Keith Hill

Reputation: 202022

No need to modify the registry, you can use the Environment.SetEnvironmentVariable() method. Use the overload that takes the EnvironmentVariableTarget and use the Process target.

Upvotes: 4

Related Questions