如何找出哪个用户以编程方式将打印命令发送到windows / windows服务器?

时间:2010-01-15 19:46:22

标签: windows printing monitor logging

我有一个Windows网络(peer-2-peer)和Active Directory,我需要记录向服务器发送任何类型打印的用户名。 我想编写一个程序来记录他们的用户名和/或他们各自的IP,我熟悉c#.net和c ++,但我没有找到任何关于如何解决我的问题的线索。

有什么方法可以在WMI的帮助下找到他们的名字,或者应该用API弄脏我的手(但我不知道哪个API)?

问候。

4 个答案:

答案 0 :(得分:1)

我过去曾经使用过它,如果它没有你需要的全部内容,至少应该监控打印队列。

http://www.merrioncomputing.com
http://www.merrioncomputing.com/Download/PrintQueueWatch/PrinterQueueWatchLicensing.htm

源代码链接(来自OP的评论):
http://www.codeproject.com/KB/printing/printwatchvbnet.aspx

答案 1 :(得分:1)

这些功能在Spooler API下公开。

EnumJobs将枚举给定打印机的所有当前作业。它将返回JOB_INFO_1结构,其中包含与给定打印作业关联的用户名:

typedef struct _JOB_INFO_1 {
  DWORD      JobId;
  LPTSTR     pPrinterName;
  LPTSTR     pMachineName;
  LPTSTR     pUserName;
  LPTSTR     pDocument;
  LPTSTR     pDatatype;
  LPTSTR     pStatus;
  DWORD      Status;
  DWORD      Priority;
  DWORD      Position;
  DWORD      TotalPages;
  DWORD      PagesPrinted;
  SYSTEMTIME Submitted;
}JOB_INFO_1, *PJOB_INFO_1;

如果您更喜欢WMI,可以将wmic.exe/node开关(或首选版本)和Win32_PrintJob类一起使用。大致是:

c:\> wmic /node 10.0.0.1 
wmic> SELECT * FROM Win32_PrintJob

...将返回包含所选服务器的所有打印作业信息的结构。您可以使用WHERE子句过滤。

答案 2 :(得分:1)

我会选择使用WMI。这使您能够查询与您的系统关联的打印机批次的打印机,并提取所有支持属性。它就像......一样简单。

System.Management.ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_PrintJob");

...创建一个WMI对象搜索器并枚举结果。

以下是一个例子:

WMI query printers

答案 3 :(得分:0)

找出哪个用户在Windows中使用C ++发送了打印作业。

#include <WinSpool.h>

wstring GetUserNameFromPrintJob(wstring m_strFriendlyName)
{
  wstring strDocName = L"";
  wstring strMachineName = L"";
  wstring strUserName = L"";

  HANDLE hPrinter ;
  if ( OpenPrinter(const_cast<LPWSTR>(m_strFriendlyName.c_str()), &hPrinter, NULL) == 0 )
  {    
    /*OpenPrinter call failed*/    
  }

  DWORD dwBufsize = 0;
  PRINTER_INFO_2* pinfo = 0;
  GetPrinter(hPrinter, 2,(LPBYTE)pinfo, dwBufsize, &dwBufsize); //Get dwBufsize

  PRINTER_INFO_2* pinfo2 = (PRINTER_INFO_2*)malloc(dwBufsize); //Allocate with dwBufsize
  GetPrinter(hPrinter, 2,(LPBYTE)pinfo2, dwBufsize, &dwBufsize);

  DWORD numJobs = pinfo2->cJobs;
  free(pinfo2); 

  JOB_INFO_1 *pJobInfo = 0;
  DWORD bytesNeeded = 0, jobsReturned = 0;

  //Get info about jobs in queue.
  EnumJobs(hPrinter, 0, numJobs, 1, (LPBYTE)pJobInfo, 0,&bytesNeeded,&jobsReturned);
  pJobInfo = (JOB_INFO_1*) malloc(bytesNeeded);
  EnumJobs(hPrinter, 0, numJobs, 1, (LPBYTE)pJobInfo, bytesNeeded, &bytesNeeded, &jobsReturned);


  JOB_INFO_1 *pJobInfoInitial = pJobInfo;
  for(unsigned short count = 0; count < jobsReturned; count++)
  {
    if (pJobInfo != NULL)
    {
      strUserName  = pJobInfo->pUserName  //username
      strMachineName = pJobInfo->pMachineName;   //machine name
      strDocName  = pJobInfo->pDocument; // Document name
      DWORD dw = pJobInfo->Status;         
    }
    pJobInfo++;
  }

  free(pJobInfoInitial);
  ClosePrinter( hPrinter );
  return strUserName ;
}