我正在为我的程序创建一个Visual Studio 2008安装向导。我发现可以添加注册表项等操作。但是,是否有可能在不编写自定义操作的情况下注册Windows环境变量呢?如果必须编写自定义操作,那么最简单的方法是什么?
http://support.microsoft.com/kb/307353
http://support.microsoft.com/kb/307353
警告:
请勿使用此方法
,它很危险。请使用内置的MSI功能更新环境变量。示例: 直接写入
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
-Path
会清除已有的内容。非常严重。解决方案: MSI功能提供了Environment表,以可靠的方式促进合并和更新环境变量。请注意,该表也足够复杂,可能会触发意外结果。请进行充分测试。特别是卸载方案。
1)
** 使用系统还原,**2)
** 尝试上次已知的好状态?**3)
** 使用Process Explorer => 环境选项卡从尚未重新启动的EXE文件中获取缓存的PATH,**4)
** 从具有相同软件包配置的类似SOE机器复制PATH,**5)
** 通过注册表中的ControlSet001(或更高版本)进行恢复。这就是我所记得的全部内容。 - Stein Åsmul [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);
}
}
}
本教程将向您展示如何创建和应用自定义操作: https://msdn.microsoft.com/zh-cn/library/d9k65z2d(v=vs.100).aspx
注:此链接为中文版。Ickydime(请参见上面的答案)的自定义操作示例显示了如何通过扩展PATH env变量来添加环境变量。下面我将分享如何使用Environment.SetEnvironmentVariable
创建一个新的环境变量。
string environmentKey = "MY_VAR";
string pathUrl = "%ProgramFiles%\\...";
public Installer1()
{
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);
Environment.SetEnvironmentVariable(environmentKey, pathUrl, EnvironmentVariableTarget.Machine);
}
[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);
Environment.SetEnvironmentVariable(environmentKey, null, EnvironmentVariableTarget.Machine);
}