C# 当谓词为“时,设置ProcessStartInfo.EnvironmentVariables”;“符文”;

C# 当谓词为“时,设置ProcessStartInfo.EnvironmentVariables”;“符文”;,c#,environment-variables,processstartinfo,runas,C#,Environment Variables,Processstartinfo,Runas,我正在开发一个C#应用程序 我需要创建变量并将其传递给一个新进程,我正在使用ProcessStartInfo.EnvironmentVariables 新进程必须运行,因此我使用Verb=“runas” 问题在于,根据该报告: 更改环境变量属性后,必须将UseShellExecute属性设置为false才能启动进程。如果UseShellExecute为true,则调用Start方法时会引发invalidoOperationException 但是runas变量需要UseShellExecute=

我正在开发一个C#应用程序

我需要创建变量并将其传递给一个新进程,我正在使用
ProcessStartInfo.EnvironmentVariables

新进程必须运行,因此我使用Verb=“runas”

问题在于,根据该报告:

更改
环境变量
属性后,必须将
UseShellExecute
属性设置为false
才能启动进程。如果
UseShellExecute
为true,则调用Start方法时会引发
invalidoOperationException

但是
runas
变量需要UseShellExecute=true

是否有一种方法可以同时执行这两项操作:将流程作为提升运行,并设置环境变量

编辑

我将尝试重新表述我的问题


是否有一种方法可以将参数安全地传递给另一个进程,这样只有另一个进程才能读取参数

它可以工作,但缺点是它还显示第二个命令提示符,环境变量仅在已启动进程的上下文中设置,因此设置不会传播到整个框中

    static void Main(string[] args)
    {
        var command = "cmd.exe";
        var environmentVariables = new System.Collections.Hashtable();
        environmentVariables.Add("some", "value");
        environmentVariables.Add("someother", "value");

        var filename = Path.GetTempFileName() + ".cmd";
        StreamWriter sw = new StreamWriter(filename);
        sw.WriteLine("@echo off");
        foreach (DictionaryEntry entry in environmentVariables)
        {
            sw.WriteLine("set {0}={1}", entry.Key, entry.Value);
        } 
        sw.WriteLine("start /w {0}", command);
        sw.Close();
        var psi = new ProcessStartInfo(filename) {
            UseShellExecute = true, 
            Verb="runas"
        };
        var ps =  Process.Start(psi);
        ps.WaitForExit();
        File.Delete(filename);
    }

有一个更好的答案:您仍然可以使用使用ShellExecute=true的ProcessStartInfo调用Process.Start(),前提是您从中调用它的方法已标记为[StatThread]属性。

可能不太好,但可能会起作用:首先创建一个批处理文件,并使用setx/M键值设置环境变量。首先运行批处理脚本,然后运行real命令。这将使您的机器环境变量变得混乱。谢谢,但这可能会造成安全漏洞,因为在此用户下运行的每个人都可以读取全局环境变量。是的,我已经说过这不好…这是一种轻描淡写的说法:-(您是否尝试将环境变量设置为(通过System.Environment.SetEnvironmentVariable(键,balue)实现);然后启动进程?但是当UseShellExecute=true时,我如何才能这样做?谢谢!你知道这种方法有多安全吗?非常安全还是非常不安全,取决于你的上下文。你打算做非常不安全的事情吗?我正在向我的应用程序传递密码。我需要除了新进程之外,没有人能够读取密码。我我也会在调用前检查exe是否已签名。然后不要使用临时批处理文件,因为它在程序运行期间是可读的。您可以使用自定义包装程序,通过共享内存块接收密码。(并在收到密码后立即覆盖)。您计划将密码存储在哪里?
    static void Main(string[] args)
    {
        var command = "cmd.exe";
        var environmentVariables = new System.Collections.Hashtable();
        environmentVariables.Add("some", "value");
        environmentVariables.Add("someother", "value");

        var filename = Path.GetTempFileName() + ".cmd";
        StreamWriter sw = new StreamWriter(filename);
        sw.WriteLine("@echo off");
        foreach (DictionaryEntry entry in environmentVariables)
        {
            sw.WriteLine("set {0}={1}", entry.Key, entry.Value);
        } 
        sw.WriteLine("start /w {0}", command);
        sw.Close();
        var psi = new ProcessStartInfo(filename) {
            UseShellExecute = true, 
            Verb="runas"
        };
        var ps =  Process.Start(psi);
        ps.WaitForExit();
        File.Delete(filename);
    }