Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 向ProcessStartInfo.LoadUserProfile启动的进程添加新的环境变量_C#_Environment Variables - Fatal编程技术网

C# 向ProcessStartInfo.LoadUserProfile启动的进程添加新的环境变量

C# 向ProcessStartInfo.LoadUserProfile启动的进程添加新的环境变量,c#,environment-variables,C#,Environment Variables,我已使用用户“podosta”登录我的电脑 这工作正常 ProcessStartInfo p = new ProcessStartInfo("c:\myapp.exe"); p.UserName = "myuser"; p.Domain = "mydomain"; p.Password = SecureString; p.UseShellExecute = false; p.LoadUserProfile = true; Process.Start(p); 流程的环境变量是用户“myuser”

我已使用用户“podosta”登录我的电脑

这工作正常

ProcessStartInfo p = new ProcessStartInfo("c:\myapp.exe");
p.UserName = "myuser";
p.Domain = "mydomain";
p.Password = SecureString;
p.UseShellExecute = false;
p.LoadUserProfile = true;
Process.Start(p);
流程的环境变量是用户“myuser”的环境变量
例如:%USERPROFILE%指向“myuser”的配置文件

这不起作用

ProcessStartInfo p = new ProcessStartInfo("c:\myapp.exe");
p.UserName = "myuser";
p.Domain = "mydomain";
p.Password = SecureString;
p.UseShellExecute = false;
p.LoadUserProfile = true;
p.EnvironmentVariables.Add("MY_NEW_VARIABLE", "SOME_TEXT");
Process.Start(p);
流程的环境变量是me‘podosta’的环境变量
示例:%USERPROFILE%指向我的个人资料“podosta” 顺便说一下,创建了%MY\u NEW\u VARIABLE%

为什么会有这种行为?
我需要用RunAs启动一个应用程序,拥有运行用户的环境,并向流程中添加一些额外的环境变量


谢谢

您看到的行为基本上是
CreateProcessWithLogon
Win32函数的文档打开,该函数在为其他用户启动进程时在后台工作(使用
System.Diagnostics.process
):

指向新进程的环境块的指针。如果这 参数为NULL时,新进程使用从中创建的环境 由lpUsername指定的用户的配置文件

因此,只要为新流程指定一个环境变量,就需要将它们全部指定

现在的问题是
ProcessStartInfo.EnvironmentVariables
属性。一旦您第一次访问它(对于ProcessStartInfo的给定实例),它将自动填充当前用户的完整环境()

以在用户“podosta”上下文中运行的这一行为例:

它做两件事:

  • p.EnvironmentVariables
    中填充“podosta”环境(包括“USERPROFILE=…podosta”)
  • 添加新变量“MY_new_variable=SOME_TEXT”
  • 然后将这个组合的集合传递给作为“myuser”启动的进程,从而获得“USERPROFILE”的“错误”(更好:意外)值

    如果要确保将
    NULL
    环境块传递给底层Win32函数,以获得上面引号中描述的行为,则永远不能“触摸”
    EnvironmentVariables
    属性,甚至不能为日志目的对其进行迭代和转储

    执行
    环境变量.Clear()
    也是不够的。这不会将内部字段设置为
    null
    ,而
    CreateProcessWithLogon
    函数只是传递了一个空的环境块,但不是null块

    如果您没有做到这一点,就会出现各种有趣的行为,例如,正在执行的流程将有一个
    USERPROFILE
    值,即启动流程的用户的值,等等

    您可以通过p/invoke调用
    CreateEnvironmentBlock
    ,根据需要添加环境变量,然后调用
    CreateProcessAsUser
    (也可以通过p/invoke),传递修改后的环境来绕过这些问题。这并非易事,尤其是当您需要
    进程
    类的所有特性,如输出重定向等时


    不幸的是,
    ProcessStartInfo.EnvironmentVariables
    属性的工作方式是这样的。

    无法访问,因为它不在那里,或者因为它的值错误而无法访问?改为启动cmd.exe进行故障排除。我编辑了我的问题。您是对的,应用程序可以访问env变量,但其值错误。哇,几年后:-)我的解决方案是“只要为新流程指定一个环境变量,您就需要将它们全部指定。”。但我当然接受你的回答,因为这种行为已经被清楚地解释了。
    p.EnvironmentVariables.Add("MY_NEW_VARIABLE", "SOME_TEXT");