0

This is working in cmd:

 "C:\Program Files (x86)\CodeMeter\Runtime\bin\cmu32.exe" --list-content | FIND "Serial Number 12345-"

Output (correctly extracted from multiple lines):

CmContainer with Serial Number 12345-67890 and version 1.19 (locked)

But I want to make it work in a .bat file and store the result to a variable (from here):

 for /f "usebackq" %%i in (`"C:\Program^ Files^ ^(x86)\CodeMeter\Runtime\bin\cmu32.exe" --list-content ^| FIND "Serial Number 12345-"`) do SET foobar=%%i

it throws:

The filename, directory name, or volume label syntax is incorrect.

PS: in the final version I'd like to use system variables for the path, like "%PROGRAMFILES(X86)%\CodeMeter\Runtime\bin\cmu32.exe", but while that does not make a difference in cmd, it throws "'C:\Program' is not recognized as an internal or external command, operable program or batch file." when called from within a .bat... so I guess there are escaping issues?

crusy
  • 1,424
  • 2
  • 25
  • 54
  • 1
    Usually there is no need to escape anything except the `|` since the path is in between `""` that protect special characters; in this situation however the very first `"` and the very last one are considered as a pair and become removed prior to further processing; to prevent that put another but escaped pair around, so `... in ('^""%ProgramFiles(x86)%\..." ^| find "..."^"') ...`... – aschipfl Jul 29 '19 at 07:30
  • @aschipfl: `'C:\Program' is not recognized as an internal or external command, operable program or batch file.`. Doble checking by adding ^ only before first space: `'C:\Program Files' is not recognized as an internal or external command, operable program or batch file.` – crusy Jul 29 '19 at 07:32
  • edited my first comment meanwhile... – aschipfl Jul 29 '19 at 07:35
  • Better, as the error msg is gone. However: The result still isn't the same as on command line, it's just `-` being stored in `foobar`... probably a different question though? – crusy Jul 29 '19 at 07:41

1 Answers1

2

In your command line:

for /f "usebackq" %%i in (`"C:\Program^ Files^ ^(x86)\CodeMeter\Runtime\bin\cmu32.exe" --list-content ^| FIND "Serial Number 12345-"`) do SET foobar=%%i

the very first and last quotation mark of the expression behind in are considered as a pair that becomes removed; the remainder becomes then processed and is then recognised as wrong syntax.

To prevent that place another pair of quitation marks around, but escape them, like this:

for /f "usebackq" %%i in (`^""C:\Program Files (x86)\CodeMeter\Runtime\bin\cmu32.exe" --list-content ^| FIND "Serial Number 12345-"^"`) do SET foobar=%%i

The reason for this odd behaviour is that for /F uses cmd /S /c to run the command line behind in, so this is what becomes executed, using your code (without any escaping):

cmd /S /c "C:\Program Files (x86)\CodeMeter\Runtime\bin\cmu32.exe" --list-content | FIND "Serial Number 12345-"

cmd /S strips the first and last " and leaves behind the following line, which is invalid syntax:

C:\Program Files (x86)\CodeMeter\Runtime\bin\cmu32.exe" --list-content | FIND "Serial Number 12345-

Now to avoid such a strange remainder, give to cmd some explicit quotation marks to remove:

cmd /S /c ""C:\Program Files (x86)\CodeMeter\Runtime\bin\cmu32.exe" --list-content | FIND "Serial Number 12345-""

The escaping I suggested is intended for the command path (including )) to appear in between a pair of quotation marks in order not to have to care about any further escaping (like ^)):

cmd /S /c ^""C:\Program Files (x86)\CodeMeter\Runtime\bin\cmu32.exe" --list-content | FIND "Serial Number 12345-"^"

You do not need the usebackq option, but you may need delims= to not split the received string at white-spaces, like this:

for /f "delims=" %%i in ('^""%ProgramFiles(x86)%\CodeMeter\Runtime\bin\cmu32.exe" --list-content ^| FIND "Serial Number 12345-"^"') do SET "foobar=%%i"
aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Do need `usebackq`, get `The system cannot find the file `""C:\Program.` (note the double quote), but delims did the trick. Thanks! – crusy Jul 29 '19 at 07:43
  • Well, `usebackq` does not change handling of double-quotes here, it just lets you use ` instead of `'`... – aschipfl Jul 29 '19 at 08:11