Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Батник на выключение батника при включении определенных программах (http://forum.oszone.net/showthread.php?t=350989)

mr.djdig@vk 04-04-2022 00:47 2982699

Батник на выключение батника при включении определенных программах
 
Доброго времени, Господа. Есть проблема, не хватает серого вещества у меня на ее решение.

В общем, есть батник запускаемый под вин10 через планировщик задач при запуске компа, задача состоит в том, чтобы написать батник, который вырубал бы его при включении определенных программ из списка.

Как я себе это представляю, оба батника запускаются через планировщик, один рабочий самый первый, второй просто постоянно находится в фоне и ничего не делает основное время, в нем внутри находится список программ-триггеров, второй батник закрывает полностью первый, и вот как это реализовать знаний моих не хватает.
Основной список программ триггеров скорее всего, steam, chrome, gamecenter, wgc, uplay. Сейчас все происходит посредством запуска второго батника на рабочем столе с taskkill /IM FSR.bat /F. Автоматический запуск первого батника реализован через тот же планировщик задач при простое ПК.

На данный момент я додумал только вот такое. Но что-то я не правильно сделал... При включенном браузере например или стиме, пейнт не закрывается
Код:

@Echo
SetLocal EnableExtensions
:KOK
Set ProcessName1=steam.exe
Set ProcessName2=chrome.exe
Set ProcessName3=wgc.exe
Set ProcessName4=gamecenter.exe

TaskList /FI "ImageName EQ %ProcessName1%" | Find /I "steam.exe"
TaskList /FI "ImageName EQ %ProcessName2%" | Find /I "chrome.exe"
TaskList /FI "ImageName EQ %ProcessName3%" | Find /I "wgc.exe"
TaskList /FI "ImageName EQ %ProcessName4%" | Find /I "gamecenter.exe"

If %ErrorLevel% EQU 1 goto KOK
If %ErrorLevel% EQU 1 taskkill /IM mspaint.exe /F
pause


megaloman 04-04-2022 18:03 2982743

mr.djdig@vk, Я бы предложил другой подход:
Запускаем "один рабочий самый первый батник" через vbs-скрипт.
В том же скрипте задан список тех процессов, при появлении любого из них убиваем "один рабочий самый первый батник"
При этом, естественно vbs-скрипт завершается.
Если до запуска скрипта процессы из списка были запущены, батник убит не будет, батник убивается только при появлении процессов после запуска скрипта.
Код:

Option Explicit
Dim Bat, MgmProc, WMIcmd, WMIout, ProcessID, SQL, Processes, Process

Bat = "CMD /C ""Z:\Box_In\batfile.bat"""
MgmProc = Array("notepad.exe", "calc.exe", "mspaint.exe")

Set WMIcmd = GetObject("WinMgmts:\\.\Root\CIMV2:Win32_Process")
WMIout = WMIcmd.Create("CMD /C ""Z:\Box_In\batfile.bat""", Null, Null, ProcessID)

Call ProcEvent(MgmProc)

SQL = "Select *From Win32_Process Where processid=" + CStr(ProcessID)
Set Processes = GetObject("winMgmts:").ExecQuery(SQL)

For Each Process In Processes
    Process.Terminate
Next

Sub ProcEvent(MgmProc)
    Dim MgmWhere, i, i1, SQL
    Dim objEventSource, objEvent
   
    i1 = LBound(MgmProc)
    SQL = "TargetInstance.Name='" + MgmProc(i1) + "'"
   
    For i = i1 + 1 To UBound(MgmProc)
        SQL = SQL + "OR TargetInstance.Name='" + MgmProc(i) + "'"
    Next
   
    SQL = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process' AND (" + SQL + ")"
    Set objEventSource = GetObject("WinMgmts:\\.\Root\CIMV2").ExecNotificationQuery(SQL)
    Set objEvent = objEventSource.NextEvent
End Sub

Если "один рабочий самый первый батник" необходимо запустить в скрытом окне
Код:

Option Explicit
Dim Bat, WMIconfig, MgmProc, WMIcmd, WMIout, ProcessID, SQL, Processes, Process

Bat = "CMD /C ""Z:\Box_In\batfile.bat"""
MgmProc = Array("notepad.exe", "calc.exe", "mspaint.exe")

Set WMIcmd = GetObject("WinMgmts:\\.\Root\CIMV2:Win32_Process")
Set WMIconfig = GetObject("WinMgmts:\\.\Root\CIMV2").Get("Win32_ProcessStartup").SpawnInstance_
WMIconfig.ShowWindow = 12

WMIout = WMIcmd.Create("CMD /C ""Z:\Box_In\batfile.bat""", Null, WMIconfig, ProcessID)

Call ProcEvent(MgmProc)

SQL = "Select *From Win32_Process Where processid=" + CStr(ProcessID)
Set Processes = GetObject("winMgmts:").ExecQuery(SQL)

For Each Process In Processes
    Process.Terminate
Next

Sub ProcEvent(MgmProc)
    Dim MgmWhere, i, i1, SQL
    Dim objEventSource, objEvent
   
    i1 = LBound(MgmProc)
    SQL = "TargetInstance.Name='" + MgmProc(i1) + "'"
   
    For i = i1 + 1 To UBound(MgmProc)
        SQL = SQL + "OR TargetInstance.Name='" + MgmProc(i) + "'"
    Next
   
    SQL = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process' AND (" + SQL + ")"
    Set objEventSource = GetObject("WinMgmts:\\.\Root\CIMV2").ExecNotificationQuery(SQL)
    Set objEvent = objEventSource.NextEvent
End Sub


mr.djdig@vk 06-04-2022 18:08 2982827

Добрый вечер/день, не было возможности зайти в тему посмотреть ответы. В первую очередь спасибо за них) Попробую вариант с запуском через vbs.

