3

I'm trying to get the output of wmic process call create so I can get the ProcessId of the newly created process. If I just run:

wmic process call create "notepad.exe a.txt","d:\"

It works just fine (it opens the file a.txt under folder d:\ with notepad). Now, if I try:

for /f "usebackq delims==; tokens=1,2" %i in (`wmic process call create "notepad.exe a.txt","d:\"^|findstr ProcessId`) do @echo pid = %j

It doesn't, and shows me the error:

Formato incorrecto. Sugerencia: <lista_parámetros> = <parámetro> [, <lista_parámetros>].

I don't really know what's going on here, can anyone explain this to me or if this is possible at all?

NOTE: Other commands work fine. For instance, if I run:

for /f "usebackq" %i in (`wmic process where "executablepath like '%%notepad.exe'" get ProcessId /value^|findstr ProcessId`) do @echo OUTPUT: %i

It gives the expected output, which in this case is:

OUTPUT: ProcessId=2084

Thanks!

dcg
  • 4,187
  • 1
  • 18
  • 32

2 Answers2

5

I just found how can it be done. Due to the command was working only directly in the command prompt I decided to use cmd /c "...", it's as follows:

for /f "usebackq delims==; tokens=1,2" %i in (`cmd /c "wmic process call create 'notepad.exe a.txt','d:\'"^|findstr ProcessId`) do @echo pid = %j

Now the only thing is that the PID needs to be trimed out of spaces, but that something else. Sorry for the inconvinience.

dcg
  • 4,187
  • 1
  • 18
  • 32
  • 2
    The key of this approach is the fact that the `,` lies in between a pair of `""`, so it is passed over to the new `cmd` instance initiated by `for /F` literally, so this works; in your original code, the `,` needed to be escaped like `^,`, that's it... – aschipfl Apr 04 '17 at 17:38
  • Great answer! Is there a way to minimize the window `wmic process call create '...'` creates? It'd be great if it was possible... – Igor May 29 '20 at 18:22
  • Thanks @Igor, this was a long while ago, I don't even remember why I was doing this . Sorry. – dcg May 29 '20 at 19:50
4

There is no need to initiate another cmd instance. You could do it as follows:

for /F "tokens=2 delims==; " %I in ('wmic Process call create "notepad.exe a.txt"^,"D:\" ^| find "ProcessId"') do @echo PID = %I

You need to escape the , like ^,, so the cmd instance initiated by the for /F loop receives it literally; otherwise, it becomes most likely replaced by a SPACE, because to cmd a comma is nothing but a token separator just like the SPACE.


When the given text file a.txt does not exist, the above code does not open a notepad.exe instance, even if executed without surrounding for /F loop:

rem // This fails in case `a.txt` is not found, `notepad.exe` is not opened:
wmic Process call create "notepad.exe a.txt","D:\" | find "ProcessId"

rem /* When removing the pipe, `notepad.exe` is opened and a window appears:
rem    `Cannot find the a.txt file. Do you want to create a new file?`: */
wmic Process call create "notepad.exe a.txt","D:\"

I guess this behaviour comes from the pipe (|), because it initiates new cmd instances for either side; I believe notepad.exe (or any other application) is run in a kind of hidden mode where no user interaction is required (for the application not to await input in the background to no avail).

Therefore I recommend to use a variant without need of a pipe, like this:

for /F "tokens=*" %I in ('wmic Process call create "notepad.exe a.txt"^,"D:\"') do @for /F "tokens=1-2 delims==; " %J in ("%I") do @if "%J"=="ProcessId" echo PID = %K

The outer for /F loop uses the default delimiters TAB and SPACE in order to remove the leading TAB in front of the keyword ProcessId, the inner loop contains an if condition to extract the correct line (instead of find) and splits off everything but the process ID number.

aschipfl
  • 33,626
  • 12
  • 54
  • 99