1 (изменено: lichy, 2009-10-16 13:31:32)

Тема: VBScript: Ожидание процесса

Здравствуйте.

Взял из коллекции код для слежения за процессами - и он у меня не выполняется полностью.
Создал процесс - получил его PID... Но процесс еще выполняется - а скрипт начинает выполняться дальше.

Кто может подсказать, в чем ошибка ?

'===================================================
' слежение за установкой
'===================================================
Set WshShell = CreateObject ("WSCript.shell")
act = "C:\setup.exe"
PID = WshShell.Exec(act).ProcessID


Set WMI = GetObject("winmgmts:\\.\root\cimv2")
Set colProcesses = WMI.ExecNotificationQuery _
("Select * From __InstanceDeletionEvent Within 1 Where TargetInstance ISA 'Win32_Process'")
Do Until 1 = 2
    Set objProcess = colProcesses.NextEvent
    If objProcess.TargetInstance.ProcessID = PID Then
       Exit Do
    End If
Loop
MsgBox "Установлено успешно" 

'===================================================
' руссификация
'===================================================
'Set WshShell = CreateObject("WScript.Shell")

act =  "cd /d "  & PathRus
runbar =  "set_stds.bat " &" "& Path & " " & PathRus

Set WshExec = WshShell.Exec("cmd.exe /q /k echo off")
WshExec.StdIn.WriteLine "chcp 1251>nul"
WshExec.StdIn.WriteLine act 
WshExec.StdIn.WriteLine runbar
WshExec.StdIn.WriteLine "exit"

MsgBox "Русифицировано"

2

Re: VBScript: Ожидание процесса

А что Вы хотите получить в итоге? Вам нужно запустить процесс и дождаться его завершения?

3

Re: VBScript: Ожидание процесса

Интересно, а если так попробовать?...

Set WMI = GetObject("winmgmts:\\.\root\cimv2")
Set colProcesses = WMI.ExecNotificationQuery ("Select * From __InstanceDeletionEvent Within 1 Where TargetInstance ISA 'Win32_Process'")
    WScript.Sleep(500)

Set WshShell = CreateObject ("WSCript.shell")
act = "C:\setup.exe"
PID = WshShell.Exec(act).ProcessID
    WScript.Sleep(500)

Do Until 1 = 2
    Set objProcess = colProcesses.NextEvent
    If objProcess.TargetInstance.ProcessID = PID Then
       Exit Do
    End If
Loop
'...

4

Re: VBScript: Ожидание процесса

alexii пишет:

А что Вы хотите получить в итоге? Вам нужно запустить процесс и дождаться его завершения?

Нужно запустить процесс, он занимает около 30 - 40 минут, и после завершения - запустить другой процесс...
В этом скрипте - почему то не дожидается завершения...

5

Re: VBScript: Ожидание процесса

WshShell.Run

Option Explicit

Dim objWshShell

Set objWshShell = WScript.CreateObject("WScript.Shell")

objWshShell.Run """%systemroot%\notepad.exe"" ""c:\boot.ini""", 1, True
objWshShell.Run """%systemroot%\system32\ping.exe"" -t localhost", 1, True

Set objWshShell = Nothing

WScript.Quit 0

6 (изменено: lichy, 2009-10-19 11:39:53)

Re: VBScript: Ожидание процесса

alexii пишет:

WshShell.Run

Option Explicit

Dim objWshShell

Set objWshShell = WScript.CreateObject("WScript.Shell")

objWshShell.Run """%systemroot%\notepad.exe"" ""c:\boot.ini""", 1, True
objWshShell.Run """%systemroot%\system32\ping.exe"" -t localhost", 1, True

Set objWshShell = Nothing

WScript.Quit 0

Спасибо, только это не решает проблему
Так же возвращает сигнал о завершении процесса, а в Диспетчере задач процесс отображается...
А второй процесс нельзя запускать, пока 1 не завершится

7

Re: VBScript: Ожидание процесса

Все еще бьюсь над этой задачей....:/
Почему процесс может посылать сигнал о завершении. а при этом еще выполняться?

8

Re: VBScript: Ожидание процесса

Не может. Давайте конкретику, что за процессы.

P.S. Один из них случайно не Консультант+?!

9

Re: VBScript: Ожидание процесса

alexii пишет:

Не может. Давайте конкретику, что за процессы.

P.S. Один из них случайно не Консультант+?!

Нет, не Консультант. его русифицировать не надо

1 процесс -- установка ... "ptsetup.exe" в диспетчере задач
        Запуская через команду Run (.,0,True) через 5 минут примерно получаю результат о завершении процесса
        Запуская с подхватыванием PID и дальнейшим отслеживанием события уничтожения процесса - те же 5 минут

2 После завершения установки я должен запустить процедуру копирования файлов из одной папки - в созданные в процессе установки. Это реализовано в .bat файле. Его запускаю с помощью Exec()

