6

I have a setup project in Visual Studio 2010 that I use to create an installation kit (MSI). I need to update the environment path to add an entry when the MSI is installed. Any idea how to do that?

I can't find the option that let me access the environment. Only thing I see that might do is to directly edit the registry. Anything better I can do, or that is my only option?

Thanks Tony

tony
  • 823
  • 2
  • 16
  • 25
  • Take note of an alternative registry location to achieve the same without modifying path - https://stackoverflow.com/questions/1145231/how-can-i-make-a-program-runnable-from-the-commandline-without-typing-its-full-p – Alexei Levenkov Nov 17 '22 at 18:23

3 Answers3

5

Visual Studio setup projects cannot set environment variables. However, you can try using a custom action. Here is some sample VBScript code:

Set WshShell = CreateObject("WScript.Shell") 
Set WshEnv = WshShell.Environment("SYSTEM") 
WshEnv("Path") = WshEnv("Path") & ";myPath"

You can copy it in a .VBS file and add that file as an install custom action.

Cosmin
  • 21,216
  • 5
  • 45
  • 60
  • Hi guys, anything else needed to be done to make this work? I'm trying to do the same thing but it says that there was a problem with the script. I checked the log file and it says " Custom action _4E748D1D_9739_45AB_A63B_527713367D4F script error -2146827788, Microsoft VBScript runtime error: Variable is undefined: 'WScript'" – Mel Nov 03 '11 at 11:07
  • Are you using the exact same code? Please note that WScript cannot be used directly. You can use it only as a CreateObject parameter. – Cosmin Nov 03 '11 at 11:17
2

I had success using the Setup Project within Visual Studio (2015) and adding a custom action that altered the registry as shown in this answer:

GetEnvironmentVariable() and SetEnvironmentVariable() for PATH Variable

The following code is for a custom action that should be applied to the commit/install/and uninstall actions of a setup project:

 [RunInstaller(true)]
public partial class GRInstallCustomAction : System.Configuration.Install.Installer
{
    string environmentKey = @"SYSTEM\CurrentControlSet\Control\Session Manager\Environment";
    string pathUrl = "C:\\Program Files (86)\\TargetFolder";
    public GRInstallCustomAction()
    {
        InitializeComponent();
    }

    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Install(IDictionary stateSaver)
    {
        base.Install(stateSaver);
    }

    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Commit(IDictionary savedState)
    {
        base.Commit(savedState);

        string environmentVar = Environment.GetEnvironmentVariable("PATH");


        //get non-expanded PATH environment variable            
        string oldPath = (string)Registry.LocalMachine.CreateSubKey(environmentKey).GetValue("Path", "", RegistryValueOptions.DoNotExpandEnvironmentNames);


        var index = oldPath.IndexOf(pathUrl);
        if (index < 0)
        {
            //set the path as an an expandable string
            Registry.LocalMachine.CreateSubKey(environmentKey).SetValue("Path", oldPath + ";" + pathUrl, RegistryValueKind.ExpandString);
        }

    }

    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Rollback(IDictionary savedState)
    {
        base.Rollback(savedState);


    }

    [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
    public override void Uninstall(IDictionary savedState)
    {
        base.Uninstall(savedState);

        //get non-expanded PATH environment variable            
        string oldPath = (string)Registry.LocalMachine.CreateSubKey(environmentKey).GetValue("Path", "", RegistryValueOptions.DoNotExpandEnvironmentNames);

        string removeString = pathUrl + ";";
        var index = oldPath.IndexOf(removeString);
        if (index < 0)
        {
            removeString = pathUrl;
            index = oldPath.IndexOf(removeString);
        }

        if (index > -1)
        {
            oldPath = oldPath.Remove(index, pathUrl.Length);
            //set the path as an an expandable string
            Registry.LocalMachine.CreateSubKey(environmentKey).SetValue("Path", oldPath, RegistryValueKind.ExpandString);
        }
    }
}
Community
  • 1
  • 1
ickydime
  • 1,051
  • 10
  • 22
0

I found ickydime's answer very helpful, with the addition of the path to my executing assembly this was perfect:

string pathUrl = System.IO.Path.GetDirectoryName(this.Context.Parameters["assemblypath"]);

Lorien
  • 9
  • 2