I'm trying to sart an instance of VLC using wmic I'm doing this mainly because I want to capture the pid of the created process
I know the command below works fine from the command line:
C:\PROGRA~1\VideoLAN\VLC_117\vlc.exe rtsp://abcd --sout="#duplicate{dst=display, dst={std{access=file, mux=ps, dst='vlc_117/video.mpg'}}} --rtsp-caching=120 --no-video-title-show"
(where rtsp://abcd can be any input file for the purposes of this example)
Trying to run it via wmic, with various different attempts as escape sequences (of which the below is one):
wmic process create 'C:\PROGRA~1\VideoLAN\VLC_117\vlc.exe rtsp://abcd --sout="#duplicate{dst=display, dst={std{access=file, mux=ps, dst='vlc_117/video.mpg'}}} --rtsp-caching=120 --no-video-title-show" '
Reliably gives me the same error:
Invalid format.
Hint: <assignlist> = <propertyname>=<propertyvalue> [, <assignlist>].
However the following:
wmic process create 'C:\PROGRA~1\VideoLAN\VLC_117\vlc.exe rtsp://abcd --sout="#duplicate{dst=display} --rtsp-caching=120 --no-video-title-show"'
Works fine - except that as a command it is useless to me. So the problem seems to be with the nested curly bracketed section of my original command.
I've tried various different escape characters...so far with no success. Can anyone suggest where I am going wrong?
Quoting and escaping rules are complicated enough in CMD, and then they get even crazier when you add WMIC complications.
WMIC can generally use
'
or"
as quote characters. Double quote within double quotes can be escaped using\"
. Single quote within single quotes can also be escaped using\'
, but the backslash does not appear to get consumed, so it seems to be useless.CMD only uses
"
, and there is no way to escape a"
within a quoted string. Poison characters like&
,|
,<
, etc. that are not within quotes must be escaped like^&
etc.Trying to merge the quoting and escaping rules for both WMIC and CMD is tricky. Remember that the CMD quoting and escaping takes place before WMIC ever sees the command line.
Also, you could use
PROCESS CALL CREATE
instead ofPROCESS CREATE
. I suppose it is possible withPROCESS CREATE
, but I've never seen how it is done.I'm not sure I know your actual command line that works without using WMIC. Based on your code, I'm assuming the following would work:
If so, then I believe the following WMIC command will work:
WMIC must see the entire command line after create as one continuous string. The internal single quotes in
'vlc_117/video.mpg'
do not cause a problem because there are no spaces in the content. Adding spaces would break this solution, and another strategy would be needed.You should be able to use the long path instead of short path if you use double quotes around the exe path:
You might want to capture the PID in a variable within a batch file, in which case a FOR /F command would be used. This adds even more complexity. Unquoted CMD token delimiters like
=
,,
etc. must be escaped because of an extra layer of parsing that FOR /F introduces. Unquoted poison characters must also be escaped because of the extra layer of parsing.The enclosing single quotes within the FOR /F IN() clause do not cause a problem because they are stripped before WMIC ever sees the command. But the unquoted
=
in--sout=...
must be escaped.I'm not in a position to test any of the above, so perhaps none of it works as written. However, the concepts I discuss should still be valid.
Seemingly minor changes to the command line could have a major impact on the solution because of the many layers and complexities of quoting and escaping. If the command is not as I interpreted, then let me know the correct command by editing your question, and I can try to adapt the answer.
UPDATE 2014-05-27
Bad news on my end. The PROCESS CALL CREATE option expects the full command line as the first string argument, optionally followed by the working directory as a second argument. The bad news is the arguments are delimited by commas. Your command line also has commas, and the PROCESS CALL CREATE parser (whatever that is) doesn't seem to support commas within your command line :(
I've tried quoting the commas within single or double quotes, and that doesn't help. I've also tried escaping the commas with
\
. Again, no luck. I've also googled for a solution and come up empty.I'm afraid there may not be a solution, unless there is VLC syntax available that eliminates the commas, or if there is a way to put the complex VLC command line arguments in some type of external script file. Or maybe some other clever person has discovered a way to escape the commas?
Here are some examples that show what I have tried. I don't have VLC so I simply substituted CMD /C with an ECHO statement. Trying to ECHO a comma fails every time.
Update 2014-12-23: A solution has been found!
Over at DosTips a group of us developed various methods for a batch script to determine its own PID. Once this is known, it is possible to use WMIC to list all child processes of the parent session. With careful bookkeeping, it is possible to reliably determine the PID of each newly created child process. But it does take a considerable amount of code. This should only be needed if your command line cannot be passed through WMIC PROCESS CALL CREATE (the comma problem).
I thought I might post another few observations here. PowerShell seems to be more resistant to confusion of tokens and symbols when using WMI to create a process. Just backtick escape nested quotation marks. Example:
Windows Script Host (JScript and VBScript) are equally resistant to the comma problem. Here's a Batch + JScript hybrid script (saved with a .bat extension) to demonstrate:
For both the PowerShell and the JScript solutions, remove
cmd /k echo
to put yourvlc
command into production.RE: pure Batch, I can't offer much for the uncommonly complicated
vlc
command referenced in the question, but this might help others. For less complex commands that need embedded quotation marks but don't have to deal with commas, you can embed quotation marks in awmic
command by escaping them with backslashes.If that doesn't work in your situation, you can also try putting the whole value into a variable retrieved with delayed expansion. Example:
Or for convenient reuse, you can put it into a subroutine:
Unfortunately, neither of these pure Batch solutions solves the comma problem.