Завершение процессов, не указанных в списке
Доброго времени суток, уважаемые. Не так давно мне пришлось решить задачу, требующую завершения всех процессов, кроме указанных в "белом списке". Написал вот такой скрипт, он работает, но есть одна неувязочка - в белый список приходится вносить и процесс cmd.exe, чтобы скрипт не прерывал свою же работу. Хотелось же, чтобы скрипт завершал работу всех остальных запущенных процессов cmd.exe (если такие будут обнаружены) кроме своего собственного. Не могу понять, как подступится к проблеме, может кто поможет? И еще, кажется что в скрипте слишком много "костылей", буду рад любым советам по упрощению\оптимизации.
Код:
@Echo Off
SetLocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
Call :CheckOS
If %ErrorLevel%==1 Exit /B
:: Файл со списком разрешённых процессов
Set #WhitelistFile=%~sdp0whitelist.txt
:: Чтение файла со списком разрешённых процессов
:ReadList
Set /A i=0
For /F "tokens=*" %%l in (%#WhitelistFile%) Do (
Set /A i+=1
Set _Whitelist!i!=%%l
)
Set Whitelist_strings=!i!
:: Получение списка процессов (кроме System и System Idle)
:GetProcList
Set ProcList_Strings=0
For /F "tokens=1,2* skip=4 delims=," %%P In ('tasklist /FO CSV') Do (
Call :Add Proclist %%~P
)
Call :Purge whitelist
Call :Purge proclist
Call :Compare
EndLocal
Exit /B
:: Вывод содержимого списка
:: (не используется, для отладки)
:Dump
Set $ListName=%*
Set /A #StrCount=!%$ListName%_strings!
Echo.
Echo ==[%$ListName%]=======:
For /L %%S In (1,1,%#StrCount%) Do (
Echo [%%S] !_%$ListName%%%S!
)
Echo.
Exit /B 0
:: Сравнение списков, завершение не разрешенных процессов
:Compare
For /L %%S In (1,1,%Proclist_strings%) Do (
Set $TmpStringData=!_Proclist%%S!
Set isUnknown=True
For /L %%S In (1,1,%Whitelist_strings%) Do (
Set $WhitelistString=!_Whitelist%%S!
If !$TmpStringData!==!$WhitelistString! Set isUnknown=False
)
If !isUnknown!==True taskkill /F /IM "!$TmpStringData!"
)
Exit /B 0
:: Добавка строки
:Add
Set $ListName=
Set $ListString=
For /F "tokens=1,* delims= " %%n In ("%*") Do (
Set $ListName=%%n
Set $ListString=%%~o
)
Set /A $StrCount=!%$ListName%_strings!
Set /A $StrCount+=1
Set _%$ListName%%$StrCount%=%$ListString%
Set %$ListName%_strings=%$StrCount%
Exit /B 0
:: Очистка от одинаковых строк
:Purge
Set $ListName=%*
Set /A #StrCount=!%$ListName%_strings!
:PurgeLoop
Set /A $TmpStringNum=0
For /L %%S In (1,1,%#StrCount%) Do (
Set $TmpStringNum=%%S
Set $TmpStringData=!_%$ListName%%%S!
For /L %%D In (1,1,%#StrCount%) Do (
If Not %%D==!$TmpStringNum! (
If "!_%$ListName%%%D!"=="!$TmpStringData!" Call :Delete %$ListName% %%D&&GoTo PurgeLoop
)
)
)
Exit /B 0
:: Удаление строки, сдвиг номеров следующих за ней
:Delete
Set $ListName=
Set $ListStringNum=
For /F "tokens=1,* delims= " %%n In ("%*") Do (
Set $ListName=%%n
Set $ListStringNum=%%o
)
Set /A #StrCount=!%$ListName%_strings!
Set /A i=0
For /L %%S In (1,1,%#StrCount%) Do (
If Not %%S==%$ListStringNum% Set /A i+=1
If Not %%S==%$ListStringNum% Set _%$ListName%!i!=!_%$ListName%%%S!
)
Set _%$ListName%%#StrCount%=
Set %$ListName%_strings=%i%
Exit /B 0
:: Проверка на версию ОС (На Win7 и Vista скрипт не проверялся,
:: поэтому и запускаться он там не будет)
:CheckOS
For /F "tokens=1,2* delims=[" %%A In ('ver') Do (
Set $TmpString=%%B
For /F "tokens=1,2* delims= " %%A In ("!$TmpString!") Do (
Set $TmpString=%%B
For /F "tokens=1,2* delims=]" %%A In ("!$TmpString!") Do (
Set $TmpString=%%A
For /F "tokens=1,2,3 delims=." %%A In ("!$TmpString!") Do (
Set VerMajor=%%A
Set VerMinor=%%B
Set VerBuild=%%C
)
)
)
)
Set bCompatibleOS=false
Echo 5.0 5.1|findstr /R "\<!VerMajor!.!VerMinor!\>">nul&&Set bCompatibleOS=true
If %bCompatibleOS%==false (
ChCp 866>nul
Echo.
Echo Ваша операционная система не поддерживается
Echo Для выхода нажмите любую кнопку...
Echo.
Pause>nul
Exit /B 1
)
Exit /B 0
UPD 28.03.12:
Добавлен усовершенствованный вариант этого скрипта, работающий без WMIC для тех, кому по какой-то причине не подходит вариант от amel27
http://forum.oszone.net/post-1888484-3.html
|