Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.95/19: Рейтинг темы: голосов - 19, средняя оценка - 4.95
145 / 100 / 6
Регистрация: 11.03.2010
Сообщений: 477

Слежение/контроль за работой принтеров

11.03.2011, 17:03. Показов 4190. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
а реально ли вообще написать програмульку, которая бы снимала данные с принтеров, и записывала кудато в лог ?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.03.2011, 17:03
Ответы с готовыми решениями:

Контроль принтеров. Вот задачка!?
У нас в конторе три принтера, и боссы очень строго относятся к расходу бумаги. Ну вот я и решил сделать что-то на подобие проги для...

В чём разница между работой по RDP и работой по RDP через браузер?
Доброго времени суток, прошу помощи у вас форумчане разобраться со столь непростой ситуацией для начинающего сисадмина. Стоит задача...

Слежение за мышкой
всем доброе время суток! У меня есть картинка чела с оружием (вид с верху) можно ( я думаю можно =) ) как-нибудь заставить его...

15
Эксперт С++
 Аватар для odip
7176 / 3234 / 82
Регистрация: 17.06.2009
Сообщений: 14,164
11.03.2011, 21:24
Какие именно данные снимала ?
0
145 / 100 / 6
Регистрация: 11.03.2010
Сообщений: 477
12.03.2011, 13:53  [ТС]
да хотя бы минимум какойто, кто+когда+сколько страниц пустил на печать.

мне вообще интересно про саму возможность реализации такой программы, в какую сторону можно посмотреть ?

Добавлено через 17 минут
вот как раз на мсдн нашел функцию, которая походу собирает все что мне нужно

http://msdn.microsoft.com/en-u... 85%29.aspx

осталось это чудо заставить работать

Добавлено через 8 минут
даже нашел темку с отличной статейкой.

Как узнать состояние принтера

Код компилится без единой ошибки все как по маслу.

Но вот непонятно пока как в этот код вводить инфо про то какой принтер меня интересует?И куда и как можно получать ответы?

Добавлено через 3 часа 6 минут
помониторил немного областьи вот что определил.

сначало нужно через
C++
1
2
3
4
5
6
7
8
9
BOOL EnumPrinters(
  __in   DWORD Flags,
  __in   LPTSTR Name,
  __in   DWORD Level,
  __out  LPBYTE pPrinterEnum,
  __in   DWORD cbBuf,
  __out  LPDWORD pcbNeeded,
  __out  LPDWORD pcReturned
);
получить список принтеров.

Потом через:
C++
1
2
3
4
5
BOOL OpenPrinter(
  __in   LPTSTR pPrinterName,
  __out  LPHANDLE phPrinter,
  __in   LPPRINTER_DEFAULTS pDefault
);
получить хендл для всех принтеров.

Ну и завершить всю эту историю с помощью:
C++
1
2
3
4
5
6
7
BOOL GetPrinter(
  __in   HANDLE hPrinter,
  __in   DWORD Level,
  __out  LPBYTE pPrinter,
  __in   DWORD cbBuf,
  __out  LPDWORD pcbNeeded
);
я сойду с ума
0
145 / 100 / 6
Регистрация: 11.03.2010
Сообщений: 477
14.03.2011, 11:09  [ТС]
может ктонить помоч разобраться с этим делом ?
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
14.03.2011, 11:16
а поискать ? Перечисление принтеров
1
145 / 100 / 6
Регистрация: 11.03.2010
Сообщений: 477
14.03.2011, 11:59  [ТС]
LK, этот кусочек я видел уже.

при его компиляции выдает вот такое вот

[BCC32 Error] Unit1.cpp(21): E2303 Type name expected
[BCC32 Error] Unit1.cpp(21): E2356 Type mismatch in redeclaration of '__stdcall EnumPrintersA(unsigned long,char *,unsigned long,unsigned char *,unsigned long,unsigned long *,unsigned long *)'
[BCC32 Error] winspool.h(1234): E2344 Earlier declaration of '__stdcall EnumPrintersA(unsigned long,char *,unsigned long,unsigned char *,unsigned long,unsigned long *,unsigned long *)'
[BCC32 Error] Unit1.cpp(21): E2063 Illegal initialization
[BCC32 Error] Unit1.cpp(21): E2293 ) expected
[BCC32 Error] Unit1.cpp(23): E2303 Type name expected
[BCC32 Error] Unit1.cpp(23): E2238 Multiple declaration for 'Pr'
[BCC32 Error] Unit1.cpp(18): E2344 Earlier declaration of 'Pr'
[BCC32 Error] Unit1.cpp(25): E2040 Declaration terminated incorrectly


компилирую в CodeGear™ C++Builder® 2009

Добавлено через 4 минуты
я нашел вот такой вот рабочий кусочек кода:

