我使用用户'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);
过程的环境变量是我'podosta'的环境变量 例如:%USERPROFILE%指向我的个人资料'podosta' 顺便说一句,%MY_NEW_VARIABLE%已创建
为什么会出现这种情况? 我需要使用RunAs启动一个应用程序,具有已运行用户的环境并向该进程添加一些额外的环境变量。
由于
答案 0 :(得分:0)
您所看到的行为基本上是MSDN上CreateProcessWithLogon
Win32函数的文档,该函数在为其他用户启动进程时使用后台工作(使用System.Diagnostics.Process
):< / p>
指向新进程的环境块的指针。如果这 参数为NULL,新进程使用从中创建的环境 由lpUsername指定的用户的配置文件。
因此,只要为新流程指定单个环境变量,就需要全部指定它们。
现在的问题是ProcessStartInfo.EnvironmentVariables
属性。一旦您第一次访问它(对于给定的ProcessStartInfo实例),它将自动填充当前用户的完整环境(ref)。
选择此行,该行在用户“podosta”的上下文中运行:
p.EnvironmentVariables.Add("MY_NEW_VARIABLE", "SOME_TEXT");
它做了两件事:
p.EnvironmentVariables
。然后将这个组合集传递给作为“myuser”启动的进程,从而获得“USERPROFILE”的“错误”(更好:意外)值。
如果您想确保将NULL
环境块传递给基础Win32函数,为了获得上面引用中描述的行为,您不能“触摸”EnvironmentVariables
属性 - 甚至没有迭代并转储它以用于记录目的。
EnvironmentVariables.Clear()
也不够。这不会将内部字段设置为null
,而CreateProcessWithLogon
函数只是传递一个空的环境块,而不是空的。
如果你没有这样做,你会得到各种有趣的行为,例如,当时正在执行的过程将具有USERPROFILE
的值,即开始该过程的用户的值等。
您可以通过p / invoke调用CreateEnvironmentBlock
,根据需要添加环境变量,然后调用CreateProcessAsUser
(也通过p / invoke),传递修改后的环境来解决这些问题。这不是一件容易的事,特别是当你想要Process
类的所有功能时,比如输出重定向等等。
ProcessStartInfo.EnvironmentVariables
属性的工作原理很不幸。