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

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

vk_k14m@vk 03-06-2018 10:33 2816638

Скрипт для авто выключения одного приложения при ручном выключении другого (.exe)
 
Использую подобный скрипт:
Код:

@ECHO OFF
START "" Program.exe
ping 127.0.0.1 -n 15 >nul
START "" Program2.exe

Тоесть когда я запускаю скрипт, то он сразу запускает приложение Program.exe, после чего через 15 секунд запускает "вспомогательное" приложение Program2.exe. Далее нужно сделать, что б после выключения приложения Program.exe скрипт автоматически, через 15 секунд выключал и "вспомогательное" приложение Program2.exe.

И еще, если можно. Нужно сделать что б этот скрипт как-то скрывался. Сворачивался в трей или еще чего. Что б окно командной строки не маячило перед глазами.

YuS_2 03-06-2018 12:20 2816655

Цитата:

Цитата vk_k14m@vk
через 15 секунд выключал и "вспомогательное" приложение Program2.exe. »

Выключал - громко сказано. Всё что умеет чистый cmd - "убивать" приложения командой taskkill. Если устроит - это организовать несложно.
Что-то другое, т.е. для корректного завершение работы, а также для скрытия окна CMD - как минимум, понадобится WSH, powershell или внешние приложения...

mwz 03-06-2018 13:21 2816668

Цитата:

Цитата vk_k14m@vk
Что[]б окно командной строки не маячило перед глазами. »

Делайте не пакетный файл, а VB-скрипт. Им же организуете и убиение процесса через заданное время.
И тогда никаких пингов — а штатная директива Sleep, не отнимающая у системы лишнее время на обработку.

Iska 03-06-2018 13:59 2816671

Цитата:

Цитата YuS_2
Всё что умеет чистый cmd - "убивать" приложения командой taskkill. »

Вообще-то, нет: именно taskkill.exe (без использования параметра /f) делает попытку закрытия главного окна приложения (путём отсылки сообщения). WSH этого не умеет (в Вашей трактовке — умеет только «убивать» процесс).

vk_k14m@vk 03-06-2018 14:10 2816673

Цитата:

Цитата mwz
Делайте не пакетный файл, а VB-скрипт. Им же организуете и убиение процесса через заданное время.
И тогда никаких пингов — а штатная директива Sleep, не отнимающая у системы лишнее время на обработку. »

Мне не нужно убиение процесса через заданное время. Мне нужно убиение второго процесса когда первый процесс завершается. Так как этот процесс может длится 20 минут, а может 6 часов. Время его работы не фиксировано. Грубо говоря, когда я закрываю первое приложение, второе тоже должно закрыться. Не важно каким способом.

Цитата:

Цитата mwz
Делайте не пакетный файл, а VB-скрипт. Им же организуете и убиение процесса через заданное время.
И тогда никаких пингов — а штатная директива Sleep, не отнимающая у системы лишнее время на обработку. »

Я без понятия что такое VB-скрипт.

gannet 03-06-2018 15:44 2816687

Цитата:

Цитата vk_k14m@vk
Мне нужно убиение второго процесса когда первый процесс завершается »

Это можно сделать, добавив параметр /wait к старту первой программы, но тогда, скорее всего, придется запускать вторую программу предварительно дополнительным батником со своим таймером)))

vk_k14m@vk 03-06-2018 15:48 2816688

Цитата:

Цитата gannet
Это можно сделать, добавив параметр /wait к старту первой программы, но тогда, скорее всего, придется запускать вторую программу предварительно дополнительным батником со своим таймером))) »

Я знаю что так можно сделать. Но такой вариант мне не подходит.

Можно вообще вручную запускать обе программы а потом вручную обе закрывать.

YuS_2 03-06-2018 16:17 2816695

Цитата:

Цитата Iska
именно taskkill.exe (без использования параметра /f) делает попытку закрытия главного окна приложения (путём отсылки сообщения). »

Верно, это я перепутал с mortscript-ом, там kill именно kill... давно не пользовался... :)
Цитата:

Цитата Iska
WSH этого не умеет »

Хмм, почему-то думал, что там есть CloseMainWindow()...
Ну, тогда powershell поможет...

Цитата:

Цитата vk_k14m@vk
Я знаю что так можно сделать. Но такой вариант мне не подходит. »

Тогда зациклить мониторинг наличия процесса через каждые 15 сек и закрывать вторую программу, если первая не обнаруживается. Но батник будет резидентом, т.е. постоянно находиться в памяти, до закрытия второго процесса.