Цитата:

Цитата megaloman
Если до запуска скрипта процессы из списка были запущены, батник убит не будет »

Вот на счет этого проблемка, если полностью описывать ситуацию, причина по которой запуск батника происходит именно через планировщик и при старте системы, батник при таком раскладе запускается от системы с повышенным приоритетом и без вида самой консоли. В первоначальном коде msplain.exe использовалась мной как заглушка вместо этого самого батника тк он использует exe файл как основу и на ней я тестировал правильно ли работает мой скрипт.

Сама суть задачи этого батника и причины, домашний ПК используется в вычислительных операциях, дабы домочадцы в виде малых лет детей и не особо разбирающихся взрослых ничего не понатыкали и/или случайно не выключили, используется так же планировщик который запустит все это дело. А вот в моменты когда на ПК выполняются какие либо ресурсозатратные задачи по типу игрушек, работы итд, нужен второй батник для завершения первого батника, как-то так. Попробую реализовать это через vbs который так же будет запускаться при простое, возможно? Сам особо в vbs не знаю, ранее использовалось все так, что в винде было два пользователя и когда нужно было, заходили под второй учеткой и там все делали, а уже в первой просто первый батник стоял на автозагрузке через ярлык, но сейчас это стало не очень удобно тк нужна автоматизация и автономность в моменты когда я не дома.

megaloman 06-04-2022 20:02 2982831

mr.djdig@vk, Вам не надо запускать программу батником, если он состоит только из одной строки Start. Напрямую VBS. Но это не решит задачу повторного запуска этого процесса.

Wraith33 08-04-2022 22:33 2982934

я делал так:
tasklist | find "Far.exe"
if errorlevel 1 goto Start_1
if errorlevel 0 goto Goto OS
:Start_1
выполняем что хотели...
Goto OS
:OS
exit

mr.djdig@vk 12-04-2022 16:47 2983142

Так, в общем то, я вроде как с помощью костылей небольших разобрался как это сделать! Всем спасибо за помощь!
Код:

