0

Suppose I generate such a script dynamically in a program of mine and hold it in a C++ string variable. How can I run it? Do I have to save it to a file first and then instruct cmd.exe to run it?

I know you can pipe commands into cmd.exe like this:

type script.bat | cmd 

But the effect of that is not to run script.bat . Instead, windows starts a new cmd.exe instance, prints the logo and waits for commands which it echos to the screen before executing them. For instance, try

echo echo hello | cmd 

Thus every line in script.bat is handled as an independent command, just as if you entered it on the command line (which is what cmd.exe thinks you are doing!). That's no good. You can't run general scripts like that. You may have loops and branches spanning several lines. So what can I do?

I know you can put several commands on one line like this:

cmd /C "echo hello & echo world" 

But can every batch script somehow and easily be changed to a oneliner? If the script was:

@echo off echo hello echo world 

I could replace it by the onliner above, but if it contains a for loop spanning several lines with brackets?

So the title question could be reformulated to: Can every batch script be transformed to a oneliner? If so then how? And if not, is there any good solution to the problem? Can I somehow trick cmd.exe into thinking that it reads a batch script from a file, while it actually gets it from a program of mine?

Edit: An interesting quirk is to do:

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

But again every line is interpreted as an independent command.

6
  • Unless you can safely replace all new lines with ampersands, then no! Commented Nov 29, 2019 at 16:18
  • @Compo It's not correct to replace all newlines with &. A compound statement spanning several lines with brackets must not! Commented Nov 29, 2019 at 16:39
  • Henrik4, a compound statement spanning several lines with brackets, does not need to span several lines. If that's your choice to do that, or you're unable to write that batch file as one complete command statement per line, then the answer is a straight no, and your examples are not representative of your actual task. Commented Nov 29, 2019 at 16:59
  • 1
    Perhaps this answer may help you... Commented Nov 29, 2019 at 17:01
  • @Aacini Yes, highly relevant and interesting. The article at dostips is very good. What you're proving is that translation of a general batch script to a series of independant commands is complicated! Commented Nov 29, 2019 at 18:20

1 Answer 1

3

FILE_ATTRIBUTE_TEMPORARY The file is being used for temporary storage. File systems attempt to keep all of the data in memory for quicker access rather than flushing the data back to mass storage. A temporary file should be deleted by the application as soon as it is no longer needed.

FILE_FLAG_DELETE_ON_CLOSE Indicates that the operating system is to delete the file immediately after all of its handles have been closed, not just the handle for which you specified FILE_FLAG_DELETE_ON_CLOSE. Subsequent open requests for the file will fail, unless FILE_SHARE_DELETE is used.

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

If you specify a temp file with these flags, you can run that as a batch. Unless you are under memory pressure the file will never be on the hard disk.

PS: Notepad will open web files if you type an URL into the Open File dialog. Notepad is a test bed for potential system features.

PPS: You can pipe it. cmd /c < ..\win.ini (not that this makes sense but we no longer have a standard batchfile in windows).

Sign up to request clarification or add additional context in comments.

12 Comments

Great! This is very close to what I'm looking for. My only question now is: Am I allowed to create a temporary file even if I don't have write access to the hard disk?
Probably not. But what scenario has a program with nowhere to write. PS Half of simple batch files will execute as commands if you enclose the batch in brackets and change %% to %. First line = ( and last line = ).
Maybe I can write but I'd like to avoid hard disk writes. I want everything to happen in memory.
What do you mean, execute as commands? I can't put a multiline script on the command line.
You can pipe it. cmd /c < ..\win.ini.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.