vk_k14m@vk 03-06-2018 16:24 2816696

А ладно. Забейте. Как то это слишком сложно...

megaloman 03-06-2018 17:24 2816702

vbs
Код:

PrgDir1 = "D:\Games\Marriage V2.3"
PrgExe1 = "marriage.exe"

PrgDir2 = "D:\Games\BUBBLES3"
PrgExe2 = "BS3.EXE"

Paus = 15  'Пауза сек

Set WMI = GetObject("winMgmts:")
Set WShell = CreateObject("WScript.Shell")

' Если PrgExe1 запущен, убъем его
Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + PrgExe1 + """")
For Each Process In Processes
    Process.Terminate
Next

' Запустим PrgExe1
WShell.CurrentDirectory = PrgDir1
R1 = WShell.Run(PrgExe1, 7, False)

WScript.Sleep Paus * 1000

' Если PrgExe1 запустилась, запустим PrgExe2
Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + PrgExe1 + """")
If Processes.Count > 0 Then
    WShell.CurrentDirectory = PrgDir2
    R2 = WShell.Run(PrgExe2, 7, False)
Else
    WScript.Quit 1
End If

' Опрашиваем. Если нет PrgExe1 убъем PrgExe2 и завершим скрипт
Do
    WScript.Sleep Paus * 1000
    Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + PrgExe1 + """")
    If Processes.Count = 0 Then
        Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + PrgExe2 + """")
        For Each Process In Processes
            Process.Terminate
        Next
        Exit Do
    End If
Loop

MsgBox "Нет " + PrgExe1 + " и " + PrgExe2 + ".  Скрипт завершен"


YuS_2 03-06-2018 18:04 2816705

Цитата:

Цитата vk_k14m@vk
Как то это слишком сложно... »

Нет там ничего сложного...

run.bat
Код:

@echo off
start "" "program.exe"

:loop
>nul timeout /t 15
tasklist /fi "imagename eq program2.exe"|>nul find /i "program2.exe"||start "" "program2.exe"
tasklist /fi "imagename eq program.exe"|>nul find /i "program.exe"&&goto loop||goto close
goto loop

:close
taskkill /fi "imagename eq program2.exe"

для скрытого запуска:
hide.vbs
Код:

Set oTmp=CreateObject("WScript.Shell")
for n = 2 to WScript.Arguments.count
  Args = Args & " " & WScript.Arguments(n-1)
next

oTmp.Run WScript.Arguments(0) & Args, 0, False

Создаёте ярлык со следующей строкой запуска:
Код:

wscript.exe //nologo hide.vbs "run.bat"
и запускаете через него.

vk_k14m@vk 04-06-2018 15:21 2816789

Цитата:

Цитата YuS_2
run.bat
Код:

@echo off
start "" "program.exe"
:loop
>nul timeout /t 15
tasklist /fi "imagename eq program2.exe"|>nul find /i "process2.exe"||start "" "program2.exe"
tasklist /fi "imagename eq program.exe"|>nul find /i "process1.exe"&&goto loop||goto close
goto loop
:close
taskkill /fi "imagename eq program2.exe"

»

Не работает, и вот почему. Про запуске program.exe и program2.exe запускаются не одноименные процессы. Эти программы что-то вроде лаунчеров. Которые запускают process.exe и process2.exe.

И еще. Не понятно что значит "imagename eq program.exe"?

Цитата:

Цитата YuS_2
для скрытого запуска:
hide.vbs
Код:

Set oTmp=CreateObject("WScript.Shell")
for n = 2 to WScript.Arguments.count
 Args = Args & " " & WScript.Arguments(n-1)
next
oTmp.Run WScript.Arguments(0) & Args, 0, False

Создаёте ярлык со следующей строкой запуска:
Код:

wscript.exe //nologo hide.vbs "run.bat"
и запускаете через него. »


YuS_2 04-06-2018 20:09 2816845

Цитата:

Цитата vk_k14m@vk
Про запуске program.exe и program2.exe запускаются не одноименные процессы. Эти программы что-то вроде лаунчеров. Которые запускают process.exe и process2.exe. »

Какие были условия, такое и решение.
Цитата:

Цитата vk_k14m@vk
когда я запускаю скрипт, то он сразу запускает приложение Program.exe, после чего через 15 секунд запускает "вспомогательное" приложение Program2.exe. Далее нужно сделать, что б после выключения приложения Program.exe скрипт автоматически, через 15 секунд выключал и "вспомогательное" приложение Program2.exe. »

Нет?
Приведите в соответствие названия процессов и всё будет работать

