c++ 监听打印机动作
可以监听多个打印机
WORD JobFields[] = { JOB_NOTIFY_FIELD_DOCUMENT,
JOB_NOTIFY_FIELD_USER_NAME,
JOB_NOTIFY_FIELD_MACHINE_NAME,
JOB_NOTIFY_FIELD_PRINTER_NAME,
JOB_NOTIFY_FIELD_STATUS,
JOB_NOTIFY_FIELD_START_TIME,
JOB_NOTIFY_FIELD_TOTAL_PAGES};
PRINTER_NOTIFY_OPTIONS_TYPE Notifications[1] = {{JOB_NOTIFY_TYPE,0,0,0,sizeof(JobFields)/sizeof(JobFields[0]),JobFields}};
PRINTER_NOTIFY_OPTIONS NotificationOptions = {2,PRINTER_NOTIFY_OPTIONS_REFRESH,1,Notifications};
HANDLE m_hPrintWaitHandle[MAXIMUM_WAIT_OBJECTS-1]; //等待对象数组
DWORD nCount = 0;
std::string GetCurrentUserName()
{
std::string sUserName = "";
char* szLogName = NULL;
DWORD dwSize = 0;
DWORD dwWindowSessionId = 0;
ProcessIdToSessionId(GetCurrentProcessId(),&dwWindowSessionId);
if (WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE,dwWindowSessionId,WTSUserName,&szLogName,&dwSize)){
sUserName = szLogName;
WTSFreeMemory(szLogName);
}
return sUserName;
}
BOOL AddEventHandle(HANDLE hPrinterNotify)
{
if(hPrinterNotify == NULL)
{
return FALSE;
}
m_hPrintWaitHandle[nCount] = hPrinterNotify;
nCount++;
return TRUE;
}
HANDLE GetEventHandle(int dwObjectIndex)
{
HANDLE hPrinterNotify = m_hPrintWaitHandle[dwObjectIndex];
return hPrinterNotify;
}
int main()
{
DWORD dwFlags = PRINTER_ENUM_CONNECTIONS | PRINTER_ENUM_LOCAL;
DWORD cbPrinters = 0;
DWORD cReturned = 0;
PPRINTER_INFO_5 pPrinters = NULL;
HANDLE hPrinter = NULL;
HANDLE hPrinterNotify = NULL;
DWORD fdwFlags = PRINTER_CHANGE_SET_JOB;
HANDLE m_hPrinter[MAXIMUM_WAIT_OBJECTS-1];
PPRINTER_NOTIFY_INFO pNotifyInfo = NULL;
DWORD dwChanged = 0;
static DWORD m_sLastJobId = 0;
std::string sPrintDocument;
std::string sPrintMachineName;
std::string sPrintUserName;
DWORD dwPrintTotalPage;
DWORD dwPrintStatus;
std::string sPrintStatusString;
std::string sPrintPrinterName;
DWORD dwStartTime = 0;
DWORD dwJobId = 0;
DWORD dwObjectIndex;
DWORD dwPrintHomePage;
::EnumPrinters(dwFlags,NULL,5,(PBYTE)pPrinters,cbPrinters,&cbPrinters,&cReturned);
if (!cbPrinters){
LOG_ERROR("CUEBAMonitorPrinter::PreMessageLoop EnumPrinters Failed ErrorCode = %d", GetLastError());
if (pPrinters != NULL){
LocalFree((HLOCAL)pPrinters);
pPrinters = NULL;
}
return 0;
}
pPrinters = (PPRINTER_INFO_5) LocalAlloc (LPTR, cbPrinters + 4);
if (!pPrinters){
LOG_ERROR("CUEBAMonitorPrinter::PreMessageLoop LocalAlloc Failed ErrorCode = %d", GetLastError());
if (pPrinters != NULL){
LocalFree((HLOCAL)pPrinters);
pPrinters = NULL;
}
return 0; }
::EnumPrinters(dwFlags,NULL,5,(PBYTE)pPrinters,cbPrinters,&cbPrinters,&cReturned);
if (!cbPrinters || !cReturned){
LOG_ERROR("CUEBAMonitorPrinter::PreMessageLoop EnumPrinters Failed ErrorCode = %d", GetLastError());
if (pPrinters != NULL){
LocalFree((HLOCAL)pPrinters);
pPrinters = NULL;
}
return 0;
}
for(DWORD dwIndex = 0;dwIndex < cReturned;dwIndex++){
if(OpenPrinter(pPrinters->pPrinterName, &hPrinter, NULL)){
hPrinterNotify = FindFirstPrinterChangeNotification(hPrinter,fdwFlags, 0, &NotificationOptions);
if(hPrinterNotify != INVALID_HANDLE_VALUE){
LOG_INFO("CUEBAMonitorPrinter::PreMessageLoop %s",TChar2s(pPrinters->pPrinterName).c_str());
if (AddEventHandle(hPrinterNotify) && dwIndex < MAXIMUM_WAIT_OBJECTS-1){
m_hPrinter[dwIndex] = hPrinter;
}
}else{
ClosePrinter(hPrinter);
}
hPrinter = NULL;
}
pPrinters++;//指针后移
}
while(true) //等待打印任务
{
int dwObjectIndex = WaitForMultipleObjects(nCount, m_hPrintWaitHandle,FALSE,INFINITE);
FindNextPrinterChangeNotification(GetEventHandle(dwObjectIndex), &dwChanged, (LPVOID)&NotificationOptions, (LPVOID*)&pNotifyInfo);
if (pNotifyInfo == NULL || pNotifyInfo->Count == 0 || dwChanged != PRINTER_CHANGE_SET_JOB){
goto OnPrinterChangeNotificationEnd;
}
for (DWORD dwIndex=0;dwIndex<pNotifyInfo->Count;dwIndex++){
if (pNotifyInfo->aData[dwIndex].Field == JOB_NOTIFY_FIELD_DOCUMENT){
sPrintDocument = TChar2s((LPCTSTR)pNotifyInfo->aData[dwIndex].NotifyData.Data.pBuf);
dwJobId = pNotifyInfo->aData[dwIndex].Id;
}else if (pNotifyInfo->aData[dwIndex].Field == JOB_NOTIFY_FIELD_MACHINE_NAME){
sPrintMachineName = TChar2s((LPCTSTR)pNotifyInfo->aData[dwIndex].NotifyData.Data.pBuf);
}else if (pNotifyInfo->aData[dwIndex].Field == JOB_NOTIFY_FIELD_USER_NAME){
sPrintUserName = TChar2s((LPCTSTR)pNotifyInfo->aData[dwIndex].NotifyData.Data.pBuf);
}else if (pNotifyInfo->aData[dwIndex].Field == JOB_NOTIFY_FIELD_TOTAL_PAGES){
dwPrintTotalPage =pNotifyInfo->aData[dwIndex].NotifyData.adwData[0];
}else if (pNotifyInfo->aData[dwIndex].Field == JOB_NOTIFY_FIELD_STATUS){
dwPrintStatus = pNotifyInfo->aData[dwIndex].NotifyData.adwData[0];
}else if (pNotifyInfo->aData[dwIndex].Field == JOB_NOTIFY_FIELD_PRINTER_NAME){
sPrintPrinterName = TChar2s((LPCTSTR)pNotifyInfo->aData[dwIndex].NotifyData.Data.pBuf);
}else if (pNotifyInfo->aData[dwIndex].Field == JOB_NOTIFY_FIELD_START_TIME){
dwStartTime = pNotifyInfo->aData[dwIndex].NotifyData.adwData[0];
}else if (pNotifyInfo->aData[dwIndex].Field == JOB_NOTIFY_FIELD_PAGES_PRINTED){
dwPrintHomePage = pNotifyInfo->aData[dwIndex].NotifyData.adwData[0];
}
}
if (!sPrintUserName.empty()){
std::string sCurrentUser = GetCurrentUserName();
if (_stricmp(sCurrentUser.c_str(),sPrintUserName.c_str()) != 0){
goto OnPrinterChangeNotificationEnd;
}
}
if (m_sLastJobId != dwJobId){
//你想做的事(输出文件名,打印机名等)
}
OnPrinterChangeNotificationEnd:
if (pNotifyInfo != NULL){
FreePrinterNotifyInfo(pNotifyInfo);
pNotifyInfo = NULL;
}
}
for (DWORD dwIndex = 0;dwIndex < nCount;dwIndex++){
if (GetEventHandle(dwIndex) != NULL){
FindClosePrinterChangeNotification(GetEventHandle(dwIndex));
m_hPrintWaitHandle[nCount] = NULL;
}
}
for (DWORD dwIndex = 0;m_hPrinter[dwIndex] != NULL;dwIndex++){
ClosePrinter(m_hPrinter[dwIndex]);
}
nCount = 0;
return 0;
}