<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; VBScript: асинхронная обработка множественных запросов WMI]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=3783&amp;type=atom" />
	<updated>2009-10-29T12:55:17Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=3783</id>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: асинхронная обработка множественных запросов WMI]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=29867#p29867" />
			<content type="html"><![CDATA[<p>Развитие предыдущего примера. Одновременно выполняются не все запросы, а только часть. Как только завершается обработка очередного запроса — делается следующий запрос.<br /></p><div class="codebox"><pre><code>Option Explicit

Dim arrComputers
Dim strComputer

Dim objSWbemServicesEx
Dim objSWbemSink
Dim objSWbemNamedValueSet

Dim lngCount
Dim lngQueueCurrLength, lngQueueMaxLength
Dim i


&#039; Массив адресов/имён опрашиваемых машин
&#039; В принципе, можно получать из сетевого окружения, с контроллера домена
&#039; или перебором доступных адресов подсети
arrComputers = Array(&quot;google.com&quot;, &quot;www.ru&quot;, &quot;127.0.0.1&quot;, &quot;server&quot;, &quot;scite.net.ru&quot;, &quot;ya.ru&quot;, &quot;script-coding.com&quot;, &quot;ixbt.com&quot;)

&#039; Максимальная длина очереди (в данном примере — сколько машин будут пинговаться одновременно),
&#039; выбирается произвольно
lngQueueMaxLength  = 3
&#039; Текущая длина очереди
lngQueueCurrLength = 0

lngCount = UBound(arrComputers)
i = 0

Set objSWbemServicesEx = GetObject(&quot;winmgmts:{impersonationLevel=impersonate}!\\.\Root\CIMV2&quot;)
Set objSWbemSink       = WScript.CreateObject(&quot;WbemScripting.SWbemSink&quot;, &quot;Sink_&quot;)

While (i &lt;= lngCount) Or (lngQueueCurrLength &gt; 0) &#039; Пингуем пока не кончатся компы и очередь
    If (i &lt;= lngCount) And (lngQueueCurrLength &lt; lngQueueMaxLength) Then
        WScript.Echo &quot;&gt; [&quot; &amp; i &amp; &quot;] &quot; &amp; arrComputers(i) &#039; Добавляем очередной комп в очередь для пинга
        
        &#039; В коллекции «objSWbemNamedValueSet» будем передавать адрес/имя хоста (замечание: в данном конкретном случае
        &#039; сие, в принципе, необязательно, поскольку класс Win32_PingStatus и так содержит
        &#039; свойство «.Address», но тут показана сама технология передачи данных в процедуру асинхронной обработки)
        Set objSWbemNamedValueSet = WScript.CreateObject(&quot;WbemScripting.SWbemNamedValueSet&quot;)
        objSWbemNamedValueSet.Add &quot;HostName&quot;, arrComputers(i)
        
        &#039; Все запросы будут обрабатываться в единственной процедуре обработки
        objSWbemServicesEx.ExecQueryAsync objSWbemSink, &quot;SELECT * FROM Win32_PingStatus WHERE ADDRESS = &#039;&quot; &amp; arrComputers(i) &amp; &quot;&#039;&quot;, , , , objSWbemNamedValueSet
        
        i = i + 1
        lngQueueCurrLength = lngQueueCurrLength + 1
    Else
        &#039; Ожидаем, пока не будут обработаны все асинхронные запросы
        WScript.Sleep 100
    End If
Wend

objSWbemSink.Cancel

Set objSWbemSink       = Nothing
Set objSWbemServicesEx = Nothing

WScript.Quit 0
&#039;=============================================================================

&#039;=============================================================================
&#039; Процедура асинхронной обработки экземпляра объекта (замечание: в данном конкретном случае
&#039; будет возвращаться единственный объект, однако, в большинстве случаев запросы
&#039; возвращают множество объектов)
Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext)
    Dim strComputer
    
    strComputer = objWbemAsyncContext.Item(&quot;HostName&quot;)
    
    If Not IsNull(objWbemObject.StatusCode) Then
        If objWbemObject.StatusCode = 0 Then
            WScript.Echo &quot;  &quot; &amp; strComputer &amp; vbTab &amp; &quot;On&quot; &amp; vbTab &amp; &quot;Response time: &quot; &amp; objWbemObject.ResponseTime &amp; &quot; ms&quot;
        Else
            WScript.Echo &quot;  &quot; &amp; strComputer &amp; vbTab &amp; &quot;Off&quot; &amp; vbTab &amp; &quot;Status code: &quot; &amp; objWbemObject.StatusCode
        End If
    Else
        WScript.Echo &quot;  &quot; &amp; strComputer &amp; vbTab &amp; &quot;Not found&quot;
    End If
End Sub
&#039;=============================================================================

&#039;=============================================================================
&#039; Процедура, вызываемая при завершении асинхронной обработки
Sub Sink_OnCompleted(iHResult, objWbemErrorObject, objWbemAsyncContext)
    objWbemAsyncContext.DeleteAll
    Set objWbemAsyncContext = Nothing
    
    &#039; Уменьшаем длину очереди
    lngQueueCurrLength = lngQueueCurrLength - 1
    &#039;lngCount = lngCount - 1
End Sub
&#039;=============================================================================</code></pre></div><p>Автор идеи — <strong>mozers</strong>.</p>]]></content>
			<author>
				<name><![CDATA[alexii]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=1844</uri>
			</author>
			<updated>2009-10-29T12:55:17Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=29867#p29867</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[VBScript: асинхронная обработка множественных запросов WMI]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=29552#p29552" />
			<content type="html"><![CDATA[<p><strong>Асинхронная обработка множественных запросов WMI на примере «Win32_PingStatus»</strong></p><p>Данный скрипт квази-одновременно, за счёт асинхронной обработки, посылает пинги по адресам, указанным в массиве arrComputers, и получает результат.</p><p>Эффективно при мониторинге большого количества сетевой аппаратуры, что позволяет <em>намного</em> быстрее получить общую картину происходящего, в отличие от использования последовательного опроса.<br /></p><div class="codebox"><pre><code>Option Explicit

Dim arrComputers
Dim strComputer

Dim objSWbemServicesEx
Dim objSWbemSink
Dim objSWbemNamedValueSet

Dim lngCount


&#039; Массив адресов/имён опрашиваемых машин
&#039; В принципе, можно получать из сетевого окружения, с контроллера домена
&#039; или перебором доступных адресов подсети
arrComputers = Array(&quot;google.com&quot;, &quot;www.ru&quot;, &quot;localhost&quot;, &quot;test&quot;)
lngCount     = UBound(arrComputers) + 1

Set objSWbemServicesEx = GetObject(&quot;winmgmts:{impersonationLevel=impersonate}!\\.\Root\CIMV2&quot;)
Set objSWbemSink       = WScript.CreateObject(&quot;WbemScripting.SWbemSink&quot;, &quot;Sink_&quot;)

For Each strComputer In arrComputers
    &#039; В коллекции «objSWbemNamedValueSet» будем передавать адрес/имя хоста (замечание: в данном конкретном случае
    &#039; сие, в принципе, необязательно, поскольку класс Win32_PingStatus и так содержит
    &#039; свойство «.Address», но тут показана сама технология передачи данных в процедуру асинхронной обработки)
    Set objSWbemNamedValueSet = WScript.CreateObject(&quot;WbemScripting.SWbemNamedValueSet&quot;)
    objSWbemNamedValueSet.Add &quot;HostName&quot;, strComputer
    
    &#039; Все запросы будут обрабатываться в единственной процедуре обработки
    objSWbemServicesEx.ExecQueryAsync objSWbemSink, &quot;SELECT * FROM Win32_PingStatus WHERE ADDRESS = &#039;&quot; &amp; strComputer &amp; &quot;&#039;&quot;, , , , objSWbemNamedValueSet
Next

&#039; Ожидаем, пока не будут обработаны все асинхронные запросы
Do
    WScript.Sleep 100
Loop Until lngCount = 0

objSWbemSink.Cancel

Set objSWbemSink       = Nothing
Set objSWbemServicesEx = Nothing

WScript.Quit 0
&#039;=============================================================================

&#039;=============================================================================
&#039; Процедура асинхронной обработки экземпляра объекта (замечание: в данном конкретном случае
&#039; будет возвращаться единственный объект, однако, в большинстве случаев запросы
&#039; возвращают множество объектов)
Sub Sink_OnObjectReady(objWbemObject, objWbemAsyncContext)
    Dim strComputer
    
    strComputer = objWbemAsyncContext.Item(&quot;HostName&quot;)
    
    If Not IsNull(objWbemObject.StatusCode) Then
        If objWbemObject.StatusCode = 0 Then
            WScript.Echo strComputer &amp; vbTab &amp; &quot;On&quot; &amp; vbTab &amp; &quot;Response time: &quot; &amp; objWbemObject.ResponseTime &amp; &quot; ms&quot;
        Else
            WScript.Echo strComputer &amp; vbTab &amp; &quot;Off&quot; &amp; vbTab &amp; &quot;Status code: &quot; &amp; objWbemObject.StatusCode
        End If
    Else
        WScript.Echo strComputer &amp; vbTab &amp; &quot;Not found&quot;
    End If
End Sub
&#039;=============================================================================

&#039;=============================================================================
&#039; Процедура, вызываемая при завершении асинхронной обработки
Sub Sink_OnCompleted(iHResult, objWbemErrorObject, objWbemAsyncContext)
    objWbemAsyncContext.DeleteAll
    Set objWbemAsyncContext = Nothing
    
    &#039; Уменьшаем счётчик оставшегося числа асинхронных обработок
    lngCount = lngCount - 1
End Sub
&#039;=============================================================================</code></pre></div><p>Автор идеи — <strong>Евген</strong>. Посильное участие, прочие плодотворные идеи и тестирование — <strong>kiber_punk</strong>, <strong>Dmitrii</strong>, <strong>Xameleon</strong>, <strong>mozers</strong>, <strong>alexii</strong>.</p>]]></content>
			<author>
				<name><![CDATA[alexii]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=1844</uri>
			</author>
			<updated>2009-10-21T11:24:59Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=29552#p29552</id>
		</entry>
</feed>
