我有一个 Windows 网络(peer-2-peer)以及 Active Directory,我需要记录向服务器发送任何类型打印的用户的名称。我想编写一个程序来记录他们的用户名和/或他们各自的 IP,并且我熟悉 c#.net 和 c++,但我还没有找到任何关于如何解决我的问题的线索。
有没有什么方法可以在 WMI 的帮助下抓住他们的名字,或者应该用 API 弄脏我的手(但我不知道哪个 API)?
问候。
我过去使用过它,如果它没有你需要的所有东西,它至少应该负责监控打印队列。
http://www.merrioncomputing.com
http://www.merrioncomputing.com/Download/PrintQueueWatch/PrinterQueueWatchLicensing.htm
源代码链接(来自 OP 的评论): http:
//www.codeproject.com/KB/printing/printwatchvbnet.aspx
这些功能在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
子句进行过滤。
我会选择使用 WMI。这使您能够查询与您的系统关联的打印机批次以及提取所有支持属性。这很简单...
System.Management.ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_PrintJob");
...创建一个 WMI 对象搜索器并枚举结果。
这是一个例子:
找出哪个用户在 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 ;
}