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
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 }\"")