Цитата:

Цитата vk_k14m@vk
Не понятно что значит "imagename eq program.exe"? »

Код:

tasklist /?
taskkill /?


По поводу скрипта hide.vbs:
А так:
Код:

Set oTmp=CreateObject("WScript.Shell")
oTmp.Run WScript.Arguments(0), 0, False

?

vk_k14m@vk 04-06-2018 20:35 2816848


Как я уже говорил, забейте. Ваши скрипты только сильнее лагают. Буду пользоваться тем что сам собрал и вручную выключать приложения...

megaloman 04-06-2018 22:33 2816860

vk_k14m@vk, Итак, как я понимаю Вашу задачу после обсуждения непоняток:
vbs
1. Запускается первая программа PrgExe1 которая запускает процесс Prc1
2. Запускается вторая программа PrgExe2 которая запускает процесс Prc2
3. Пауза. Отслеживается наличие Prc1.
4. Если Prc1 отсутствует, убиваем Prc2. Завершаем скрипт.
5. Иначе возвращаемся на 3.

Код:

PrgDir1 = "D:\Program Files\MTA Province"        ' Папка с первой программой
PrgExe1 = "MTA\MTA.exe"                ' Exe-файл первой программы
Prc1 = "proxy_sa.exe"                        ' Процесс запущенный первой программой       

PrgDir2 = "C:\Program Files (x86)\Bandicam"                ' Папка со второй программой
PrgExe2 = "Loader.exe"                        ' Exe-файл второй программы
Prc2 = "bdcam.exe"                        ' Процесс запущенный второй программой       

Paus = 15  'Пауза сек

Set WMI = GetObject("winMgmts:")
Set WShell = CreateObject("WScript.Shell")