Но так как дождаться окончания установки не могу -- то копирование не возможно.

10

Re: VBScript: Ожидание процесса

Проверяйте ProcessMonitor'ом кто кого когда за кем запускает.

Инструкция по инсталляции и работе с PocketTrade | Ай Ти Инвест, ptsetup.exe — эта инсталляция?

11

Re: VBScript: Ожидание процесса

alexii пишет:

Проверяйте ProcessMonitor'ом кто кого когда за кем запускает.

Инструкция по инсталляции и работе с PocketTrade | Ай Ти Инвест, ptsetup.exe — эта инсталляция?

ptsetup = это инсталяция...

А при чем PocketTrade ?

И ProcessMonitor - не подходит, так как нужно все реализовать стандартными средствами Windows

12

Re: VBScript: Ожидание процесса

lichy, на всякий случай, повторюсь, если я был недостаточно понятен:
1. Что это за приложение? Как называется, где про него можно прочитать?
2. Если Вы никак не хотите отвечать на первый вопрос: Process Monotor'ом Вы сами должны отследить, что происходит при запуске инсталляции, а именно: какие процессы порождаются, как протекают, в какой последовательности и т.п. Потому что, такого, как Вы озвучили в #6, быть не может. И я подозреваю, что Вы следите не за тем процессом.

13

Re: VBScript: Ожидание процесса

Добрый день.
облазил пол инета, по гуглил неудачно, в яндексе пошарился, пол форума поиском пролазил. Не знаю как правильно искать ответ на такой вот простенький вопрос.

Есть 1с 7.7. Есть необходимость обновлять каждый день копию. Но копию не всегда получается обновить, так как бывает что люди не выходят из базы. И блокируется файл "1Cv7.LCK". Вот думал написать скрипт который узнает какой именно "1cv7.exe" его использует и запершить данный процесс.
Как завершить нужный процесс я уже изучил, по его PID. а вот узнать его пит из WBS я пока не научился. помогите пожалуйста разобраться с этим вопросом.

14

Re: VBScript: Ожидание процесса

2lawyerly, то есть кто то будет работать в базе, а вы его хоп, и отрубите?
Может копировать на живую? Например с помощью такой вот программы, или лучше установите автоматические бэкапер, пусть он сам по расписанию работает.

Нас невозможно сбить с пути, нам пофигу куда идти.

15 (изменено: lawyerly, 2010-11-19 15:51:52)

Re: VBScript: Ожидание процесса

2DnsIs
Этот процесс проходит ночью. над копией базы. так что работать в ней в это время просто ни кто не должен. Так что его надо принудительно хлоп, удалить всю базу, залить новую и проиндексировать.
Всё остальное реализовал, кроме этого.

16

Re: VBScript: Ожидание процесса

lawyerly, в WSH нет способа узнать, какой из процессов блокирует тот или иной файл. Если Вас устроит использование сторонних приложений, тогда возможно сие проделать. У Вас

…удалить всю базу, залить новую и проиндексировать.

делается на WSH или на CMD/BAT?

В любом случае, придётся пользовать внешние утилиты [для случая удалённого открытия файлов по сети есть и встроенные варианты — с закрытием открытых файлов, но, естественно, без снятия удалённого процесса], например, Handle или OpenedFilesView, используя в том и в другом случае фильтр по полному имени файла «1Cv7.LCK». Если Вам достаточно только снять приложение — обойдётесь одной строкой, если ещё нужно предварительно сохранить имя пользователя, открывшего процесс 1С — немного сложнее.

Пробуйте.

17

Re: VBScript: Ожидание процесса

alexii пишет:

делается на WSH или на CMD/BAT?

изначально на WSH.
Когда дохожу до удаления. Проверяет на наличие файла "1Cv7.LCK". Если он есть, то запускаю батник с кодом:

D:\copy\handle.exe D:\copy\comp\1cv7.lck > D:\copy\logs.txt

Делаю паузу в скрипте 2000 и получаю текстовый файл:

Handle v3.42
Copyright (C) 1997-2008 Mark Russinovich
Sysinternals - www.sysinternals.com

1cv7.exe           pid: 3728     18: D:\copy\comp\1Cv7.LCK

Вот тут не могу найти как мне получить этот самый PID в переменную, что бы убить процесс. Поможите кто чем может.

18

Re: VBScript: Ожидание процесса

Можно так:

Option Explicit

' Enum WshExecStatus
Const WshRunning  = 0
Const WshFinished = 1
Const WshFailed   = 2


Dim objWshShell
Dim objWshExec

Dim objRegExp

Dim strFile

Dim strOut
Dim strErr
Dim strLine

Dim objMatch


strFile = "C:\2222.doc"
'strFile = "D:\copy\comp\1cv7.lck"

