Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/16: Рейтинг темы: голосов - 16, средняя оценка - 4.88
5472 / 1150 / 50
Регистрация: 15.09.2012
Сообщений: 3,576

Создание события в WBEM (WMI)

18.03.2013, 19:31. Показов 3210. Ответов 12
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приведите пример кода на VBA, который выдаёт сообщение, когда в очереди печати принтера появлятеся распечатываемый документ.


Примечание

WBEM и WMI - одно и то же, просто разные названия.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
18.03.2013, 19:31
Ответы с готовыми решениями:

[C#+WMI]Можно ли через WMI узнать температуру процессора и ядер?
Можно ли через WMI узнать температуру процессора и ядер? Щас лопачу сайты вожусь но русскоязычной документации по WMI нету :( А тем...

Поставщик HiPerfCooker_v1 зарегистрирован в пространстве имен WMI Root\WMI с правами локальной системы
Поставщик HiPerfCooker_v1 зарегистрирован в пространстве имен WMI Root\WMI с правами локальной системы. Это может привести к нарушениям...

Создание объекта-события и обработчика события
Допустим у меня есть следующий класс: public class Example { private boolean bool; public boolean isBool() { return bool;...

12
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
20.03.2013, 02:31
WBEM нужен только для подключения. Но можно и в обход него, встроенными средствами самого WMI.

Здесь тоже самое писал: Печать с использованием функции Shell

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Sub main()
    Dim WMI As Object, Jobs As Object, Job
    
    Set WMI = GetObject("WinMgmts:{impersonationLevel=impersonate}!\\.\Root\CIMv2")
 
    Do
        DoEvents
        Set Jobs = WMI.ExecQuery("SELECT * FROM Win32_PrintJob")
        
    Loop While Jobs.Count = 0
    
    For Each Job In Jobs
        Debug.Print Job.Name
    Next
    
End Sub

Другие свойства JOB:
http://msdn.microsoft.com/en-u... s.85).aspx

Больше информации - файл в системе: c:\windows\system32\Printing_Admin_Scrip ts\ru-RU\prnjobs.vbs
0
5472 / 1150 / 50
Регистрация: 15.09.2012
Сообщений: 3,576
20.03.2013, 09:05  [ТС]
Пункт 1

Цитата Сообщение от Dragokas Посмотреть сообщение
WBEM нужен только для подключения. Но можно и в обход него, встроенными средствами самого WMI.
синтаксис то для VBA-программиста одинаков, что при использовании термина "WBEM", что при использовании термина "WMI". Я разницы не заметил. Может быть для других программистов (например, для C-программистов) есть разница между "WBEM" и "WMI".


Пункт 2

Dragokas, я использовал в своём макросе такие же строки кода, как у вас в сообщении #2, в коде строки 6 - 10. И макрос не успел отследить появление в очереди печати документа: документ быстро появился в очереди печати и исчез. Т.е. некоторые документы в очереди печати появляются и исчезают быстрее, чем макрос успевает срабатывать. Это случилось для конкретного виртуального принтера "Microsoft XPS Document Writer". У меня алгоритм другой, чем у вас в сообщении #2: макрос запускает документ на печать, а затем макрос смотрит очередь печати.

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

Но может быть как-то можно попробовать использовать в "WBEM" события, например, есть такое слово "ExecNotificationQuery". Может быть на основе него сделать событие.


Пункт 3

Вообще нужно что-нибудь придумать, чтобы отслеживать печатаемый документ от начала и до конца. Чтобы документ имел так называемый "хэндл" - имя, которое даётся объекту, чтобы потом следить за объектом по этому имени. VBA-средства здесь не помогут, нужно, наверное использовать API-функции. С помощью какой-то API-функции отправлять Excel-книгу на печать (в моём конкретном случае нужна печать по листам и по страницам, а не целой книги) и по особому имени (по-научному - по "хэндлу") отслеживать распечатываемую книгу.

Возможно ли такое сделать простыми средствами и вообще, воможно ли? Не знаю.
0
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18033 / 7736 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
21.03.2013, 02:08
Пункт 1.
Нет, разные. По ссылке выше как раз код на основе WBEM.

Пункт 2.
Я написал по четко данному Вами в посте № 1 алгоритме. Дальше можно фантазировать сколько угодно.
Например, добавить тайм-аут выхода из цикла в первоначальную задумку:
Visual Basic
1
2
3
4
5
6
7
8
9
'...
'здесь команда отправки на печать
dim t!: t=timer
Do
        DoEvents
        Set Jobs = WMI.ExecQuery("SELECT * FROM Win32_PrintJob")
        
Loop While Jobs.Count = 0 and timer-t < 5
'...
Пункт 3.
Печатать через API можно: http://support.microsoft.com/kb/154078
Не думаю, что это принесет Вам какую-то выгоду.
Отслеживать через события принтера тоже можно: http://www.freevbcode.com/ShowCode.asp?ID=3383 (компилируется только на VB 5.0). http://www.codeproject.com/Art... rom-VB-NET (библиотека классов на VB.NET)
Но зачем такие сложности.

WMI имеет структуру запросов по принципу SQL, поэтому отследить нужный документ, думаю, не проблема.
Уж на нем на много проще сформировать нужный цикл, чем подключать дополнительные библиотеки на API.
Просмотрите нужные Вам свойства по ссылке MSDN из поста № 2.
0
5472 / 1150 / 50
Регистрация: 15.09.2012
Сообщений: 3,576
21.03.2013, 08:06  [ТС]
По пункту 1

При своём мнении останусь: для VBA-программиста нет разницы между терминами "WBEM" и "WMI".


По пункту 2

У вас не событие, а просто цикл, который что-то смотрит.


По пункту 3

Я имел ввиду сделать VBA-макрос, а не использовать другие языки программирования (например, "VB") для решения задачи.


Цитата Сообщение от Dragokas Посмотреть сообщение
WMI имеет структуру запросов по принципу SQL, поэтому отследить нужный документ, думаю, не проблема.
я считаю, что отследить распечатку документа на принтер - это проблема. Или докажите обратное. Только здесь обсуждается язык "VBA", а не другие языки программирования.
0
2619 / 549 / 109
Регистрация: 21.03.2012
Сообщений: 1,051
21.03.2013, 09:37
Лучший ответ Сообщение было отмечено как решение

Решение

Скрипт, VBA не имеет собственных средств решения данной задачи. Поэтому придётся пользоваться либо WinAPI, либо WMI (возможно, свои средства имеет .NET Framework). Суть решения в любом случае заключается в создании подписки на соответствующее системное событие.

Цитата Сообщение от Скрипт Посмотреть сообщение
... отследить распечатку документа на принтер - это проблема...
Пожалуй, нет. Другое дело, что VBA для этого неудобен и "расточителен", т.к. придётся держать открытым приложение, в котором работает макрос.
Советую "переложить" этот груз на VB-сценарий. В качестве примера приведу сценарий обработки соответствующего события для экземпляра класса Win32_PrintJob:
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Dim objWMI, objCollection, objItem
Dim strMsg, strTemp, intPos
On Error Resume Next
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
If Err.Number = 0 Then
    Set objCollection = objWMI.ExecNotificationQuery _
        ("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE Targetinstance ISA 'Win32_PrintJob'")
    If Err.Number = 0 Then
        Do
            Set objItem = objCollection.NextEvent
            If Err.Number <> 0 Then
                WScript.Echo "Ошибка " & Err.Number & " при обработке запроса." & Err.Description
                Err.Clear
                Exit Do
            End If
            strMsg = "Владелец задания: " & objItem.TargetInstance.Owner & vbNewLine
            If Err.Number <> 0 Then Err.Clear
            strTemp = objItem.TargetInstance.Name
            If Err.Number = 0 Then
                intPos = InStrRev(strTemp, ", ")
                If intPos > 0 Then strTemp = Mid(strTemp, 1, intPos - 1)
                strMsg = strMsg & "Принтер: " & strTemp & vbNewLine
            Else
                Err.Clear
            End If
            strMsg = strMsg & "Документ: " & objItem.TargetInstance.Document & vbNewLine
            If Err.Number <> 0 Then Err.Clear
            strMsg = strMsg & "Кол-во страниц: " & objItem.TargetInstance.TotalPages
            If Err.Number <> 0 Then Err.Clear
            Exit Do
        Loop
        WScript.Echo strMsg
    Else
        WScript.Echo "Ошибка " & Err.Number & " при создании подписки." & Err.Description
        Err.Clear
    End If
    Set objCollection = Nothing
Else
    WScript.Echo "Ошибка " & Err.Number & " при подключении к WMI-пространству." & Err.Description
    Err.Clear
End If
Set objWMI = Nothing
WScript.Quit 0
Это иллюстрация реализации подписки синхронного типа.

Если всё-таки нужна реализация именно на VBA, то советую несколько изменить подход - отказаться от регистрации самого события, а заняться периодической проверкой содержимого журнала событий ОС ("Система"/"System"). Это класс Win32_NTLogEvent. Здесь есть свои особенности, но их можно обсудить, если будет соответствующий интерес.
0
5472 / 1150 / 50
Регистрация: 15.09.2012
Сообщений: 3,576
21.03.2013, 10:19  [ТС]
Пункт 1

Dmitrii, я только "VBA" знаю, поэтому рассматриваю только примеры на "VBA".


Пункт 2

Я знаю, что в 'VBA" можно использовать "API-функции", различные библиотеки. Но для этого же не надо переходить на другой язык программирования.


Пункт 3

Цитата Сообщение от Dmitrii Посмотреть сообщение
Советую "переложить" этот груз на VB-сценарий.
не понимаю, что вы предлагаете: что за VB-сценарий? Что вы под этим подразумеваете? В "MS Office" слово "сценарий" используется редко и никак не связано вроде с программированием.


Пункт 4

Цитата Сообщение от Dmitrii Посмотреть сообщение
Если всё-таки нужна реализация именно на VBA, то советую несколько изменить подход - отказаться от регистрации самого события, а заняться периодической проверкой содержимого журнала событий ОС ("Система"/"System").
Периодическая проверка делается с помощью цикла. Я использовал цикл и макрос не успевал отслеживать появление в очереди печати документа. Есть вариант - смотреть историю распечатки. Но за какой период её смотреть? В этом сложность, может быть человек секунду назад что-то делал с тем же самым файлом. Как макросу указать, какой именно файл нужен?


Пункт 5

Новая идея пришла. Можно попробовать получить доступ к истории распечатки с помощью "WBEM". Вроде можно так сделать.

Алгоритм тогда примерно такой:
  1. запускается макрос;
  2. макрос берёт историю распечатки;
  3. запускает на печать документ;
  4. снова смотрит историю распечатки;
  5. делает выводы на основе истории распечатки.
0
2619 / 549 / 109
Регистрация: 21.03.2012
Сообщений: 1,051
21.03.2013, 10:46
Скрипт, укажите, пожалуйста, конечную цель, ради которой Вы пытаетесь решить обсуждаемую задачу.
0
5472 / 1150 / 50
Регистрация: 15.09.2012
Сообщений: 3,576
21.03.2013, 11:22  [ТС]
Dmitrii, проблема в чём? В том, что нужно распечатать Excel-листы в том порядке, в котором они идут в Excel-книге. По техническим причинам нужно печатать каждый лист отдельно (это связано с формированием текста в колонтитулах).

Если сразу все листы посылать на печать, то в очереди печати по каким-то правилам меняется порядок Excel-листов и они распечатываются не в нужном порядке.
0
2619 / 549 / 109
Регистрация: 21.03.2012
Сообщений: 1,051
21.03.2013, 11:56
Пока вижу два способа решения задачи:
- использовать задержку после печати текущего листа (скажем, с помощью API-функции Sleep());
- "ловить" событие удаления задания на печать текущего листа из очереди печати.
По сути второй способ - лишь более сложный вариант первого.
0
5472 / 1150 / 50
Регистрация: 15.09.2012
Сообщений: 3,576
21.03.2013, 12:26  [ТС]
Пункт 1

Цитата Сообщение от Dmitrii Посмотреть сообщение
- использовать задержку после печати текущего листа (скажем, с помощью API-функции Sleep());
это и так уже обсуждается и применяется.


Пункт 2

Цитата Сообщение от Dmitrii Посмотреть сообщение
"ловить" событие удаления задания на печать текущего листа из очереди печати.
Ради этого и создана эта тема. Только под событием понимается "событие" - как явление в программировании. Ведь есть же в программировании такое слово "событие". А не цикл, который что-то смотрит.
У вас в сообщении #6 что-то есть. Я пока ещё не смотрел. Т.к. мне время понадобится, чтобы разобраться.
0
2619 / 549 / 109
Регистрация: 21.03.2012
Сообщений: 1,051
21.03.2013, 13:18
Скрипт, в Вашем случае нужно именно синхронное наблюдение (асинхронное неуместно по сути задачи).
Только вот при реализации через WMI это всё равно будет цикл.
Смотрите описание WMI-класса __InstanceDeletionEvent и соответствующие примеры.
0
5472 / 1150 / 50
Регистрация: 15.09.2012
Сообщений: 3,576
22.03.2013, 09:40  [ТС]
Сейчас на свежую голову посмотрел, может быть в очереди печати и не меняется порядок распечатки Excel-листов.
Если посмотреть очередь печати, то порядок меняется, но печатаются Excel-листы не в том порядке, как находятся в окне "Очередь печати". Может быть и не нужно ничего использовать, т.к. программа Excel печатает синхронно - т.е. код продолжит свою работу только после того, как документ будет отправлен в очередь печати.

Пока прихожу к выводу, что очередь печати не влияет на порядок распечатки документов.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
22.03.2013, 09:40
Помогаю со студенческими работами здесь

Создание события
Здравствуйте! Пишется простенький класс, который преобразует данные в нужный вид и передает по сокетам, а так же принимает их. Класс будет...

создание события
мне нужно чтобы в Edit1 на клик выводилось true или false тоесть при нажатии на Edit первый раз появилось True в том же самом Edit ...

Создание глобального события
Доброго времени суток, не знаю как назначить вот такой код всем формам: private void AllForms_FormClosed(object sender,...

Создание обработчика события
1. помогите прописать обработчик события wm_Timer! 2. как в С++ builder XEвызвать окно добавления метода()...

Создание события по дате
Приветствую всех. Я придумал себе новую проблему. Создаю эту тему потому что даже не знаю как сформулировать вопрос поисковику. Ну...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Фото всей Земли с борта корабля Orion миссии Artemis II
kumehtar 04.04.2026
Это первое подобное фото сделанное человеком за 50 лет. Снимок называют новым вариантом легендарной фотографии «The Blue Marble» 1972 года, сделанной с борта корабля «Аполлон-17». Новое фото. . .
Вывод диалогового окна перед закрытием, если документ не проведён
Maks 04.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать программный контроль на предмет проведения документа. . .
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита "ПричинаСписания". . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Программное заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru