Как я могу узнать, какой пользователь отправляет команду печати на сервер Windows / Windows программно? - PullRequest
1 голос
/ 15 января 2010

У меня есть сеть Windows (peer-2-peer), а также Active Directory, и мне нужно регистрировать имена пользователей, которые отправляют любые виды печати на сервер. Я хочу написать программу для регистрации их имени пользователя и / или соответствующего IP-адреса, и я знаком с c # .net и c ++, но я не нашел никакой подсказки относительно того, как решить мою проблему.

Есть ли какой-нибудь способ поймать их имя с помощью WMI или следует запачкать мою руку с помощью API (но какой API я понятия не имею)?

С уважением.

Ответы [ 4 ]

1 голос
/ 15 января 2010

Эти функции доступны в 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.

1 голос
/ 15 января 2010

Я бы пошел с использованием WMI. Это дает вам возможность запрашивать пакеты принтеров, связанных с вашей системой, а также извлекать все вспомогательные свойства. Это так же просто, как ...

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

... создание поискового объекта WMI и перечисление результатов.

Вот пример:

WMI-принтеры запросов

1 голос
/ 15 января 2010

Я использовал это в прошлом, и если он не имеет всего, что вам нужно, он должен по крайней мере позаботиться о мониторинге очередей печати. ​​

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

Ссылка на исходный код (из комментария ОП):
http://www.codeproject.com/KB/printing/printwatchvbnet.aspx

0 голосов
/ 16 октября 2012

Узнайте, какой пользователь отправил задание на печать с помощью C ++ в Windows.

#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 ;
}
...