<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; VBScript & WMI: ограничение времени работы выбранных процессов]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=5081</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=5081&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «VBScript & WMI: ограничение времени работы выбранных процессов».]]></description>
		<lastBuildDate>Sat, 23 Oct 2010 13:11:29 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[VBScript & WMI: ограничение времени работы выбранных процессов]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=40763#p40763</link>
			<description><![CDATA[<p>Данный скрипт создан для того, чтобы детей ограничивать в провождении времени за играми на компьютере. Ограничение времени даётся на одни сутки. В массив процессов заносятся имена файлов от игр. Данный скрипт логирует все удачные либо неудачные (после истечения лимита времени) запуски игр.<br />Лог создаётся в папке запуска скрипта в файл PlayTime.log<br /></p><div class="codebox"><pre><code>Public strPrevent       &#039; флаг запрета запуска
Public arrProcesses     &#039; массив процессов
Public LogFile
Const ForAppending = 8
Const HKEY_CURRENT_USER = &amp;H80000001
strPause=3000           &#039; значение паузы 3 секунды
strPauseTime=&quot;00:00:03&quot; &#039; тоже самое в формате времени
TimeLimit=&quot;00:45:00&quot;    &#039; ограничение шпильного времени 45 минут 
strKeyPath = &quot;Software\proc_monitor&quot;                          &#039; ветка реестра где будет производиться учёт
Set FileSytemObject = CreateObject(&quot;Scripting.FileSystemObject&quot;) 
ParentFolderName = FileSytemObject.GetParentFolderName(Wscript.ScriptFullName) 
LogFile = FileSytemObject.BuildPath(ParentFolderName,&quot;PlayTime.log&quot;) 

arrProcesses=Array(&quot;IceAge2pc.exe&quot;,&quot;dirt2.exe&quot;,&quot;DiRT.exe&quot;,&quot;speed.exe&quot;,&quot;Game.exe&quot;,&quot;iceage3.exe&quot;,&quot;Tumblebugs.exe&quot;,&quot;FarmFrenzy3_America.wrp.exe&quot;,&quot;FerrariVR.exe&quot;,&quot;MTX.exe&quot;,&quot;FarmFrenzy3.wrp.exe&quot;,&quot;motogp2.exe&quot;,&quot;TmForever.exe&quot;,&quot;FarmFrenzy3_Arctica.exe&quot;)

strComputer = &quot;.&quot;
Set oReg=GetObject(&quot;winmgmts:{impersonationLevel=impersonate}!\\&quot; &amp; strComputer &amp; &quot;\root\default:StdRegProv&quot;)
Set objWMIService = GetObject(&quot;winmgmts:\\&quot; &amp; strComputer &amp; &quot;\root\CIMV2&quot;) 
Set WshShell = CreateObject(&quot;WScript.Shell&quot;)

On Error Resume Next                                         &#039; включаем обработку ошибок
WshShell.RegRead &quot;HKEY_CURRENT_USER\Software\proc_monitor\&quot;  &#039; проверяем, есть ли такая ветка реестра
If Err.Number&lt;&gt;0 Then
Err.Clear
On Error Goto 0                                               &#039; отключаем обработку ошибок
oReg.CreateKey HKEY_CURRENT_USER,strKeyPath                   &#039; если нет - то создаём ветку
oReg.CreateKey HKEY_CURRENT_USER,strKeyPath &amp; &quot;\CurrDate&quot;     &#039; создаём веточку для даты
oReg.SetStringValue HKEY_CURRENT_USER,strKeyPath &amp; &quot;\CurrDate&quot;,&quot;strDate&quot;,CStr(DateValue(Date)) &#039; прописываем сегоднящнюю дату
End If



      &#039; сейчас будем синхронизировать список процессов в скрипте и реестре

strValue = &quot;00:00:00&quot;  &#039; нулевое время
oReg.EnumValues HKEY_CURRENT_USER, strKeyPath,arrValueNames

If IsNull(arrValueNames) Then               &#039; в реестре всё пусто, надо заполнять списком

For Each Process in arrProcesses
oReg.SetStringValue HKEY_CURRENT_USER,strKeyPath,Process,strValue
Next

Else                                        &#039; если учёт ранее вёлся


  &#039; Синхронизация реестра к массиву
  &#039; лишнее из реестра удаляется

For r=0 to UBound(arrValueNames)
strFlag=0                            &#039; флаг совпадения наименования процесса
For n=0 to UBound(arrProcesses)
If arrValueNames(r)=arrProcesses(n) Then
strFlag=1
Exit For
End If
Next

If strFlag=0 Then                     &#039; если совпадения нет - то удаляем
oReg.DeleteValue HKEY_CURRENT_USER,strKeyPath,arrValueNames(r)
End If

Next


  &#039; Синхронизация массива к реестру
  &#039; недостающие процессы дописываются в реестр

For r=0 to UBound(arrProcesses)
strFlag=0                            &#039; флаг совпадения наименования процесса
For n=0 to UBound(arrValueNames)
If arrProcesses(r)=arrValueNames(n) Then
strFlag=1
Exit For
End If
Next

If strFlag=0 Then             &#039; если совпадения нет - то дописываем в реестр
oReg.SetStringValue HKEY_CURRENT_USER,strKeyPath,arrProcesses(r),strValue
End If

Next

End if



                               &#039;   ОСНОВНОЙ ЦИКЛ

&#039; асинхронный обработчик на создание процесса
Set SINKC = WScript.CreateObject(&quot;WbemScripting.SWbemSink&quot;,&quot;SINKC_&quot;)
objWMIService.ExecNotificationQueryAsync SINKC, &quot;SELECT * FROM __InstanceCreationEvent WITHIN 3 WHERE TargetInstance ISA &#039;Win32_Process&#039;&quot;

&#039; асинхронный обработчик на удаление процесса
Set SINKT = WScript.CreateObject(&quot;WbemScripting.SWbemSink&quot;,&quot;SINKT_&quot;)
objWMIService.ExecNotificationQueryAsync SINKT, &quot;SELECT * FROM __InstanceDeletionEvent WITHIN 3 WHERE TargetInstance ISA &#039;Win32_Process&#039;&quot;

Do While 1=1

&#039;   I  считывание, сравнение даты, обнуление счётчиков при смене даты

oReg.GetStringValue HKEY_CURRENT_USER,strKeyPath &amp; &quot;\CurrDate&quot;,&quot;strDate&quot;,strDate  &#039; считываем дату последнего учёта

If DateValue(strDate)&lt;&gt;DateValue(Date) Then                                       &#039; если даты не совпадают
For Each Process in arrProcesses
oReg.SetStringValue HKEY_CURRENT_USER,strKeyPath,Process,strValue                 &#039; то обнуляем счётчики отработанного времени у всех процессов
Next
oReg.SetStringValue HKEY_CURRENT_USER,strKeyPath &amp; &quot;\CurrDate&quot;,&quot;strDate&quot;,CStr(DateValue(Date)) &#039; прописываем сегоднящнюю дату
   &#039; логируем смену даты
   Set LogF = FileSytemObject.OpenTextFile(LogFile, ForAppending, True) 
   LogF.WriteLine String(25,&quot;-&quot;) &amp; &quot;  &quot; &amp; DateValue(Date) &amp; &quot;  &quot; &amp; String(25,&quot;-&quot;)
   LogF.Close
End If

&#039;  II  расчёт суммарного шпильного времени

sumTime=&quot;00:00:00&quot;

For Each Process in arrProcesses
oReg.GetStringValue HKEY_CURRENT_USER,strKeyPath,Process,strTime
sumTime=TimeValue(sumTime) + TimeValue(strTime)
Next

&#039;  III  сравниваем &quot;выработанное&quot; время с лимитным и устанавливаем флаг запрета шпиля

If TimeValue(sumTime)&gt;=TimeValue(TimeLimit) Then
strPrevent=1                                       &#039; ЗАПРЕЩЕНО
Else
strPrevent=0                                       &#039; РАЗРЕШЕНО
End If

&#039;  IV   учёт времени работы процессов из списка и убивание процессов при выставленном флаге

Set colItems = objWMIService.ExecQuery(&quot;SELECT * FROM Win32_Process&quot;) 
For Each objItem in colItems 
strOut=0           &#039; обнуление флага выхода из цклов в начале первичного цикла For
   For Each Process in arrProcesses
     If LCase(objItem.Name)=LCase(Process) Then                                                                  &#039; если процесс из списка работает
              &#039; если флаг запрета запуска выставлен - то убиваем процессы из списка
       If strPrevent=1 Then  
           objItem.Terminate
      &#039; здесь логируем здесь логируем принудительно закрытый процесс
   Set LogF = FileSytemObject.OpenTextFile(LogFile, ForAppending, True) 
   LogF.WriteLine Now &amp; &quot; принудительно закрыт процесс: &quot; &amp; LCase(Process)
   LogF.Close
           Exit For
       Else
          oReg.GetStringValue HKEY_CURRENT_USER,strKeyPath,Process,strTime
          oReg.SetStringValue HKEY_CURRENT_USER,strKeyPath,Process,CStr(TimeValue(strTime)+TimeValue(strPauseTime))    &#039; то к его времени прибавляем время паузы
           strOut=1   &#039; флаг выхода из цикла вложенного For при встрече любого первого процесса
           Exit For
       End If
     End If
   Next
If strOut=1 Then   &#039; в соответствии с флагом выхода выходим из первичного цикла For
     Exit For
End If
Next

Wscript.Sleep strPause
Loop


      &#039;  асинхронный убийца при запуске

Sub SINKC_OnObjectReady(objLatestEvent, objAsyncContext)  

   For Each Process in arrProcesses
   If LCase(Process)=LCase(objLatestEvent.TargetInstance.Name) Then

   If strPrevent=1 Then    &#039; при запуске убиваем процессы из списка при запрещающем флаге
   objLatestEvent.TargetInstance.Terminate

   &#039; здесь логируем предотвращённый запуск
   Set LogF = FileSytemObject.OpenTextFile(LogFile, ForAppending, True) 
   LogF.WriteLine Now &amp; &quot; предотвращен запуск: &quot; &amp; objLatestEvent.TargetInstance.Name
   LogF.Close
   Exit Sub
   End If

   &#039; здесь логируем разрешённый запуск
   Set LogF = FileSytemObject.OpenTextFile(LogFile, ForAppending, True) 
   LogF.WriteLine Now &amp; &quot; запущен процесс: &quot; &amp; objLatestEvent.TargetInstance.Name
   LogF.Close

   End If
   Next

End Sub



&#039; логирование при закрытии процесса

Sub SINKT_OnObjectReady(objLatestEvent, objAsyncContext)  

   For Each Process in arrProcesses
   If LCase(Process)=LCase(objLatestEvent.TargetInstance.Name) Then
   If strPrevent&lt;&gt;1 Then  &#039; если этот флаг не учитывать - то будет проходить двойное логирование (принудительное и потом нормальное)
   Set LogF = FileSytemObject.OpenTextFile(LogFile, ForAppending, True) 
   LogF.WriteLine Now &amp; &quot; нормально закрыт процесс: &quot; &amp; objLatestEvent.TargetInstance.Name
   LogF.Close
   End If
   End If
   Next

End Sub</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Евген)]]></author>
			<pubDate>Sat, 23 Oct 2010 13:11:29 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=40763#p40763</guid>
		</item>
	</channel>
</rss>