Set objWshShell = WScript.CreateObject("WScript.Shell")
Set objWshExec  = objWshShell.Exec("""c:\Program Files\Handle\handle.exe"" -u """ & strFile & """")

If objWshExec.Status <> WshFailed Then
    strOut = ""
    strErr = ""
    
    Do Until objWshExec.Status = WshFinished
        strOut = strOut & objWshExec.StdOut.ReadAll
        strErr = strErr & objWshExec.StdErr.ReadAll
        
        WScript.Sleep 100
    Loop
    
    For Each strLine In Split(strOut, vbCrLf)
        If InStr(strLine, strFile) Then
            With WScript.CreateObject("VBScript.RegExp")
                .IgnoreCase = True
                .Pattern = "^.+ pid: (\d+) +(.+\\.+?) +.+$"
                
                For Each objMatch In .Execute(strLine)
                    WScript.Echo "PID: ", objMatch.SubMatches(0)
                    WScript.Echo "User:", objMatch.SubMatches(1)
                Next
                
            End With
        End If
    Next
End If

Set objWshExec  = Nothing
Set objWshShell = Nothing

WScript.Quit 0

19

Re: VBScript: Ожидание процесса

Спасибо большое. Немного подправил под себя и заработало
Могли бы расписать код?
мне не понятны некоторые куски.

Option Explicit - ? Так как этот код встраивался в другой, у меня ругался на эту строчку. за комментировал, но остался вопрос дл ячего это используется?

Enum WshExecStatus - что это такое?

Почему надо объявлять переменные Dim -ом? Про Set я разобрался, а про дим и просто простое присваивание не понял

Do Until objWshExec.Status = WshFinished
        strOut = strOut & objWshExec.StdOut.ReadAll
        strErr = strErr & objWshExec.StdErr.ReadAll
        
        WScript.Sleep 100
    Loop

этот кусок кода вообще не понял ни Do Unti ... Loop ни что присваивается переменным.

For Each strLine In Split(strOut, vbCrLf)
        If InStr(strLine, strFile) Then
            With WScript.CreateObject("VBScript.RegExp")
                .IgnoreCase = True
                .Pattern = "^.+ pid: (\d+) +(.+\\.+?) +.+$"
                
                For Each objMatch In .Execute(strLine)
                    WScript.Echo "PID: ", objMatch.SubMatches(0)
                    WScript.Echo "User:", objMatch.SubMatches(1)
                Next
                
            End With
        End If
Next

For Each strLine In Split(strOut, vbCrLf) присваиваем переменной strLine каждую строку полученную из обращения к Handle, Split - разбирает массив на подстроки, где strOut - массив полученных данных, vbCrLf - маска как обрабатывать строки.
InStr - ищет совподения в тексте. strLine - где ищет , strFile - что ищет.

.IgnoreCase = True
.Pattern = "^.+ pid: (\d+) +(.+\\.+?) +.+$"

вот тут примерно понимаю, но если поясните буду признателен.

                For Each objMatch In .Execute(strLine)
                    WScript.Echo "PID: ", objMatch.SubMatches(0)
                    WScript.Echo "User:", objMatch.SubMatches(1)
                Next

Понимаю что получаем, но не понимаю как

20

Re: VBScript: Ожидание процесса

lawyerly пишет:

Option Explicit - ? Так как этот код встраивался в другой, у меня ругался на эту строчку. за комментировал, но остался вопрос дл ячего это используется?

Отсюда и ниже. Крайне рекомендуется к применению.

lawyerly пишет:

Enum WshExecStatus

'Enum WshExecStatus

Просто комментарий для констант ниже. Набор констант, перечисленных ниже, составляет перечисление «WshExecStatus».

lawyerly пишет:

Почему надо объявлять переменные Dim -ом?

См. выше про «Option Explicit».

lawyerly пишет:

Этот кусок кода вообще не понял

If objWshExec.Status <> WshFailed Then ' Если статус задания не «неудачный запуск», то…
    strOut = ""
    strErr = ""
    
    Do Until objWshExec.Status = WshFinished ' Пока статус задания не равен «задание завершено»…
        strOut = strOut & objWshExec.StdOut.ReadAll ' Добавляем в переменную strOut очередную порцию из выходного потока задания
        strErr = strErr & objWshExec.StdErr.ReadAll ' Добавляем в переменную strErr очередную порцию из потока ошибок задания
        
        WScript.Sleep 100 ' Ждём
    Loop
lawyerly пишет:

вот тут примерно понимаю, но если поясните буду признателен.

Шаблон, по которому производится поиск. Скобками группируем то, что нужно будет впоследствии выбрать.
Метод «.Execute()» возвращает коллекцию Matches, которую перебираем по одному объекту в цикле. «.SubMatches()» — это то, что попало в скобки шаблона.