@echo off
:1
tasklist | find "steam.exe"
IF %ERRORLEVEL% neq 0 goto 2
If %ERRORLEVEL% neq 1 taskkill /IM mspaint.exe /F
:2
tasklist | find "GameCenter.exe"
IF %ERRORLEVEL% neq 0 goto 3
If %ERRORLEVEL% neq 1 taskkill /IM mspaint.exe /F
:3
tasklist | find "wgc.exe"
IF %ERRORLEVEL% neq 0 goto 4
If %ERRORLEVEL% neq 1 taskkill /IM mspaint.exe /F
:4
tasklist | find "chrome.exe"
IF %ERRORLEVEL% neq 0 goto 1
If %ERRORLEVEL% neq 1 taskkill /IM mspaint.exe /F
goto 1
pause


megaloman 13-04-2022 10:14 2983193

mr.djdig@vk, Показанный Вами батник - не очень хорошая идея, он будет грузить процессор. И где повторный запуск главного процесса?
Цитата:

Цитата megaloman
Вам не надо запускать программу батником »

Вместо Вашей задачи я использовал для отладки mspaint.exe, привёл пример её запуска с параметрами - именем файла, у Вас его нет. Вы для отладки можете указать свой файл. В боевом режиме - реальную программу.
Как работает:
Вы запускаете скрипт планировщиком.
1. Если у Вас не запущена основная программа (сейчас - mspaint.exe) и все программы из списка, запускаем основную программу.
2. Скрипт ждет появления одной из программ из списка
3. Как только такая программа появляется - основная программа убивается.
4. Скрипт в цикле с паузой (не надо излишне грузить процессор) опрашивает начиная с п.1 и, пока хоть одна программа из списка присутствует, основная программа запущена не будет.
Код:

Option Explicit

Dim PgmMain: PgmMain = "mspaint.exe"
Dim PgmStart: PgmStart = """mspaint.exe"" ""D:\CMD_Forum\Box_In\Лаб-4.png"""

Dim PauseMsec: PauseMsec = 15000

Dim MgmProc
MgmProc = Array("steam.exe", "GameCenter.exe", "wgc.exe", "chrome.exe")

Dim WMIcmd, WMIout, i, SQuery, Processes, Process
Dim WSH, Ret
Set WSH = CreateObject("WScript.Shell")

SQuery = "Select *From Win32_Process Where Name=""" + PgmMain + """"
For Each Ret In MgmProc
    SQuery = SQuery + " or Name=""" + Ret + """"
Next

Do
    Set Processes = GetObject("winMgmts:").ExecQuery(SQuery)
    If Processes.Count = 0 Then
'''''''''''''''''''''''''''''''''''        Ret = WSH.Run(PgmStart, 1, False)
        Ret = WSH.Run(PgmStart, 0, False)
        WScript.Sleep (4000)
        Call ProcEvent(MgmProc)
        Do
            Set Processes = GetObject("winMgmts:").ExecQuery("Select *From Win32_Process Where Name=""" + PgmMain + """")
            For Each Process In Processes
                Process.Terminate
            Next
        Loop While Processes.Count > 0
    End If
    WScript.Sleep (PauseMsec)
Loop

Sub ProcEvent(MgmProc)
    Dim MgmWhere, i, i1, SQL
    Dim objEventSource, objEvent
   
    i1 = LBound(MgmProc)
    SQL = "TargetInstance.Name='" + MgmProc(i1) + "'"
   
    For i = i1 + 1 To UBound(MgmProc)
        SQL = SQL + "OR TargetInstance.Name='" + MgmProc(i) + "'"
    Next
   
    SQL = "SELECT * FROM __InstanceCreationEvent WITHIN 2 WHERE TargetInstance ISA 'Win32_Process' AND (" + SQL + ")"
    Set objEventSource = GetObject("WinMgmts:\\.\Root\CIMV2").ExecNotificationQuery(SQL)
    Set objEvent = objEventSource.NextEvent
End Sub

Программа запускается Ret = WSH.Run(PgmStart, 0, False). 0 отвечает за скрытый режим. Если для отладки надо видеть запускаемую программу, поставьте 1.
В скрипте работает бесконечный цикл, сам он не завершится. Если зачем-то его надо завершить - в диспетчере задач убейте процесс wscript.exe


Время: 23:48.

Время: 23:48.
© OSzone.net 2001-