如何在C#中执行DOS SET命令并使变量在exe关闭后仍然存在?

4
我有一个在DOS命令进程中启动的C#控制台可执行文件。
我需要能够从C#可执行文件执行DOS命令(特别是需要能够设置变量),并使变量持久化,以便DOS进程的其余部分可以引用它们。
例如:
启动DOS进程 -> C#执行SET命令来设置UserVariable -> DOS进程可以ECHO %UserVariable%
由于性能原因,我不能将SET命令写入DOS脚本。事实上,我不能进行任何文件I/O。
有人能帮忙吗?
6个回答

4

谢谢您的回复。- 之后我该如何检索这个值?需要的是:在单个命令窗口的生命周期内,我们需要能够从C#中调用设置dos变量,以便在同一命令窗口中访问。理想情况下,这些值不应在窗口关闭后保留。 - Mohammed
我认为使用 SETX yourvar= 会将其删除。 - Ignacio Soler Garcia
我们担心的不是删除,而是在 C# 代码之后检索它以供使用(例如 ECHO %SomeVariable%)在 DOS 代码中。目前,除非找到可行的解决方案,否则我们将不得不使用单个文件 I/O 在进程中编写一个带有 set 命令的小批处理文件。 - Mohammed
如果您调用SETX命令,变量将一直保留,直到被删除。因此,在执行SETX命令后,您可以使用%var%从任何地方访问该变量。您打开一个cmd窗口,执行SETX test="jj",关闭该窗口,再打开另一个cmd窗口,输入%test%,您将得到jj。 - Ignacio Soler Garcia
感谢您清晰而有帮助的回复。是的,这个方法可以行得通,但它会违反我正在处理的限制,所以不幸的是我不能使用它。 - Mohammed

3
问题不在于你正在从C#应用程序中调用SET。即使您打开Windows提示符并调用SET以设置用户变量,它也不会在会话中持久存在。

显示、设置或删除CMD环境变量。使用SET所做的更改仅在当前CMD会话的持续时间内保留。

来源。 我建议你直接通过.Net设置变量。您可以使用Environment.SetEnvironmentVariable来实现这一点。

当然,如果你有一个好的理由从提示符执行该操作,@SoMoS的帖子就是正确的方法。但我并不是在抄袭他的答案 :) - Bruno Brant

1

如果您正在从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循环执行,并且变量将存在于调用脚本的上下文中。


这太完美了 :) 正是我想要的。 - Mohammed

1

不幸的是,这个方法没有起作用。在我的C#代码中使用了Environment.SetEnvironmentVariable("MoTest", "We are Sorted...");,但在C#代码之后的DOS脚本中无法检索到该值。 - Mohammed
你传了什么作为第三个参数? - Mr. TA
哎呀,没注意到重载。我刚试了一下 Environment.SetEnvironmentVariable("MoTest", "We are Sorted...", EnvironmentVariableTarget.Process); 但是得到了相同的结果。我对使用 USER 或 MACHINE 感到谨慎,因为这两个都会写入注册表。 - Mohammed
想一想。你传入“Process”,并想知道为什么它在进程外不可用。然而,你对“User”和“Machine”持怀疑态度,因为它们会写入注册表。难道没有想过,为了使其在进程外可用,它需要被写入某个地方,而注册表恰好就是这个地方吗? - Mr. TA
谢谢您纠正我的拼写,我知道它需要被写在某个地方,但是希望有人知道一种不需要文件I/O和不使用注册表来设置值的方法。我们的系统将有很多并发脚本运行,因此我们不会使用注册表来存储仅需要存在于单个脚本生命周期内的值。再次感谢您的所有时间和精力,但我认为我们将采用每个脚本执行一个单独文件写入的“折衷方案”,并观察其对性能的影响。 - Mohammed
我认为没有必要对原帖人过于苛刻,所以我选择回答“-1”。 - Bruno Brant

0

这绝不是一个答案,但考虑到问题的性质,这种“妥协”是我们目前选择的路径。

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

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


-1

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

就我而言,在那个枚举中的第三个元素,Process,基本上是无用的。我唯一能看到它可能有用的方式是,如果一个进程生成另一个进程,并将其环境传递给子进程。对于大多数常规管理脚本来说,这是过度杀伤力。


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