【问题标题】:How do I execute a DOS SET command from C# and have the variable persist after the exe closes?如何从 C# 执行 DOS SET 命令并在 exe 关闭后使变量保持不变?
【发布时间】:2012-06-17 15:32:41
【问题描述】:

我在 DOS 命令进程中启动了一个 C# 控制台可执行文件。

我需要能够从 C# 可执行文件执行 DOS 命令(特别是我需要能够设置变量)并让变量保持不变,以便 DOS 进程的其余部分可以引用它们。

即:

启动DOS进程 -> C# 执行一个 SET 命令来设置 UserVariable -> DOS 进程可以 ECHO %UserVariable%

由于性能原因,我无法将 set 命令写入 dos 脚本。事实上,我根本无法进行任何文件 I/O。

谁能帮忙?

【问题讨论】:

    标签: c# set dos process.start


    【解决方案1】:

    【讨论】:

    • 感谢您的回复。 - 之后我将如何检索价值?需要是这样的:对于单个命令窗口的生命周期,我们需要能够设置在该命令窗口中调用的 C# 中的 dos 变量,以便在同一命令窗口中访问。理想情况下,这些值不应在窗口关闭后持续存在。
    • 我认为使用 SETX yourvar= 会删除它
    • 我们担心的不是删除。它正在检索它以在 C# 之后的 DOS 代码中使用(例如 ECHO %SomeVariable%)。目前,除非找到可行的解决方案,否则我们将不得不在处理中使用单个文件 I/O 来编写带有 set 命令的小批处理文件。
    • 如果您调用 SETX,该变量将永远保留,直到被删除。因此,在您执行 SETX 命令后,您可以使用 %var% 从任何您想要的地方访问该变量。你打开一个 cmd,执行 SETX test="jj",关闭 cmd,打开另一个 cmd,写 %test% 你得到 jj
    • 感谢您的清晰而有帮助的回复。是的,这会起作用,但它会违反我正在工作的限制,所以很遗憾我不能使用它。
    【解决方案2】:

    问题不在于您是从 C# 应用程序中调用 SET 的事实。即使您打开 Windows 提示并调用 SET 来设置用户变量,它也不会在会话中持续存在。

    显示、设置或删除 CMD 环境变量。所做的更改 SET 将仅在当前 CMD 会话期间保留。

    Source

    无论如何,我建议您直接通过 .Net 设置变量。您可以使用Environment.SetEnvironmentVariable 来执行此操作。

    【讨论】:

    • 当然,如果您有充分的理由从提示中执行此操作,@SoMoS 帖子是您的最佳选择。不过,我并没有窃取他的答案。 :)
    【解决方案3】:

    如果您从 dos 脚本运行 C# 应用程序并希望之后从脚本使用应用程序中设置的变量,我不知道如何仅针对 C# 中的该脚本的上下文执行此操作,另一个这里的答案向您展示了机器本身,但我很感激您需要一些永久性范围较小的东西。

    元编程解决方法可能是:

    • 从 DOS FOR 循环调用 C# 应用程序
    • 从 C# 应用程序输出到控制台 SET 命令
    • 使用 for 循环执行应用输出

    调用 DOS 脚本如下所示:

    FOR /F "tokens=* delims=" %%A IN ('MyApp.exe') DO ( 
       %%A
    )
    

    MyApp.exe 的控制台输出需要采用以下格式:

    SET UserVariable1=UserValue1
    SET UserVariable2=UserValue2
    

    然后每个输出行将由调用 FOR 循环执行,然后变量将存在于调用脚本的上下文中。

    【讨论】:

    • 这是完美的 :) 正是我所追求的。
    【解决方案4】:

    改用以下 .NET 方法:

    Environment.SetEnvironmentVariable

    【讨论】:

    • 不幸的是,这不起作用。使用:Environment.SetEnvironmentVariable("MoTest", "We are Sorted...");在我的 C# 代码中,我无法在 C# 代码之后检索 DOS 脚本中的值。
    • 第三个参数你传递了什么?
    • 糟糕,没有注意到过载。刚刚用 Environment.SetEnvironmentVariable("MoTest", "We are Sorted...", EnvironmentVariableTarget.Process);但得到了相同的结果。我很担心使用 USER 或 MACHINE 来写入注册表。
    • 想一想。您正在传递“流程”并想知道为什么它在您的流程之外不可用。然而,您对“用户”和“机器”持怀疑态度,因为它会写入注册表。你有没有想过要让它在你的进程之外可用,它需要写成 SOMEWHERE 并且注册表恰好是它?
    • 感谢您纠正我的拼写,是的,我知道它需要写在某个地方,但希望有人知道一种在没有文件 I/O 和不使用的情况下设置值的方法注册表。我们的系统将运行大量并发脚本,因此我们不会使用注册表来存储只需要在单个脚本的生命周期内存在的值。再次感谢您付出的所有时间和努力,但我认为我们将“妥协”每次脚本执行写入单个文件,看看这如何影响性能。
    【解决方案5】:

    这绝不是一个答案,但从问题的性质来看,这种“妥协”是我们暂时选择的路径。

    我们将使用由 C# 应用程序创建的批处理脚本,其中包含所需的所有简单设置命令,然后由调用 C# 应用程序的 CMD 进程执行。

    请随意添加任何进一步的想法和 cmets,因为这不是理想的解决方案。

    【讨论】:

      【解决方案6】:

      不幸的是,据我所知,这是至少通过 Windows 7 可用的“解决方案”。我一直在尝试各种设置和随后使用环境变量的方法,我的底线是研究表明,如果要使用变量,必须事先将其设置到 USER 或 MACHINE 键中,或者必须是局部变量,通过脚本命令设置,然后在同一脚本中进一步测试。

      就我而言,该枚举中的第三个元素 Process 基本上是无用的。我可以看到它可能有用的唯一方法是,如果一个进程产生另一个进程,将其环境传递给子进程。对于大多数普通的管理脚本来说,这太过分了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多