' Если Prс1 запущен, убъем его
Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + Prc1 + """")
For Each Process In Processes
    Process.Terminate
Next

' Запустим PrgExe1
WShell.CurrentDirectory = PrgDir1
R1 = WShell.Run("""" + PrgDir1 + "\" + PrgExe1 + """", 7, False)

WScript.Sleep Paus * 1000

' Если Prс1 запустилась, запустим PrgExe2
Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + Prc1 + """")
If Processes.Count > 0 Then
    WShell.CurrentDirectory = PrgDir2
    R2 = WShell.Run("""" + PrgDir2 + "\" + PrgExe2 + """", 7, False)
Else
    Msg = "Текущая папка" + vbCrLf + WShell.CurrentDirectory  + vbCrLf + vbCrLf
    MsgBox Msg + "Запуск" + vbCrLf + """" + PrgDir1 + "\" + PrgExe1 + """" + vbCrLf + "не запустил процесс" + vbCrLf + """" + Prc1 + """"
    WScript.Quit 1
End If

' Опрашиваем. Если нет Prс1 убъем Prс2 и завершим скрипт
Do
    WScript.Sleep Paus * 1000
    Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + Prc1 + """")
    If Processes.Count = 0 Then
        Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + Prc2 + """")
        For Each Process In Processes
            Process.Terminate
        Next
        Exit Do
    End If
Loop

MsgBox "Нет " + Prc1 + " и " + Prc2 + ".  Скрипт завершен"

Пропишите правильно папки программ, имена экзешников, имена процессов, ими запускаемых
Если постановка задачи иная, не томите, изложите подробно и четко. При кривой постановке скрипты обязательно, как Вы говорите, будут лагать. И придётся забить - на корзину работать нет охоты.

vk_k14m@vk 04-06-2018 23:04 2816868

Цитата:

Цитата megaloman
Если постановка задачи иная, не томите, изложите подробно и четко. При кривой постановке скрипты обязательно, как Вы говорите, будут лагать. И придётся забить - на корзину работать нет охоты. »

Постановка правильна.
Цитата:

1. Запускается первая программа "D:\Program Files\MTA Province\MTA\MTA.exe" которая запускает процесс "D:\Program Files\MTA Province\proxy_sa.exe"
2. Запускается вторая программа "C:\Program Files (x86)\Bandicam\Loader.exe" которая запускает процесс "C:\Program Files (x86)\Bandicam\bdcam.exe"
3. Пауза. Отслеживается наличие "D:\Program Files\MTA Province\proxy_sa.exe".
4. Если "D:\Program Files\MTA Province\proxy_sa.exe" отсутствует, убиваем "C:\Program Files (x86)\Bandicam\bdcam.exe". Завершаем скрипт.
5. Иначе возвращаемся на 3.
Такс. Создал файл "start.vbs", вписал в него такой текст:
Код:

PrgDir1 = "D:\Program Files\MTA Province"        ' Папка с первой программой
PrgExe1 = "MTA\MTA.exe"                ' Exe-файл первой программы
Prc1 = "proxy_sa.exe"                        ' Процесс запущенный первой программой       

PrgDir2 = "C:\Program Files (x86)\Bandicam"                ' Папка со второй программой
PrgExe2 = "Loader.exe"                        ' Exe-файл второй программы
Prc2 = "bdcam.exe"                        ' Процесс запущенный второй программой       

Paus = 15  'Пауза сек

Set WMI = GetObject("winMgmts:")
Set WShell = CreateObject("WScript.Shell")

' Если Prс1 запущен, убъем его
Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + Prc1 + """")
For Each Process In Processes
    Process.Terminate
Next

' Запустим PrgExe1
WShell.CurrentDirectory = PrgDir1
R1 = WShell.Run(PrgExe1, 7, False)

WScript.Sleep Paus * 1000

' Если Prс1 запустилась, запустим PrgExe2
Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + Prc1 + """")
If Processes.Count > 0 Then
    WShell.CurrentDirectory = PrgDir2
    R2 = WShell.Run(PrgExe2, 7, False)
Else
    WScript.Quit 1
End If

' Опрашиваем. Если нет Prс1 убъем Prс2 и завершим скрипт
Do
    WScript.Sleep Paus * 1000
    Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + Prc1 + """")
    If Processes.Count = 0 Then
        Set Processes = WMI.ExecQuery("Select *From Win32_Process Where Name=" + """" + Prc2 + """")
        For Each Process In Processes
            Process.Terminate
        Next
        Exit Do
    End If
Loop

MsgBox "Нет " + Prc1 + " и " + Prc2 + ".  Скрипт завершен"

сохранил. При запуске скрипта такая ошибка.

YuS_2 04-06-2018 23:06 2816869

Цитата:

Цитата vk_k14m@vk
Как я уже говорил »

Для того, чтобы скрипт работал правильно, необходимо: правильно прописывать пути к запускаемым им программам (в данном случае run.bat), либо он должен находиться в одном каталоге с ними (тогда путь указывать необязательно, только наименование).
В общем, если кратко: поместите ярлык, скрипт hide.vbs и пакетник run.bat в один каталог. Предварительно проверьте работу пакетника, он должен работать самостоятельно, а после всех проверок и наладки, запускайте в скрытом режиме.

Цитата:

Цитата vk_k14m@vk
Ваши скрипты только сильнее лагают. »

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

vk_k14m@vk 04-06-2018 23:17 2816872

Цитата:

Цитата YuS_2
Для того, чтобы скрипт работал правильно, необходимо: правильно прописывать пути к запускаемым им программам (в данном случае run.bat), либо он должен находиться в одном каталоге с ними (тогда путь указывать необязательно, только наименование).
В общем, если кратко: поместите ярлык, скрипт hide.vbs и пакетник run.bat в один каталог. Предварительно проверьте работу пакетника, он должен работать самостоятельно, а после всех проверок и наладки, запускайте в скрытом режиме. »

Не поверишь, ярлык, скрипт и батник и так лежат в одной папке. Только скрипт выдает ошибку когда запускаю ярлык. А батник не завершает второй процесс при завершении первого.

YuS_2 04-06-2018 23:37 2816876

Цитата:

Цитата vk_k14m@vk
А батник не завершает второй процесс при завершении первого. »

Естественно, т.к. после уточнения:
Цитата:

Цитата vk_k14m@vk
Постановка правильна. »

он явно должен быть другим :)
Код:

@echo off
set "prg1=D:\Program Files\MTA Province\MTA\MTA.exe"
set "prg2=C:\Program Files (x86)\Bandicam\Loader.exe"
set "prc1=proxy_sa.exe"
set "prc2=bdcam.exe"

start "" "%prg1%"

:loop
>nul timeout /t 15
tasklist /fi "imagename eq %prc2%"|>nul find /i "%prc2%"||start "" "%prg2%"
tasklist /fi "imagename eq %prc1%"|>nul find /i "%prc1%"&&goto loop||goto close
goto loop

:close
taskkill /fi "imagename eq %prc2%"

а hide.vbs поправьте так:
Код:

Set oTmp=CreateObject("WScript.Shell")
oTmp.Run """" & WScript.Arguments(0) & """", 0, False

Затем в ярлыке укажите абсолютные пути к самому hide.vbs и run.bat
Код:

wscript.exe //nologo "D:\здесь путь к папке где он находится\hide.vbs" "E:\здесь путь к папке где он находится\run.bat"
- в таком варианте им не обязательно находится в одном каталоге.

PS На всякий случай: "батник" сохраняйте в кодировке 866, скрипт vbs в кодировке 1251... для исключения проблем с кириллицей в путях...

Iska 04-06-2018 23:56 2816880

Цитата:

Цитата vk_k14m@vk
Не работает, и вот почему. Про запуске program.exe и program2.exe запускаются не одноименные процессы. Эти программы что-то вроде лаунчеров. Которые запускают process.exe и process2.exe. »

Начинают выясняться антиресные подробности ;).

Цитата:

Цитата megaloman
Если постановка задачи иная, не томите, изложите подробно и четко. При кривой постановке скрипты обязательно, как Вы говорите, будут лагать. И придётся забить - на корзину работать нет охоты. »

Работать можно. Токмо за отдельную оплату. После этого, как правило, и техзадание рождается быстро, и детали излагаются чётко.


Цитата:

Цитата YuS_2
Код:

wscript.exe //nologo …
»

Для wscript.exe параметр //nologo не требуется.

YuS_2 04-06-2018 23:59 2816882

Цитата:

Цитата Iska
Токмо за отдельную оплату. »

почасовую :)
тогда да: и быстро , и четко.

YuS_2 05-06-2018 00:15 2816887

Хмм... удалил, после уточнений, ибо не совсем понятно будет...

megaloman 05-06-2018 00:22 2816888

vk_k14m@vk, Я исправил скрипт под открывшиеся тонкости задачи. Возьмите его заново. Естественно, с такими данными полноценно протестировать скрипт я не могу ...

YuS_2 05-06-2018 00:30 2816889

Цитата:

Цитата Iska
Для wscript.exe параметр //nologo не требуется. »

Да, наверное... но это уже привычка... :)

vk_k14m@vk 05-06-2018 00:47 2816890

Цитата:

Цитата YuS_2
он явно должен быть другим »

Эх. Запуск первого приложения происходит. Запуск второго тоже. Но завершение второго процесса все же нет. Что я делаю не так?
В скрипте же написано
Код:

set "prc2=bdcam.exe"

...

:close
taskkill /fi "imagename eq %prc2%"

Но этот процесс не хочет завершатся


Я убрал из ярлыка //nologo и естественно запускаю от имени администратора. Но этот процесс не хочет убиваться. Хотя просто в командной строке от имени админа прекрасно убивается.
Код:

taskkill /f /im bdcam.exe
Я даже пытался в скрипт это добавлять
Код:

:close
taskkill /f /fi /im "imagename eq %prc2%"

Все равно, не хочет он закрываться.

Еще вопрос, окно командной строки, если запускать не через ярлык, должно все время быть на виду пока не убьет процесс? У меня оно открывается и закрывается как раз перед запускам первого приложения.

vk_k14m@vk 05-06-2018 01:08 2816897

Цитата:

Цитата megaloman
Я исправил скрипт под открывшиеся тонкости задачи. Возьмите его заново. Естественно, с такими данными полноценно протестировать скрипт я не могу ... »

"Исправленный" скрипт перестал запускать второе приложение.

Ну его нафиг

YuS_2 05-06-2018 01:32 2816901

Цитата:

Цитата vk_k14m@vk
Я даже пытался в скрипт это добавлять
Код:

:close
taskkill /f /fi /im "imagename eq %prc2%"

Все равно, не хочет он закрываться. »

Так не совсем правильно...
Попробуйте эту строку:
Код:

taskkill /f /t /fi "imagename eq %prc2%"
Цитата:

Цитата vk_k14m@vk
Еще вопрос, окно командной строки, если запускать не через ярлык, должно все время быть на виду пока не убьет процесс? У меня оно открывается и закрывается как раз перед запускам первого приложения.»

Да, консоль должна закрываться только после выполнения taskkill. Если у Вас она закрывается раньше, то, соответственно, что-то работает неправильно.
1. Замените в начале пакетного сценария off на on
2. Откройте отдельную консоль: Win+R и команда cmd
3. Из этой открытой консоли вызовите пакетный сценарий run.bat и смотрите, что происходит во время его выполнения.

Ну и заодно покажите результат
Код:

tasklist /fi "imagename eq bdcam*"
только сначала запустите нужные задачи (обе программы) без батника, вручную.


Время: 18:35.

Время: 18:35.
© OSzone.net 2001-