精华内容
下载资源
问答
  • 如何监控打印机打印的文件
    千次阅读
    更多相关内容
  • 监控windows打印机打印文件的事件通知,列举系统打印机详细列表,VS2010项目工程详细源码 。
  • 打印机监控,打印机打印内容记录,打印机状态监控。通过Hook和轮询两种方式结合监控打印机
  • C# 打印机监控系统 打印任务监控 读取内存生成图片 ,实时监测 支持.spl文件转emf,需要的快下载吧
  • 监控局域网内:共享打印机 获取打印记录、打印人员、打印文件等详细信息。导出为excel表格
  • 使用PowerShell脚本自动监控服务器或者电脑上的所有打印机驱动,如果有Error的任务卡在驱动中导致后续的打印任务全部卡在上面,脚本会执行一个邮件通知 邮件通知内容: - 打印机名 - Error状态的打印机任务名 - ...
  • 这是一个外国社区的一个三哥的代码,经过修改以后分享给大家,基本实现了监控本地打印机打印状态,加入了本人的详细注释,十分好理解,包含了一些C++ dll调用,回调函数,线程同步等基本操作,作为初学者的例子也...
  • 如何监控打印机打印队列,可以获得正在打印文档的文档名,状态,所有者,页数,大小等。 答: 1、C++代码 一、API介绍: API是ApplicationProgrammingInterface的缩写,也就是应用程序调用系统功能的接口。...

    问:

    如何监控打印机的打印队列,可以获得正在打印文档的文档名,状态,所有者,页数,大小等。

    答:

    1、C++代码

    一、API介绍:

    API是Application Programming Interface的缩写,也就是应用程序调用系统功能的接口。Windows API主要包括系统定义的函数、消息及与之相关的数据类型。我们使用各种开发工具归根结底都是和API打交道。

    二、与打印状态相关的API:

    Api函数名 函数说明 W3.x W9x NT 
    EnumJobs 获取打印作业信息 否 是 是 
    OpenPrinter 获取指定打印机的句柄 否 是 是 


    在 Windows NT 版本以及 Windows 9x 中,增加了一批全新的、专门用来处理打印机及打印机队列状态的 API 函数。在这里,将通过 API 函数 OpenPrinter 与 EnumJobs,来确定打印机打印作业状态所需的信息。

    OpenPrinter,用来获取给定打印机的句柄,通过该句柄可以实现对相应打印机的操作。

    函数 EnumJobs,用来列出所指定打印机上正在打印的作业信息,这里给定打印机的引用就是通过使用上述OpenPrinter函数反馈回来的打印机句柄。


    EnumJobs函数介绍:

    EnumJobs (ByVal hPrinter As Long, ByVal FirstJob As Long, ByVal NoJobs As Long, ByVal Level As Long, pJob As Long, ByVal cbBuf As Long, pcbNeeded As Long, pcReturned As Long) 

    API函数EnumJobs用于列举给定打印机当前所有正在打印的任务状态信息,该函数可以列举给定打印机简要的或者详细的(Level决定)队列任务状态信息。在引用该函数时,通常先把cbBuf变量设置为0,以获得打印机队列任务的字节数,该字节数存储在pcbNeeded里以决定pJob变量大小,然后再次引用该函数,获得打印机队列任务的详细信息。

    参数:

    hPrinter
    打印机句柄。

    FirstJob
    统计打印机队列任务数的起始点,0表示从第一个任务开始统计列举所有的打印任务。

    NoJobs
    需要列举的最大打印任务数。一般设为127。

    Level
    标示存储在pJob里的信息格式。如果该值为1,数据以JOB_INFO_1的格式存储;如果该值为2,数据以JOB_INFO_2的格式存储。

    pJob
    数组变量,保存打印任务的所有信息;cbBuf设为0时,该值也为0。Level变量的值决定pJob的数据格式(JOB_INFO_1 OR JOB_INFO_2)

    cbBuf
    该值通常为0。

    pcbNeeded
    存储打印机里打印任务的字节数。

    pcReturned
    用来存放打印任务数量的变量。

    通过上表可以看出,这两个API函数只用使用在Windows 9x 以及 Windows NT环境中

    三、开发工具:

    C++ Builder作为快速开发Windows平台下应用程序的工具,已经为越来越多的开发者采用。但是,如果要开发出专业的Windows应用软件,还需要使用大量的Windows API函数,以下是笔者应用C++ Builder以及Windows API函数来实现对打印机状态的时时监控。

    选择C++ Builder的理由:

    一:由于Windows API 都是用C或C++编写的,C++ Builder更易于底层应用。

    二:C++ Builder对于Windows API的引用更加简单,这一点是Visual Basic所欠缺的。


    四、程序实例:
    1、启动C++ Builder程序,新创建一个工程;

    2、进入工程,在当前窗体分别添加一个CheckListBox控件、一个Timer控件;

    3、在CheckListBox控件的Item属性添加打印机名称列表(假设在网络中HostPrinter主机上有三台打印机Printer1、Printer2、Printer3),则Item项目里内容格式为:\\HostPrinter\Printer1、\\HostPrinter\\Printer2、\\HostPrinter\\Printer3 ;

    4、Timer的Interval属性设置为60000(一分钟),在Timer的OnTimer事件加入如下代码:

    {
    HANDLE hPrinter; //打印机句柄
    JOB_INFO_2 jobs[30]; //保留打印作业详细信息
    DWORD size=sizeof(jobs);
    JOB_INFO_2 *jobs1=NULL; //动态数组用于对大于size的任务进行操作
    DWORD pcbNeeded=0; //所有打印字节数
    int actNeed=0;
    DWORD pcReturned=0; //打印任务数
    char buf[19]; //指向打印机或机器名
    int ret1; //获得打印机句柄返回值
    int ret; //获得打印机任务返回值
    TDateTime startTime;
    Word Hour=0;
    Word Hour1=0;
    Word Min=0;
    Word Min1=0;
    Word Sec=0;
    Word MSec=0;
    int StartTime=0; //任务开始时间
    int NowTime=0; //当前时间
    int TotalTime=0; //任务停留时间
    String str;
    int length;
    int PrintCount;
    int InitCount=15; //设定的打印队列数量--------报警底线
    int InitTime=10; //设定的打印队列事件--------报警底线(分钟)
    PrintCount =CheckListBox1->Count ;
    for (int i=0; i < PrintCount; i++)
    {
    //..............取得列表里的打印机
    str=CheckListBox1->Items->Strings[i] ;
    length=str.Length() ;
    //................字符串到字符的转换,
    StrPLCopy(buf,str,length); 
    //................获得打印机句柄
    ret1= OpenPrinter(buf, &hPrinter, NULL);
    //................获得打印任务数
    ret= EnumJobs(hPrinter, 0, 127, 2,0, 0, &pcbNeeded, &pcReturned); //必要的一步,先取出打印机里任务的字节数,然后决定jobs1变量大小。//--------------------------①
    //.................重定义Jobs1, 根据pcbNeeded决定使用哪个变量
    if (pcbNeeded>size)
    {
    actNeed=pcbNeeded;
    jobs1=new JOB_INFO_2[actNeed];
    ret= EnumJobs(hPrinter, 0, 127, 2,(LPBYTE)jobs1, actNeed, &pcbNeeded, &pcReturned);
    startTime=SystemTimeToDateTime(jobs1[0].Submitted); //------------------②
    delete jobs1;
    }
    else
    {
    ret= EnumJobs(hPrinter, 0, 127, 2,(LPBYTE)jobs, size, &pcbNeeded, &pcReturned);//-----------------------------③
    if (pcReturned>0)
    startTime=SystemTimeToDateTime(jobs[0].Submitted);
    }
    //.................pcbNeeded>size结束
    //................如果队列里有打印任务,比对数量与时间
    if (pcReturned>0)
    {
    //.................时间转换,计算一天内的时间差
    {
    //............时间比较运算处理;
    //............时间转换StartTime转换成分钟
    }
    DecodeTime(Now(),Hour1, Min1, Sec,MSec);
    NowTime=Hour1*60+Min1;
    TotalTime=NowTime-StartTime;
    }
    //依据条件判断是否报警
    if ((pcReturned>InitCount) |(TotalTime >InitTime))
    {
    Beep();
    }
    pcReturned=0;
    pcbNeeded=0;
    }
    //..........................pcReturned>0结束
    }//....................................................for结束

    5、编译并运行上述程序:

    ①程序中,此处的获得打印机任务的目的主要是获得打印机作业的字节数------ pcbNeeded,该变量里字节的大小,将决定进一步获得打印机里作业的状态时所用的变量是Jobs还是Jobs1。

    ②当pcbNeeded>size,给Jobs1分配空间,然后获得打印机当前作业的状态。

    ③当pcbNeeded<size,用Jobs作为变量,获得当前打印机作业状态。

    用C++ Builder编程监控打印机队列状态:
    只需要转换成vc++即可

    注:②、③参数引用与①不同。


    五、应用分析:

    可以说IT技术在制造业得到了广泛的应用,而打印控制与监控则是制造业中众多应用中的较为典型的应用。通常,在生产制造过程中,都有很多打印机用于打印生产排序单、装配单、铭牌、标签等等。因此打印机的时时状态(缺纸、墨尽、卡纸)在这里就显得尤为重要了,如果不能及时的监控到打印机的状态势必会影响生产的正常持续运行。所以为了保证生产正常运行拥有一套用于监控打印机时时状态的程序是很有必要的。

     

    2、VC++的代码

    BOOL GetJobs(HANDLE hPrinter,        /* Handle to the printer. */ 
                    JOB_INFO_2 **ppJobInfo, /* Pointer to be filled.  */ 
                    int *pcJobs,            /* Count of jobs filled.  */ 
                    DWORD *pStatus)         /* Print Queue status.    */ 
       {
       DWORD               cByteNeeded,
                            nReturned,
                            cByteUsed;
        JOB_INFO_2          *pJobStorage = NULL;
        PRINTER_INFO_2       *pPrinterInfo = NULL;
    
       /* Get the buffer size needed. */ 
           if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded))
           {
               if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
                   return FALSE;
           }
    
           pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded);
           if (!(pPrinterInfo))
               /* Failure to allocate memory. */ 
               return FALSE;
    
           /* Get the printer information. */ 
           if (!GetPrinter(hPrinter,
                   2,
                   (LPSTR)pPrinterInfo,
                   cByteNeeded,
                   &cByteUsed))
           {
               /* Failure to access the printer. */ 
               free(pPrinterInfo);
               pPrinterInfo = NULL;
               return FALSE;
           }
    
           /* Get job storage space. */ 
           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)
           {
               /* Failure to allocate Job storage space. */ 
               free(pPrinterInfo);
               pPrinterInfo = NULL;
               return FALSE;
           }
    
           ZeroMemory(pJobStorage, cByteNeeded);
    
           /* Get the list of jobs. */ 
           if (!EnumJobs(hPrinter,
                   0,
                   pPrinterInfo->cJobs,
                   2,
                   (LPBYTE)pJobStorage,
                   cByteNeeded,
                   (LPDWORD)&cByteUsed,
                   (LPDWORD)&nReturned))
           {
               free(pPrinterInfo);
               free(pJobStorage);
               pJobStorage = NULL;
               pPrinterInfo = NULL;
               return FALSE;
           }
    
           /*
            *  Return the information.
            */ 
           *pcJobs = nReturned;
           *pStatus = pPrinterInfo->Status;
           *ppJobInfo = pJobStorage;
           free(pPrinterInfo);
    
           return TRUE;
    
       }
    
       BOOL IsPrinterError(HANDLE hPrinter)
       {
    
           JOB_INFO_2  *pJobs;
           int         cJobs,
                       i;
           DWORD       dwPrinterStatus;
    
           /*
            *  Get the state information for the Printer Queue and
            *  the jobs in the Printer Queue.
            */ 
           if (!GetJobs(hPrinter, &pJobs, &cJobs, &dwPrinterStatus))
               return FALSE;
    
           /*
            *  If the Printer reports an error, believe it.
            */ 
           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;
           }
    
           /*
            *  Find the Job in the Queue that is printing.
            */ 
           for (i=0; i < cJobs; i++)
           {
               if (pJobs[i].Status & JOB_STATUS_PRINTING)
               {
                   /*
                    *  If the job is in an error state,
                    *  report an error for the printer.
                    *  Code could be inserted here to
                    *  attempt an interpretation of the
                    *  pStatus member as well.
                    */ 
                   if (pJobs[i].Status &amp;
                       (JOB_STATUS_ERROR |
                       JOB_STATUS_OFFLINE |
                       JOB_STATUS_PAPEROUT |
                       JOB_STATUS_BLOCKED_DEVQ))
                   {
                       return TRUE;
                   }
               }
           }
    
           /*
            *  No error condition.
            */ 
           return FALSE;
    
       }

    3、确定打印队列的状态(C++代码)

    问题
      有时,程序员需要显示存在于系统中的各种打印机中打印作业的状态,但似乎不能找到一种方法来查询当前哪些打印机是可用的以及在这些打印机上正在运行哪些作业。
      那么,如何利用 Windows API 函数来查询可用的打印机及其所处的工作状态呢?

    方法
      在 Windows NT 版本以及 Windows 9x 中,增加了一批全新的、专门用来处理打印机及打印机队列状态的 API 函数。在本节中,将讨论 API 函数 EnumPrinters 与 EnumJobs,这两个函数可提供给程序员确定打印作业状态所需的信息。
      在 Windows 9x 中添加的函数 EnumPrinters,用来列出所有正在有效运行的打印机的名称及其标识符,此函数可用于列出用户能够访问的无论是在本地工作的还是在网络上运行的所有打印机,在本节的例子中,我们只考虑本地打印机的情况。
      新的 Windows 9x API 中增加的另一个函数 EnumJobs,用来列出所指定打印机上正在打印的作业,为了能够使用这个函数,必须有打印机的句柄,这就需要使用另外一个 API 函数 OpenPrinter。
      需要注意的是,这几个 API 函数只能在 Windows 9x 以及 Windows NT 中使用。

    步骤
      按照下列方法生成一个例子程序。选择菜单 Dialog,并从此菜单中选择菜单项 Printer Jobs,此时显示一个所有可用打印机的对话框,在第一个列表框中选择其中一个打印机后,即在第二个列表框中显示该打印机的作业列表。

      实现例子程序的步骤如下:
      1.在 Visual C++ 中利用 AppWizard 创建新的工程 Ld104。
      2.进入 AppStudio,创建新的对话框。把按钮 OK 与 Cancel 移动到对话框的底部。在对话框中添加两个列表框。
      3.进入 ClassWizard,为刚创建的对话模板生成新的对话框类,把此新类命名为 CPrintQDlg。
      4.在 ClassWizard 中,从下拉列表中选择类 CPrintQDlg,从对象列表中选择对象 CPrintQDlg,从消息列表中选择消息 WM_INITDIALOG,点击按钮 Add Function 添加新的函数 OnInitDialog。把下面的代码输入到类 CPrintQDlg 的方法 OnInitDialog 中。

    BOOL CPrintQDlg::OnInitDialog() 
    {
        CDialog::OnInitDialog();
    
        int size=4096;
        unsigned long sizeNeeded=0;
        unsigned long numPrinters;
        PPRINTER_INFO_1 pPrinters;
        pPrinters=(PPRINTER_INFO_1)LocalAlloc((LMEM_FIXED/LMEM_ZEROINIT),size);
        int ret=EnumPrinters(PRINTER_ENUM_LOCAL,NULL,1,
            (LPBYTE)pPrinters,size,&sizeNeeded,&numPrinters);
        CListBox * list=(CListBox *)GetDlgItem(IDC_LIST1);
        for(int i=0;i<(int)numPrinters;++i)
        list->AddString(pPrinters[i].pName);
        LocalFree(pPrinters);
    
        return TRUE;  // return TRUE unless you set the focus to a control
    }

      5.在 ClassWizard 中,从下拉列表中选择类 CPrintQDlg,从对象列表中选择对象 IDC_LIST1,从消息列表中选择消息 LBN_SELCHANGE,点击按钮 Add Function 添加新的函数 OnSelectPrinter。把下面的代码输入到类 CPrintQDlg 的方法 OnSelectPrinter 中。

    void CPrintQDlg::OnSelectPrinter()
    {
        HANDLE handle;
        JOB_INFO_1 jobs[10];
    
        CListBox * list1=(CListBox *)GetDlgItem(IDC_LIST1);
        char buf[256];
        list1->GetText(list1->GetCurSel(),buf);
    
        if(!OpenPrinter(buf,&handle,NULL))
        {
        MessageBox("Could not open printer","Error",
            MB_OK/MB_ICONINFORMATION);
        return;
        }
    
        DWORD size=sizeof(jobs);
        DWORD numBytes=0;
        DWORD numEntries=0;
        int ret=EnumJobs(handle,0,10,1,(LPBYTE)jobs,
            size,&numBytes,&numEntries);
    
        CListBox * list2=(CListBox *)GetDlgItem(IDC_LIST2);
        for(int i=0;i<(int)numEntries;++i)
        {
        char buf[80];
        sprintf(buf,"Job %ld",jobs[i].JobId);
        if(jobs[i].pStatus!=NULL)
            strcat(buf,jobs[i].pStatus);
        else
        {
            switch(jobs[i].Status)
            {
            case JOB_STATUS_PAUSED:
                strcat(buf," Paused");
                break;
            case JOB_STATUS_PRINTED:
                strcat(buf," Printed");
                break;
            case JOB_STATUS_PRINTING:
                strcat(buf," Printing");
                break;
            case JOB_STATUS_SPOOLING:
                strcat(buf," Spooling");
                break;
            }
        }
        list2->AddString(buf);
        }
    }

      6.把下面一行代码添加到文件 PrintQDlg.cpp 的顶端。
      #include "winspool.h"
      7.进入 AppStudio 并在菜单 IDR_MAINFRAME 中添加新菜单 Dialog。在此菜单中添加标题为 Printer Jobs 的菜单项,标识符命名为 ID_PRINTER_JOBS。
      8.进入 ClassWizard,从下拉组合框中选择对象 CMainFrame,从对象列表中选择对象 ID_PRINTER_JOBS,从消息列表中选择消息 COMMAND,点击按钮 Add Function 添加新的函数 OnPrinterJobs,把下面的代码输入到此方法中。

    void CMainFrame::OnPrinterJobs()
    {
        CPrintQDlg dlg;
    
        dlg.DoModal();
    }

      9.把下面一行代码添加到文件 MainFrame.cpp 的顶端。
      #include "PrintQDlg.h"
      10.编译并运行此例子程序。

    4、更完整的例子可以参考微软的文章:

    http://support.microsoft.com/support/kb/articles/Q158/8/28.asp
    http://support.microsoft.com/support/kb/articles/Q228/7/69.asp

     

    整理自:https://bbs.csdn.net/topics/50015663

    展开全文
  • 使用python实现连接打印机批量打印文件python打印文件python连接打印机python打印文档文件python打印图片文件python批量打印文文件 python打印文件 python连接打印机 使用模块:win32print 官方文档: 模块win32...

    python打印文件

    python连接打印机

    使用模块:win32print
    官方文档: 模块win32print.

    pip install pywin32
    import win32print
    import win32api

    查看当前电脑上安装了哪些打印机:

    #查看当前电脑上安装了哪些打印机:
    import win32print
    printers = win32print.EnumPrinters(3)
    print(printers)
    

    结果显示有两台打印机
    获取默认打印机:

    #查看当前电脑上安装了哪些打印机:
    import win32print
    printer = win32print.GetDefaultPrinter()
    print(printer)
    

    默认的打印机

    python打印文档文件

    对于微软office的文档、pdf、txt等有用,前提是要有打开这些文件的软件,不然会报错:

    // An highlighted block
    def printer_file(filename):
        win32api.ShellExecute (
        0,
        "print",
        filename,
        '/d:"%s"' % win32print.GetDefaultPrinter (),
        ".",
        0
        )
        print(filename+'----打印成功')
    printer_loading(r'E:\img\1.jpg')
    

    python打印图片文件

    电脑上有图片查看器,不然会报错

    
    
    def printer_pic(pic_path, printer_name):
        # 物理宽度、高度
        PHYSICALWIDTH = 110
        PHYSICALHEIGHT = 111
        # 物理偏移位置
        PHYSICALOFFSETX = 112
        PHYSICALOFFSETY = 113
        printer_name = win32print.GetDefaultPrinter()
        hDC = win32ui.CreateDC()
        hDC.CreatePrinterDC(printer_name)
        printer_size = hDC.GetDeviceCaps(PHYSICALWIDTH), hDC.GetDeviceCaps(PHYSICALHEIGHT)
        # printer_margins = hDC.GetDeviceCaps (PHYSICALOFFSETX), hDC.GetDeviceCaps (PHYSICALOFFSETY)
        # 打开图片
        # #通过每个像素使它尽可能大
        # #页面不失真。
        bmp = Image.open(file_name)
        ratios = [1.0 * 1754 / bmp.size[0], 1.0 * 1240 / bmp.size[1]]
        scale = min(ratios)
        # #开始打印作业,并将位图绘制到
        # #按比例缩放打印机设备。
        hDC.StartDoc(file_name)
        hDC.StartPage()
        dib = ImageWin.Dib(bmp)
        scaled_width, scaled_height = [int(scale * i) for i in bmp.size]
        print(scaled_width, scaled_height)
        x1 = int((printer_size[0] - scaled_width) / 2)
        y1 = int((printer_size[1] - scaled_height) / 2)
        # 横向位置坐标
        x1 = 1580
        # 竖向位置坐标
        y1 = 30
        # 4倍为自适应图片实际尺寸打印
        x2 = x1 + bmp.size[0] * 4
        y2 = y1 + bmp.size[1] * 4
        dib.draw(hDC.GetHandleOutput(), (x1, y1, x2, y2))
    
        hDC.EndPage()
        hDC.EndDoc()
        hDC.DeleteDC()
    
    
    printer_name = win32print.GetDefaultPrinter()
    pic_path = r'E:\file\img\2.jpg'
    printer_pic(file_name, printer_name)
    
    

    这个时候可以发现你连上的默认打印机已经开始打印了

    python批量打印文文件

    使用ThreadPoolExecutor线程池来批量打印文件

    import win32ui
    from PIL import Image, ImageWin
    from concurrent.futures import ThreadPoolExecutor
    import win32api
    import win32print
    import os
    import collections
    
    
    class Printer:
        def __init__(self):
            self.printer_name = win32print.GetDefaultPrinter()
            self.path = None
            self.file_path_list = []
    
        # 打印启动项
        def printer_loading(self, path):
            self.path = path
            png_path_list, pdf_path_list = self.get_file_all()
            executor = ThreadPoolExecutor(max_workers=3)
            executor.map(self.printer_png_loading, png_path_list)
            executor.map(self.printer_other_loading, pdf_path_list)
    
        # 打印图片
        def printer_png_loading(self, file_path):
            try:
                # HORZRES / VERTRES = printable area 可打印的区域
                HORZRES = 8
                VERTRES = 10
                # PHYSICALWIDTH/HEIGHT = total area 总面积
                #
                PHYSICALWIDTH = 110
                PHYSICALHEIGHT = 111
                printer_name = win32print.GetDefaultPrinter()
                hDC = win32ui.CreateDC()
                hDC.CreatePrinterDC(printer_name)
                printable_area = hDC.GetDeviceCaps(HORZRES), hDC.GetDeviceCaps(VERTRES)
                printer_size = hDC.GetDeviceCaps(PHYSICALWIDTH), hDC.GetDeviceCaps(PHYSICALHEIGHT)
                # #打开图像,如果宽度大于高,计算出要乘的倍数
                # #通过每个像素使它尽可能大
                # #页面不失真。
                bmp = Image.open(file_path)
                if bmp.size[0] > bmp.size[1]:
                    bmp = bmp.rotate(90)
    
                ratios = [1.0 * printable_area[0] / bmp.size[0], 1.0 * printable_area[1] / bmp.size[1]]
                scale = min(ratios)
    
                # #开始打印作业,并将位图绘制到
                # #按比例缩放打印机设备。
                hDC.StartDoc(file_path)
                hDC.StartPage()
    
                dib = ImageWin.Dib(bmp)
                scaled_width, scaled_height = [int(scale * i) for i in bmp.size]
                x1 = int((printer_size[0] - scaled_width) / 2)
                y1 = int((printer_size[1] - scaled_height) / 2)
                x2 = x1 + scaled_width
                y2 = y1 + scaled_height
                dib.draw(hDC.GetHandleOutput(), (x1, y1, x2, y2))
    
                hDC.EndPage()
                hDC.EndDoc()
                hDC.DeleteDC()
    
                print('-ok!!--The picture prints normally---' + file_path)
            except Exception as ex:
                print('-error!!--Picture prints abnormally---' + file_path)
                print(repr(ex))
    
        # 打印其他文件
        def printer_other_loading(self, file_path):
            try:
                open(file_path, "r")
                win32api.ShellExecute(
                    0,
                    "print",
                    file_path,
                    '/d:"%s"' % self.printer_name,
                    ".",
                    0
                )
                print('--ok!!-the pdf prints normally---' + file_path)
            except Exception as ex:
                print(repr(ex))
                print('-error!!--the pdf prints abnormally---', + file_path)
    
        # 递归查找文件,并放入到对应的列表中
        def get_file_all(self):
            dl = collections.deque()
            dl.append(self.path)
            png_path_list = []
            pdf_path_list = []
            while len(dl) != 0:
                pop = dl.popleft()
                listfile = os.listdir(pop)
                for i in listfile:
                    newpath = os.path.join(pop, i)
                    if os.path.isdir(newpath):
                        print("目录:", newpath)
                        dl.append(newpath)
                    else:
                        if newpath.split(".")[-1] in ['png', 'img', 'jpg', 'jpeg']:
                            png_path_list.append(newpath)
                        elif newpath.split(".")[-1] in ['pdf', 'txt', 'xlsx', 'md', 'word']:
                            pdf_path_list.append(newpath)
            return png_path_list, pdf_path_list
    
    
    if __name__ == '__main__':
        path = r'E:\file'
        Printer().printer_loading(path)
    
    
    
    展开全文
  • 打印机监控系统.rar

    2019-08-23 13:57:31
    打印机监控系统 打印任务监控 读取内存生成图片 ,实时监测 支持.spl文件转emf,可将emf上传服务器。
  • 共享打印机监控工具

    2016-05-25 16:17:29
    1. 该软件无须安装,直接将软件包解压缩到一个目录下,运行PrinterMon.exe程序即可。 2. 如果需要该程序随系统启动而自动启动,则在...7. 该软件主要为企业管理者提供打印机、纸张、文件档案等公司资源的监控服务。
  • 打印技术之打印机状态监控

    千次阅读 2015-03-24 18:29:14
     在上一篇博文中我主要介绍了如何获取以及设置系统的默认打印机,本文将介绍如何对打印机状态进行实时监控,记录下所打印的文档、打印的份数以及打印时间等打印信息。   1.打印机虚脱机技术  在正式介绍如何对...

    http://www.cnblogs.com/menlsh/p/4211988.html



      在上一篇博文中我主要介绍了如何获取以及设置系统的默认打印机,本文将介绍如何对打印机状态进行实时监控,记录下所打印的文档、打印的份数以及打印时间等打印信息。

     

    1.打印机虚脱机技术

      在正式介绍如何对打印机状态进行实时监控之前,我们有必要先了解一下打印机虚脱机技术。

      独占设备是指在一个程序(作业、用户)的整个运行期间独占设备,直到该程序(作业、用户)完成。系统的独占设备是有限的(比如,一台计算机只能够连接一台打印机),往往不能够满足多进程的要求,会引起大量进程由于等待某些独占设备而阻塞。另一方面,申请到独立设备的进程在其整个运行期间占有设备,利用率却非常低,造成独占设备长时间处于空闲状态。

      为了解决这种矛盾,最常用的办法就是利用共享设备来模拟独占设备,从而提高系统效率和独占设备的利用率。该技术就是虚脱机技术(SPOOL:Simultaneous Peripaheral Operation On Line)。

      打印机是典型的独占设备,引入虚脱机技术后,用户的打印请求传递给SPOOL系统,而不是真正的把打印机分配给用户。SPOOL系统先在磁盘上申请一个空闲区域,把需要打印的数据传输到里面,再把用户的打印请求挂到打印机队列上。如果打印机空闲,就会从打印机队列中取出一个打印请求,再从磁盘的对应区域取出数据,执行打印操作。由于磁盘是共享的,SPOOL系统可以随时响应打印请求并把数据缓存起来,以此实现独占设备模拟共享设备,从而提高系统效率和独占设备的利用率。

     

    2.枚举当前打印机的打印任务

      在Windows API中提供了如下一些打印相关枚举函数:

      EnumForms();         //枚举当前打印机支持的所有页型

      EnumJobs();           //枚举当前打印机的打印任务

      EnumMonitors();         //枚举可用监视器

      EnumPorts();          //枚举可用的打印端口

      EnumPrinterDrivers();     //枚举打印机驱动程序

      EnumPrinters();          //枚举打印机

      EnumPrinterProcessors();   //枚举打印进程

      我们要监控打印机状态,需要用到EnumJobs()函数,用来枚举当前打印机的打印任务。该函数的原型如下:

    复制代码
     1 BOOL
     2 WINAPI
     3 EnumJobs(
     4     HANDLE  hPrinter,
     5     DWORD   FirstJob,
     6     DWORD   NoJobs,
     7     DWORD   Level,
     8     LPBYTE  pJob,
     9     DWORD   cbBuf,
    10     LPDWORD pcbNeeded,
    11     LPDWORD pcReturned
    12 );
    复制代码

      其中,参数hPrinter表示打印机对象句柄;参数FirstJob表示作业列表中要枚举的第一个作业的索引(索引号从0开始);参数NoJobs表示要枚举的作业数量;参数Level表示级别(取值可以是1或2);参数pJob表示JOB_INFO_x结构的缓冲区(x由参数Level决定);参数cbBuf表示JOB_INFO_x结构的缓冲区大小;参数pcbNeeded用于保存请求的缓冲区长度;参数pcReturned则表示了载入缓冲区的结构数量。

     

    3.具体编程实现

      了解了EnumJobs()函数之后,我们就可以开始编写具体的代码了。

    3.1获得打印机对象句柄

      我们知道,EnumJobs()函数的第一个参数是打印机对象句柄hPrinter,所以在调用EnumJobs()函数之前,我们需要获得打印机对象句柄,这可以通过调用OpenPrinter()函数来实现。该函数原型为:

    复制代码
    1 BOOL
    2 WINAPI
    3 OpenPrinter(
    4    LPSTR    pPrinterName,
    5    LPHANDLE phPrinter,
    6    LPPRINTER_DEFAULTS pDefault
    7 );
    复制代码

      其中,参数pPrinterName是打印机的名称;参数phPrinter就是我们想要得到的打印机对象句柄。

    3.2获取打印状态

      获取得到打印机对象句柄之后,我们便可以使用EnumJobs()函数来枚举打印任务,从而得到打印状态了。具体实现方法如下:

    复制代码
     1 /*
     2  * 函数功能 : 显示打印机状态
     3  * 备    注 : 
     4  * 作    者 : 博客园 依旧淡然
     5  */
     6 void CPrintDemoDlg::ShowPrinterStatus()
     7 {
     8     HANDLE printerHandle;                //打印机设备句柄
     9     
    10     //检测打开打印机设备是否成功
    11     if(!OpenPrinter(m_strPrinterName.GetBuffer(0), &printerHandle, NULL))
    12         return;
    13     
    14     DWORD nByteNeeded;
    15     DWORD nReturned;
    16     DWORD nByteUsed;
    17     
    18     //通过调用GetPrinter()函数得到作业数量
    19     PRINTER_INFO_2* pPrinterInfo = NULL;
    20     GetPrinter(printerHandle, 2, NULL, 0, &nByteNeeded);
    21     pPrinterInfo = (PRINTER_INFO_2*)malloc(nByteNeeded);
    22     GetPrinter(printerHandle, 2, (LPBYTE)pPrinterInfo, nByteNeeded, &nByteUsed);
    23     
    24     //通过调用EnumJobs()函数枚举打印任务
    25     JOB_INFO_2* pJobInfo = NULL;
    26     EnumJobs(printerHandle, 0, pPrinterInfo->cJobs, 2, NULL, 0, 
    27         (LPDWORD)&nByteNeeded, (LPDWORD)&nReturned);
    28     pJobInfo = (JOB_INFO_2*)malloc(nByteNeeded);
    29     ZeroMemory(pJobInfo, nByteNeeded);
    30     EnumJobs(printerHandle, 0, pPrinterInfo->cJobs, 2, (LPBYTE)pJobInfo, nByteNeeded, 
    31         (LPDWORD)&nByteUsed, (LPDWORD)&nReturned);
    32     
    33     //检测当前是否有打印任务
    34     if(pPrinterInfo->cJobs == 0)
    35         return;
    36     
    37     //纸张类型
    38     CString strPageSize = _T("");
    39     if(pJobInfo[0].pDevMode->dmPaperSize == DMPAPER_A4)
    40         strPageSize = _T("A4");
    41     else if(pJobInfo[0].pDevMode->dmPaperSize == DMPAPER_B5)
    42         strPageSize = _T("B5");
    43 
    44     //打印份数
    45     CString strPrintCopies = _T("");
    46     strPrintCopies.Format("%d", pJobInfo[0].pDevMode->dmCopies);
    47 
    48     //打印颜色
    49     CString strPrintColor = _T("");
    50     if(pJobInfo[0].pDevMode->dmColor == DMCOLOR_COLOR)
    51         strPrintColor = _T("彩色");
    52     else if(pJobInfo[0].pDevMode->dmColor == DMCOLOR_MONOCHROME)
    53         strPrintColor = _T("黑白");
    54 
    55     //打印时间
    56     CString strSubmitted = _T("");
    57     strSubmitted.Format("%d-%d-%d %d:%d:%d",
    58         pJobInfo[0].Submitted.wYear, pJobInfo[0].Submitted.wMonth, pJobInfo[0].Submitted.wDay,
    59         pJobInfo[0].Submitted.wHour+8, pJobInfo[0].Submitted.wMinute, pJobInfo[0].Submitted.wSecond);
    60 
    61   //更新打印机状态列表控件
    62     UpdateDataPrinterStatusListCtrl(pJobInfo[0].pDocument, strPageSize,
    63         strPrintCopies, strPrintColor, strSubmitted);
    64 
    65     free(pPrinterInfo);
    66     
    67     //关闭打印机设备
    68     ClosePrinter(printerHandle);
    69 }
    复制代码

      可以看到,在上述代码中,我们首先调用OpenPrinter()函数得到了打印机设备句柄printerHandle,然后通过调用GetPrinter()函数来为PRINTER_INFO_2结构体对象pPrinterInfo赋值,从而进一步通过pPrinterInfo->cJobs得到打印机作业数量。随后,我们通过调用EnumJobs()函数枚举打印任务,为JOB_INFO_2结构体对象pJobInfo赋值。JOB_INFO_2结构体中便存储了我们需要得到的一系列打印机状态信息。最后,我们调用了UpdateDataPrinterStatusListCtrl()函数,将打印机状态信息显示在一个列表控件上。

      程序运行结果如图1所示。在打印机选择下拉列表中,会列出当前系统中的所有打印机,选择要监听的打印机之后,点击开始监听按钮,便会创建一个子线程,对打印机状态进行监听(我这里因为没有连接打印机,所以使用的是虚拟打印机Adobe PDF)。当有文档被打印时,打印状态便会实时的显示在列表中。

    图1 打印机状态监控

      由图1可以看出,目前我们已经可以得到打印的文档名称、纸张类型、打印份数、打印颜色以及打印时间这些信息了。如何能够获取得到更多的打印信息呢?比如打印文档的路径、内容、大小、页数等信息,又比如在打印文档中加入自定义页眉、页脚或是水印等。这些功能我还在进一步研究学习,哪位博友若是有这方面的经验,还望指点,我将不胜感激。


    展开全文
  • 打印机监控-printermon

    2015-01-29 11:40:21
    7. 该软件主要为企业管理者提供打印机、纸张、文件档案等公司资源的监控服务。 因为网络和系统的复杂性,监视到的打印作业资料不表示一定准确,请不要盲目地 依此作出什么结论性的判断。 8. 请不要超越您自己的...
  • 打印文件中的spl文件,解析成可用的emf文件源码,用于打印监控相关。
  • 管理打印机打印ubuntu环境下把word文档转换成pdf在linux中如何使用CUPS进行打印CUPS(Common UNIX Printing System)通用打印系统**,是linux的打印机打印作业管理器。LPD(行式打印机守护程序),使用等宽字符和...
  • 监控打印机

    2019-01-08 06:20:10
    监控打印机状态参数记录: _JOB_INFO_2W = record JobId: DWORD; pPrinterName: LPWSTR; pMachineName: LPWSTR; pUserName: LPWSTR; pDocument: LPWSTR; pNotifyName: LPWSTR; pDatatype: LPWSTR; ...
  • 打印机厂商列表无Generic的解决方案Generic-Text-Only驱动,在添加打印机的时候选择从硬盘安装,然后选择里面的inf文件安装即可,安装后可以在打印机列表选择Generic-Text-Only这个打印机,可以将部分打印文件保存为...
  • 打印文件和减少文件数量 释放打印机控制 技术员流程 反复检查打印机是否缺纸 当打印机缺纸时,请以最大纸张数量装满 然后,合成过程将是 一个学生进程将打印3个文档。 一个学生进程将打印2个文档 一个技术员过程,...
  • 未注册用户无权打印文件。当系统检测到非法用户,将会自动删除打印任务,并记录打印日志。经过测试证明,该方案能实现对用户和打印任务进行有效的监控,为企业内部的打印机管理提供了方便、快捷的途径。
  • 需求:开发一个虚拟打印机,提供给客户端使用。客户端使用这个虚拟打印机生成文档保存内打印容和设置好的打印选项(打印机选项和文档...得到两个文件,一个保存打印内容(.spl)(或直接保存成图片?),一个保存打印选...
  • 易语言源码易语言监控打印源码.rar 易语言源码易语言监控打印源码.rar 易语言源码易语言监控打印源码.rar 易语言源码易语言监控打印源码.rar 易语言源码易语言监控打印源码.rar 易语言源码易语言监控打印源码....
  • 未注册用户无权打印文件。当系统检测到非法用户,将会自动删除打印任务,并记录打印日志。经过测试证明,该方案能实现对用户和打印任务进行有效的监控,为企业内部的打印机管理提供了方便、快捷的途径。
  • 3、运行一次后,以后每次开机将会自动隐身监控打印机作业信息; 4、运行以后你将看不到程序的运行主界面,你可以按Ctrl+Alt+F10键调出程序。  5、调出程序后将有一个密码验证画面,初始化密码为admin,你可以在...
  • 打印信息获取(分析SPOOL文件

    热门讨论 2013-11-10 22:33:46
    每一个打印任务在发送给打印机前都会将任务压缩成制定文件(SHD, SPL)一个为打印任务信息,另外一个为任务压缩文档(类似压缩bitmap)。这就为我们除了HOOK打印函数、注册打印消息、生成虚拟打印机接替系统打印...
  • 可以支持监控打印机文档标题,保存打印电脑的IP等相关打印信息。包括纸张数量
  • 2.以用户管理和用户配额管理为中心的打印机任务防火墙,通过阻止非法用户或者打印配额不足的用户使用打印机打印文件,彻底改变企业内部打印资源被随意使用的局面,是企业降低打印成本,培养员工珍惜打印资源
  • 完整的打印机监控源码

    热门讨论 2013-01-30 11:29:13
    负责监控该电脑的打印动作。并把内容转成图片储存。并将图片传送到服务器机器上,并将打印内容传到服务器上面. 解决方案: 1. 先用api打印函数连接到指定的打印机.再试着用枚举函数()获得打印作业信息.根据信息得知...
  • 易语言监控打印源码
  • 第一部分:介绍如何与Zebar进行连接,把ZPL指令或者模板文件发送到斑马打印机进行打印。 第二部分:介绍如何接收Zebar进行打印之后如何得到斑马打印机的反馈信息,防止打印出错的情况下继续进行工业的操作。需要用...
  • 打印机监控程序

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,784
精华内容 3,513
关键字:

如何监控打印机打印的文件