C++
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
BOOL GetJobs(HANDLE hPrinter,      /* Дескриптор принтера. */
        JOB_INFO_2 **ppJobInfo, /* Указатель который будем заполнять.*/
        int *pcJobs,            /* Счётчик заданий. */
        DWORD *pStatus)         /* Состояние очереди печати.*/
 
   {
 
   DWORD               cByteNeeded,
                        nReturned,
                        cByteUsed;
    JOB_INFO_2          *pJobStorage = NULL;
    PRINTER_INFO_2       *pPrinterInfo = NULL;
 
   /* Получаем необходимый размер буфера. */
       if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded))
       {
           if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
               return FALSE;
       }
 
       pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded);
       if (!(pPrinterInfo))
           /* Ошибка выделения памяти. */
           return FALSE;
 
       /* Получаем информацию о принтере. */
       if (!GetPrinter(hPrinter,
               2,
               (LPSTR)pPrinterInfo,
               cByteNeeded,
               &cByteUsed))
       {
           /* Ошибка доступа к принтеру. */
           free(pPrinterInfo);
           pPrinterInfo = NULL;
           return FALSE;
       }
 
       /* Получаем необходимы размер для заданий. */
       if (!EnumJobs(hPrinter,
               0,
               pPrinterInfo->cJobs,
               2,
               NULL,
               0,
               (LPDWORD)&cByteNeeded,
               (LPDWORD)&nReturned))
       {
           if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
           {
               free(pPrinterInfo);
               pPrinterInfo = NULL;
               return FALSE;
           }
       }
 
       pJobStorage = (JOB_INFO_2 *)malloc(cByteNeeded);
       if (!pJobStorage)
       {
           /* Ошибка выделения памяти для информации о заданиях. */
           free(pPrinterInfo);
           pPrinterInfo = NULL;
           return FALSE;
       }
 
       ZeroMemory(pJobStorage, cByteNeeded);
 
       /* Получаем список заданий. */
       if (!EnumJobs(hPrinter,
               0,
               pPrinterInfo->cJobs,
               2,
               (LPBYTE)pJobStorage,
               cByteNeeded,
               (LPDWORD)&cByteUsed,
               (LPDWORD)&nReturned))
       {
           free(pPrinterInfo);
           free(pJobStorage);
           pJobStorage = NULL;
           pPrinterInfo = NULL;
           return FALSE;
       }
 
       /*
        *  Возвращаем информацию.
        */
       *pcJobs = nReturned;
       *pStatus = pPrinterInfo->Status;
       *ppJobInfo = pJobStorage;
       free(pPrinterInfo);
 
       return TRUE;
 
   }
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 
   BOOL IsPrinterError(HANDLE hPrinter)
   {
 
       JOB_INFO_2  *pJobs;
       int         cJobs,
                   i;
       DWORD       dwPrinterStatus;
 
       /*
        *  Получаем информацию о состоянии очереди принтера и
        *  заданиях в очереди принтера.
        */
       if (!GetJobs(hPrinter, &pJobs, &cJobs, &dwPrinterStatus))
           return FALSE;
 
       /*
        *  Если на принтере ошибка, то возвращаем ошибку.
        */
       if (dwPrinterStatus &
           (PRINTER_STATUS_ERROR |
           PRINTER_STATUS_PAPER_JAM |
           PRINTER_STATUS_PAPER_OUT |
           PRINTER_STATUS_PAPER_PROBLEM |
           PRINTER_STATUS_OUTPUT_BIN_FULL |
           PRINTER_STATUS_NOT_AVAILABLE |
           PRINTER_STATUS_NO_TONER |
           PRINTER_STATUS_OUT_OF_MEMORY |
           PRINTER_STATUS_OFFLINE |
           PRINTER_STATUS_DOOR_OPEN))
       {
           return TRUE;
       }
 
       /*
        *  Находим задание в очереди, которое печатается.
        */
       for (i=0; i < cJobs; i++)
       {
           if (pJobs[i].Status & JOB_STATUS_PRINTING)
           {
               /*
                *  Если задание в состоянии ошибки,
                *  то возвращаем ошибку.
                */
               if (pJobs[i].Status &
                   (JOB_STATUS_ERROR |
                   JOB_STATUS_OFFLINE |
                   JOB_STATUS_PAPEROUT |
                   JOB_STATUS_BLOCKED_DEVQ))
               {
                   return TRUE;
               }
           }
       }
 
       /*
        *  Ошибок на принтере нет.
        */
       return FALSE;
 
   }
компилируется он без единой ошибки, но пока еще не разобрался как им пользоваться, и как из него вытащить полученую информацию.
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
14.03.2011, 12:18
Цитата Сообщение от koldun Посмотреть сообщение
при его компиляции выдает вот такое вот ...
подозреваю, что у вас там еще есть "нагромождение" кода, потому как код из Перечисления принтеров - просто скопированный и вставленный без никаких изменений, прекрасно работает (у меня "железный" принтер не подключен, Вынь7, РАД ХЕ):
Миниатюры
Слежение/контроль за работой принтеров  
1
145 / 100 / 6
Регистрация: 11.03.2010
Сообщений: 477
14.03.2011, 12:38  [ТС]
Вот это я лузер...

