【问题标题】:Can I run a windows batch script from memory?我可以从内存中运行 Windows 批处理脚本吗?
【发布时间】:2019-11-29 16:08:35
【问题描述】:

假设我在我的程序中动态生成这样的脚本并将其保存在 C++ 字符串变量中。我该如何运行它?我是否必须先将其保存到文件中,然后指示 cmd.exe 运行它?

我知道您可以像这样将命令通过管道传输到 cmd.exe:

type script.bat | cmd

但这样做的效果不是运行 script.bat 。相反,Windows 会启动一个新的 cmd.exe 实例,打印徽标并等待命令在执行之前回显到屏幕上。例如,尝试

echo echo hello | cmd

因此,script.bat 中的每一行都作为一个独立的命令处理,就像您在命令行中输入它一样(这就是 cmd.exe 认为您正在做的事情!)。那不好。你不能像那样运行一般脚本。您可能有跨越多行的循环和分支。那我该怎么办?

我知道你可以像这样将多个命令放在一行中:

cmd /C "echo hello & echo world"

但是每个批处理脚本都可以以某种方式轻松地更改为 oneliner 吗?如果脚本是:

@echo off

echo hello
echo world

我可以用上面的 onlineer 替换它,但是如果它包含一个 for 循环跨越几行带括号?

所以标题问题可以重新表述为:每个批处理脚本都可以转换为单行吗?如果是,那怎么办?如果没有,有什么好的解决方案吗?我能否以某种方式欺骗 cmd.exe,使其认为它从文件中读取批处理脚本,而实际上它是从我的程序中获取的?

编辑:一个有趣的怪癖是:

echo echo hello | cmd /C "for /f "tokens=*" %a in ('more') do @%a"

但同样,每一行都被解释为一个独立的命令。

【问题讨论】:

  • 除非您可以安全地用 & 号替换所有新行,否则不行!
  • @Compo 用 & 替换所有换行符是不正确的。跨多行带括号的复合语句不得!
  • Henrik4,一个跨越多行带括号的复合语句,不需要跨越多行。如果这是您的选择,或者您无法将该批处理文件编写为每行一个完整的命令语句,那么答案是否定的,并且您的示例不代表您的实际任务。
  • 也许this answer 可以帮助你...
  • @Aacini 是的,高度相关且有趣。 dostips 上的文章非常好。您要证明的是,将通用批处理脚本转换为一系列独立命令很复杂!

标签: windows batch-file cmd


【解决方案1】:

FILE_ATTRIBUTE_TEMPORARY 文件正在用于临时存储。 文件系统试图将所有数据保存在内存中以更快 访问而不是将数据刷新回大容量存储。一个临时的 文件一旦不再被应用程序删除 需要。

FILE_FLAG_DELETE_ON_CLOSE 表示操作系统要 关闭所有句柄后立即删除文件, 不仅仅是您为其指定 FILE_FLAG_DELETE_ON_CLOSE 的句柄。 随后对该文件的打开请求将失败,除非 使用了 FILE_SHARE_DELETE。

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea

如果您使用这些标志指定临时文件,则可以将其作为批处理运行。除非您处于内存压力之下,否则该文件永远不会在硬盘上。

PS:如果您在“打开文件”对话框中键入 URL,记事本将打开 Web 文件。记事本是潜在系统功能的测试平台。

PPS:您可以通过管道传输它。 cmd /c < ..\win.ini(不是说这是有道理的,但我们在 windows 中不再有标准的批处理文件)。

【讨论】:

  • 太棒了!这与我正在寻找的非常接近。我现在唯一的问题是:即使我没有对硬盘的写访问权限,我是否可以创建一个临时文件?
  • 可能不会。但是什么场景有一个程序无处可写。 PS 如果将批处理括在括号中并将%% 更改为%,一半的简单批处理文件将作为命令执行。第一行 = (,最后一行 = )
  • 也许我可以写,但我想避免硬盘写。我希望一切都发生在记忆中。
  • 什么意思,作为命令执行?我不能在命令行上放置多行脚本。
  • 您可以通过管道传输它。 cmd /c < ..\win.ini.
猜你喜欢
  • 2014-09-05
  • 1970-01-01
  • 2015-07-20
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
相关资源
最近更新 更多