Escaping strings when using wmic

前端 未结 2 681
终归单人心
终归单人心 2020-12-11 09:38

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

2条回答
  •  失恋的感觉
    2020-12-11 10:09

    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:

    $addr = "rtsp://abcd"
    $cmd = "cmd /k echo C:\PROGRA~1\VideoLAN\VLC_117\vlc.exe $addr --sout=`"#duplicate{dst=display, dst={std{access=file, mux=ps, dst='vlc_117/video.mpg'}}} --rtsp-caching=120 --no-video-title-show`""
    $proc = ([wmiclass]'win32_process').create($cmd)
    
    $proc.ProcessId
    

    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:

    @if (@CodeSection == @Batch) @then
    @echo off & setlocal
    
    set "addr=rtsp://abcd"
    for /f %%I in ('cscript /nologo /e:JScript "%~f0" "%addr%"') do set "PID=%%I"
    echo Process: %PID%
    goto :EOF
    
    @end // end Batch / begin JScript hybrid code
    var wmi = GetObject("winmgmts:root\\cimv2"),
        proc = wmi.Get("Win32_Process").Methods_("Create").InParameters.SpawnInstance_();
    
    proc.CommandLine = 'cmd /k echo C:\\PROGRA~1\\VideoLAN\\VLC_117\\vlc.exe '
        + WSH.Arguments(0)
        + ' --sout="#duplicate{dst=display, dst={std{access=file, mux=ps, dst=\'vlc_117/video.mpg\'}}} --rtsp-caching=120 --no-video-title-show"';
    
    var exec = wmi.ExecMethod('Win32_Process', 'Create', proc);
    WSH.Echo(exec.ProcessId);
    

    For both the PowerShell and the JScript solutions, remove cmd /k echo to put your vlc 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 a wmic command by escaping them with backslashes.

    wmic process call create "powershell \"test-connection localhost -count 1\""
    

    If that doesn't work in your situation, you can also try putting the whole value into a variable retrieved with delayed expansion. Example:

    set "proc=powershell \"test-connection localhost -count 1\""
    setlocal enabledelayedexpansion
    for /f "tokens=2 delims==;" %%I in (
        '2^>NUL wmic process call create "!proc!" ^| find "ProcessId"'
    ) do endlocal & set /a PID = %%I
    echo Proc: %PID%
    

    Or for convenient reuse, you can put it into a subroutine:

    @echo off & setlocal
    
    set "pc=localhost"
    call :run PID "powershell -window normal \"test-connection %pc% -count 1\""
    echo Proc: %PID%
    goto :EOF
    
    :run  
    setlocal
    set proc=%*
    call set proc=%%proc:%1 =%%
    setlocal enabledelayedexpansion
    for /f "tokens=2 delims==;" %%I in (
        '2^>NUL wmic process call create !proc! ^| find "ProcessId"'
    ) do (endlocal & endlocal & set /a %~1 = %%I && goto :EOF)
    

    Unfortunately, neither of these pure Batch solutions solves the comma problem.

提交回复
热议问题