я в шоке.

неработало когда я просто вставил код в тело срр файла.

а когда воткнул его в обработчик кнопки, так запахал как миленький
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
14.03.2011, 12:42
Цитата Сообщение от koldun Посмотреть сообщение
Вот это я лузер...

я в шоке.

неработало когда я просто вставил код в тело срр файла.

а когда воткнул его в обработчик кнопки, так запахал как миленький
слов нет... одни мысли...
код можно, конечно, вставить и в тело , но обернув его предварительно в през... пардон, в функцию .
0
145 / 100 / 6
Регистрация: 11.03.2010
Сообщений: 477
14.03.2011, 12:50  [ТС]
эт я просто делал по аналогии с вот тем сдоровенным длинным кодом, что я тут привел.

его то я как раз просто вставил в срр и запустил, все заработало без ошибок, потом смотрю, еще 1 примерчик(вот этот коротенький), и я его точно так же запихнул, компилирую и полезли ошибки сразу...

а мозх то сразу не просек, что нужно в кнопку его запихать
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
14.03.2011, 12:55
так с тем кодом как раз все нормально - функции там объявлены
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
BOOL GetJobs(HANDLE hPrinter,      /* Дескриптор принтера. */
        JOB_INFO_2 **ppJobInfo, /* Указатель который будем заполнять.*/
        int *pcJobs,            /* Счётчик заданий. */
        DWORD *pStatus)         /* Состояние очереди печати.*/
 
{
    Тело_Функции :D;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BOOL IsPrinterError(HANDLE hPrinter)
{
    Истчо_Одно_Тело ;);
}
1
145 / 100 / 6
Регистрация: 11.03.2010
Сообщений: 477
14.03.2011, 13:04  [ТС]
эт я уже понял спасиб!

осталось понять как этими функциями пользоваться, и как от них можно получить информацию.
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
14.03.2011, 13:48
Цитата Сообщение от koldun Посмотреть сообщение
эт я уже понял спасиб!

осталось понять как этими функциями пользоваться, и как от них можно получить информацию.
ссылка удалена - подозреваю, что там есть, как пользоваться, но оно - 1. не наше, 2. те же яйца, только в профиль (см. структуру PRINTER_INFO_2) .
1
145 / 100 / 6
Регистрация: 11.03.2010
Сообщений: 477
14.03.2011, 14:13  [ТС]
вот мне интересно, вот как Вам удается находить такие отличные темки ?

я с гуглом просидел наверно с пол дня на выходных, и нашел путёвого только 2 куска кода, которые мы уже обсудили.

а тут сразу такая полезная тема...
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
14.03.2011, 14:27
Цитата Сообщение от koldun Посмотреть сообщение
как?
а я знаю ...
How To Call Win32 Spooler Enumeration APIs Properly
1
145 / 100 / 6
Регистрация: 11.03.2010
Сообщений: 477
14.03.2011, 14:32  [ТС]
у меня скоро начнется депресия..

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

спасибо за помощь.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.03.2011, 14:32
Помогаю со студенческими работами здесь

Слежение за объектом
Здравствуйте. Помогите с задачей: идет видео с камеры. Нажимая на кнопку &quot;stop&quot; на данном кадре выделяются границы объектов. Нажимая на...

Сделать слежение
Собственно возникла такая необходимость, что нужно тормозить бесконечный цикл на время, пока другая функция выполнится... Пытался сделать...

Слежение за объектом
Дорогие форумчане! Очень прошу вашей помощи. Поделитесь или сделайте del] программу, которая на видео файле детектирует объекты. Алгоритм...

Слежение за событиями
Как отключить слежение за событиями в WinXP, чтобы при просмотре с помощью eventvwr.msc было пусто.

слежение за форумами
Приветствую, камрады. Занимаюсь не сколько раскруткой, сколько веб-аналитикой. Ежедневно приходится перелопачивать десятки...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Автоматическое создание документа при проведении другого документа
Maks 29.03.2026
Реализация из решения ниже выполнена на нетиповых документах, разработанных в конфигурации КА2. Есть нетиповой документ "ЗаявкаНаРемонтСпецтехники" и нетиповой документ "ПланированиеСпецтехники". В. . .
Настройка движения справочника по регистру сведений
Maks 29.03.2026
Решение ниже реализовано на примере нетипового справочника "ТарифыМобильнойСвязи" разработанного в конфигурации КА2, с целью учета корпоративной мобильной связи в коммерческом предприятии. . . .
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при создании или изменении элементов справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи электронной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru