Tôi tin rằng những điều sau đây là chống đạn, miễn là người dùng có quyền truy cập vào các điểm WMIC và TEMP đến một đường dẫn hợp lệ nơi người dùng có đặc quyền ghi. Đây là kết quả cuối cùng của một số công việc hợp tác tại http://www.dostips.com/forum/viewtopic.php?f=3&t=6133 .
@echo off
:getPID [RtnVar]
::
:: Store the Process ID (PID) of the currently running script in environment variable RtnVar.
:: If called without any argument, then simply write the PID to stdout.
::
setlocal disableDelayedExpansion
:getLock
set "lock=%temp%\%~nx0.%time::=.%.lock"
set "uid=%lock:\=:b%"
set "uid=%uid:,=:c%"
set "uid=%uid:'=:q%"
set "uid=%uid:_=:u%"
setlocal enableDelayedExpansion
set "uid=!uid:%%=:p!"
endlocal & set "uid=%uid%"
2>nul ( 9>"%lock%" (
for /f "skip=1" %%A in (
'wmic process where "name='cmd.exe' and CommandLine like '%%<%uid%>%%'" get ParentProcessID'
) do for %%B in (%%A) do set "PID=%%B"
(call )
))||goto :getLock
del "%lock%" 2>nul
endlocal & if "%~1" equ "" (echo(%PID%) else set "%~1=%PID%"
exit /b
Kịch bản thiết lập một khóa độc quyền trên một tệp tạm thời kết hợp thời gian hiện tại vào tên. Chỉ có thể có xung đột nếu hai quá trình giống như được đặt tên cố gắng để có được PID trong cùng khoảng thời gian 0,01 giây, trong trường hợp đó chỉ có một quá trình sẽ thành công.
Bất kỳ quá trình nào không thành công sẽ lặp lại nhiều lần và thử lại với đường dẫn tệp khóa mới cho đến khi thành công.
Đường dẫn đầy đủ đến tệp khóa được chuyển thành ID duy nhất có thể được sử dụng trong truy vấn WMIC. WMIC được chạy trong lệnh FOR / F, có nghĩa là nó đang chạy trong tiến trình cmd.exe con. Đó là lý do tại sao ParentProcessID của quá trình cmd.exe được truy xuất.