为进程设置环境变量

58

什么是环境变量概念?

在一个C#程序中,我需要调用一个可执行文件。该可执行文件会调用一些与其位于同一文件夹中的其他可执行文件。这些可执行文件依赖于"PATH"和"RAYPATH"两个环境变量被正确设置。我尝试了以下两种方法:

  1. 我创建了一个进程并在StartInfo中设置了这两个变量。这些变量已经存在但缺少所需的信息。
  2. 我尝试使用 System.Environment.SetEnvironmentVariable() 方法来设置这些变量。

当我运行这个进程时,系统找不到可执行文件 ("executeable1")。我尝试将 StartInfo.FileName 设置为 "executeable1" 的完整路径 - 但是此时由 "executeable1" 中调用的 EXE 文件无法找到...

我该怎么处理这个问题?

string pathvar = System.Environment.GetEnvironmentVariable("PATH");
System.Environment.SetEnvironmentVariable("PATH", pathvar + @";C:\UD_\bin\DAYSIM\bin_windows\;C:\UD_\bin\Radiance\bin\;C:\UD_\bin\DAYSIM;");
System.Environment.SetEnvironmentVariable("RAYPATH", @"C:\UD_\bin\DAYSIM\lib\;C:\UD_\bin\Radiance\lib\");

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.WorkingDirectory = @"C:\UD_\bin\DAYSIM\bin_windows";

//string pathvar = p.StartInfo.EnvironmentVariables["PATH"];
//p.StartInfo.EnvironmentVariables["PATH"] = pathvar + @";C:\UD_\bin\DAYSIM\bin_windows\;C:\UD_\bin\Radiance\bin\;C:\UD_\bin\DAYSIM;";
//p.StartInfo.EnvironmentVariables["RAYPATH"] = @"C:\UD_\bin\DAYSIM\lib\;C:\UD_\bin\Radiance\lib\";


p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;

p.StartInfo.FileName = "executeable1";
p.StartInfo.Arguments = arg1 + " " + arg2;
p.Start();
p.WaitForExit();

2
你漏掉了前导分号。 - Harry Johnston
好的 - 添加了前导分号 - 现在可以找到并运行“executable1” - 这很棒。然而,在“executable1”内部调用的名为“form”的进程似乎仍然失败了...有什么想法吗? - timkado
1
也许你应该尝试用 cmd.exe 替换 executable1,这样你就可以看到环境是什么样子的了?这可能会给你一些线索。 - Harry Johnston
你能指导我一个好的解释,System.Environment.SetEnvironmentVariable() 和将它们放入StartInfo之间的区别是什么吗? - timkado
1
不是很确定。简短的版本:SetEnvironmentVariable更改当前进程的环境变量。这些更改可能会被子进程继承。StartInfo仅影响子进程。很可能通过设置StartInfo,子进程只获取您包含的环境变量,因此如果您以这种方式进行操作,您可能需要枚举现有的环境变量并复制它们,根据需要添加、修改或排除。 - Harry Johnston
2个回答

116

你实际上遇到了什么问题?System.Environment.SetEnvironmentVariable会更改当前进程的环境变量。如果你想更改你所创建的进程变量,只需使用EnvironmentVariables字典属性:

var startInfo = new ProcessStartInfo();

// Sets RAYPATH variable to "test"
// The new process will have RAYPATH variable created with "test" value
// All environment variables of the created process are inherited from the
// current process
startInfo.EnvironmentVariables["RAYPATH"] = "test";

// Required for EnvironmentVariables to be set
startInfo.UseShellExecute = false;

// Sets some executable name
// The executable will be search in directories that are specified
// in the PATH variable of the current process
startInfo.FileName = "cmd.exe";

// Starts process
Process.Start(startInfo);

4
在你的示例代码中,子进程只会继承单个环境变量RAYPATH吗?还是其他环境变量也会被继承?换句话说,startInfo.EnvironmentVariables是否会被“new ProcessStartInfo()”预填充? - Harry Johnston
14
所有的环境变量都是从父进程继承来的。new ProcessStartInfo()会填充这个字典。 - ken2k

6

有许多类型的环境变量,例如系统级别和用户级别。这取决于您的要求。

要设置环境变量,只需使用获取/设置方法。将变量名称和值作为参数传递,如果需要定义访问级别,则必须一起传递。要访问该值,请使用设置方法,也要传递访问级别参数。

例如,我正在定义用户级别的变量:

//For setting and defining variables
System.Environment.SetEnvironmentVariable("PathDB", txtPathSave.Text, EnvironmentVariableTarget.User);
System.Environment.SetEnvironmentVariable("DBname", comboBoxDataBaseName.Text, EnvironmentVariableTarget.User);

//For getting
string Pathsave = System.Environment.GetEnvironmentVariable("PathDB", EnvironmentVariableTarget.User);
string DBselect = System.Environment.GetEnvironmentVariable("DBname", EnvironmentVariableTarget.User);

你写道:“有许多类型的环境变量,例如系统级别和用户级别。这取决于您的需求。” <-- 看起来有三种类型 https://learn.microsoft.com/en-us/dotnet/api/system.environmentvariabletarget?view=net-7.0 用户、机器(系统)和进程。 - barlop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接