最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Powershell escape in LUA script - Stack Overflow

programmeradmin1浏览0评论

Trying to kill some child processes (given parent pid) from within a lua script. Found solution using wmic but prefer using powershell.

I can run each of these powershell commands in a standard windows cmd.exe and they all behave as expected.

powershell -Command "Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq 311 } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"

cmd /c "powershell -Command Get-WmiObject Win32_Process ^| Where-Object { $_.ParentProcessId -eq 311 } ^| ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"

set PARENT_PID=311 && powershell -NoProfile -ExecutionPolicy Bypass -Command "$parentPID = [int]$env:PARENT_PID; Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq $parentPID } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"

Each one is essentially the same command as I got more desperate trying to find a variation that would work in lua. However, of course, when trying to run any of them from within a LUA script I cannot get them to work. The command 'windows' pass by very fast and do not appear to have any text in them:

os.execute("powershell -Command \"Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq " .. pid .. " } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }\"")

os.execute("powershell -Command \"Get-WmiObject Win32_Process ^| Where-Object { $_.ParentProcessId -eq " .. pid .. " } ^| ForEach-Object { Stop-Process -Id $_.ProcessId -Force }\"")

os.execute("set PARENT_PID=" .. pid .. " && powershell -NoProfile -ExecutionPolicy Bypass -Command \"$parentPID = [int]$env:PARENT_PID; Get-WmiObject Win32_Process ^| Where-Object { $_.ParentProcessId -eq $parentPID } ^| ForEach-Object { Stop-Process -Id $_.ProcessId -Force }\"")

Any tips on escaping the commands or general troubleshooting methods?

UPDATE:

The provided answer is the correct way to solve the problem in question. Turns out I had another problem which was actually causing my command to fail (debugging late at night not a good idea)

Big piece of advice when having trouble escaping characters being sent to a shell command. WRITE IT TO A BATCH FILE FIRST TO MAKE ABSOLUTELY SURE THE FORMATTING IS CORRECT!

Anyways it ended up being something simple - my pid variable that I passed into the call had a newline in it! Trouble was I didn't see this in my debug log because I guess vlc strips them out. I did not notice this until first trying to write the contents of the command to a batch file. I later sanitized the pid variable and sure enough all good. My troubleshooting code for reference.

    local sanitized_pid = job_pid:gsub("%s+", "")
    local batch_file = system_directory .. "\\abort_job.bat"
    local batch_content = "powershell -Command \"Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq " .. sanitized_pid .. " } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }\"\n"
    local file = io.open(batch_file, "w")
    if file then
        file:write(batch_content)
        file:close()
        os.execute(batch_file)
    else
        vlc.msg.err("Failed to create batch file for aborting job.")
    end

Trying to kill some child processes (given parent pid) from within a lua script. Found solution using wmic but prefer using powershell.

I can run each of these powershell commands in a standard windows cmd.exe and they all behave as expected.

powershell -Command "Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq 311 } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"

cmd /c "powershell -Command Get-WmiObject Win32_Process ^| Where-Object { $_.ParentProcessId -eq 311 } ^| ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"

set PARENT_PID=311 && powershell -NoProfile -ExecutionPolicy Bypass -Command "$parentPID = [int]$env:PARENT_PID; Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq $parentPID } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }"

Each one is essentially the same command as I got more desperate trying to find a variation that would work in lua. However, of course, when trying to run any of them from within a LUA script I cannot get them to work. The command 'windows' pass by very fast and do not appear to have any text in them:

os.execute("powershell -Command \"Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq " .. pid .. " } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }\"")

os.execute("powershell -Command \"Get-WmiObject Win32_Process ^| Where-Object { $_.ParentProcessId -eq " .. pid .. " } ^| ForEach-Object { Stop-Process -Id $_.ProcessId -Force }\"")

os.execute("set PARENT_PID=" .. pid .. " && powershell -NoProfile -ExecutionPolicy Bypass -Command \"$parentPID = [int]$env:PARENT_PID; Get-WmiObject Win32_Process ^| Where-Object { $_.ParentProcessId -eq $parentPID } ^| ForEach-Object { Stop-Process -Id $_.ProcessId -Force }\"")

Any tips on escaping the commands or general troubleshooting methods?

UPDATE:

The provided answer is the correct way to solve the problem in question. Turns out I had another problem which was actually causing my command to fail (debugging late at night not a good idea)

Big piece of advice when having trouble escaping characters being sent to a shell command. WRITE IT TO A BATCH FILE FIRST TO MAKE ABSOLUTELY SURE THE FORMATTING IS CORRECT!

Anyways it ended up being something simple - my pid variable that I passed into the call had a newline in it! Trouble was I didn't see this in my debug log because I guess vlc strips them out. I did not notice this until first trying to write the contents of the command to a batch file. I later sanitized the pid variable and sure enough all good. My troubleshooting code for reference.

    local sanitized_pid = job_pid:gsub("%s+", "")
    local batch_file = system_directory .. "\\abort_job.bat"
    local batch_content = "powershell -Command \"Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq " .. sanitized_pid .. " } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }\"\n"
    local file = io.open(batch_file, "w")
    if file then
        file:write(batch_content)
        file:close()
        os.execute(batch_file)
    else
        vlc.msg.err("Failed to create batch file for aborting job.")
    end
Share Improve this question edited Mar 12 at 15:23 dtmland asked Mar 12 at 8:41 dtmlanddtmland 2,2384 gold badges24 silver badges51 bronze badges 2
  • 1 Why did you add ^ before |? – shingo Commented Mar 12 at 8:44
  • @shingo Saw others doing it, thought I would need it, and it does work in some of the cmd.exe calls… – dtmland Commented Mar 12 at 8:46
Add a comment  | 

1 Answer 1

Reset to default 2
  • When calling a command from cmd.exe / a batch file, metacharacters such as | only need escaping as ^| if they are outside of (what cmd.exe sees as) "..."-enclosed strings.

  • Since you're passing the PowerShell code to execute via the -Command parameter to powershell.exe, the Windows PowerShell CLI, enclosed in "...", you must therefore not use ^-escaping (as the ^ chars. would then be passed through to PowerShell and break the command):

-- ^ instances removed
os.execute("powershell -Command \"Get-WmiObject Win32_Process | Where-Object { $_.ParentProcessId -eq " .. pid .. " } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }\"")
发布评论

评论列表(0)

  1. 暂无评论