在 printspooler 中使用 SetJob 函数 API
using SetJob function in printspooler API
我正在使用我发现的 getJobs 函数来获取打印机(而非打印设备)中的当前打印作业。到目前为止,我可以知道我的虚拟打印机队列中有多少打印作业,并且我有来自 JOB_INFO_ strucs 的信息需要处理,但我正在尝试使用 SetJob() 从打印中删除作业队列(存储我想要的信息后)。有了这个我得到一个错误:
0xC0000005: Access violation reading location 0x00002012.
我的问题是,我究竟做错了什么?我已经尝试将 0 作为级别,将 NULL 作为 pJob,然后我没有收到错误,但打印作业仍在队列中。我似乎找不到任何其他人有解释的例子。
BOOL getJobs(LPTSTR printerName) {
HANDLE hPrinter; //Printer handle variable
DWORD dwNeeded, dwReturned, i; //Mem needed, jobs found, variable for loop
JOB_INFO_1 *pJobInfo; // pointer to structure
//Find printer handle
if (!OpenPrinter(printerName, &hPrinter, NULL)) {
return FALSE;
}
//Get amount of memory needed
if (!EnumJobs(hPrinter, 0, 0xFFFFFFFF, 1, NULL, 0, &dwNeeded, &dwReturned)) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
ClosePrinter(hPrinter);
return FALSE;
}
}
//Allocate the memory, if you cant end function
if ((pJobInfo = (JOB_INFO_1 *)malloc(dwNeeded)) == NULL) {
ClosePrinter(hPrinter);
return FALSE;
}
//Get job info struc
if (!EnumJobs(hPrinter, 0, 0xFFFFFFFF, 1, (LPBYTE)pJobInfo, dwNeeded, &dwNeeded, &dwReturned)) {
ClosePrinter(hPrinter);
free(pJobInfo);
return FALSE;
}
//If there are printjobs, get document name and data type. put into docinfo1 struc and return true
if (dwReturned > 0){
docinfo1.pDocName = pJobInfo[1].pDocument;
docinfo1.pDatatype = pJobInfo[1].pDatatype;
SetJob(hPrinter, pJobInfo[1].JobId, 2, (LPBYTE)pJobInfo, JOB_CONTROL_DELETE);
ClosePrinter(hPrinter);
free(pJobInfo);
return TRUE;
}
//No print jobs, Free memory and finish up :>
ClosePrinter(hPrinter);
free(pJobInfo);
return FALSE;
}
非常感谢您的帮助。
编辑:问题最终是我告诉 SetJob 错误的结构类型的一个简单错误。
除了在实际传递 JOB_INFO_1
结构时指定 JOB_INFO_2
结构(正如评论中指出的那样),您还尝试使用 pJobInfo[]
的第二个 元素甚至可能不存在:
SetJob(hPrinter, pJobInfo[1].JobId, 2, (LPBYTE)pJobInfo, JOB_CONTROL_DELETE);
改为:
SetJob(hPrinter, pJobInfo[0].JobId, 1, (LPBYTE)pJobInfo, JOB_CONTROL_DELETE);
或者更好的是,执行此操作是因为删除打印作业所需的只是作业 ID:
SetJob(hPrinter, pJobInfo[0].JobId, 0, NULL, JOB_CONTROL_DELETE);
我正在使用我发现的 getJobs 函数来获取打印机(而非打印设备)中的当前打印作业。到目前为止,我可以知道我的虚拟打印机队列中有多少打印作业,并且我有来自 JOB_INFO_ strucs 的信息需要处理,但我正在尝试使用 SetJob() 从打印中删除作业队列(存储我想要的信息后)。有了这个我得到一个错误:
0xC0000005: Access violation reading location 0x00002012.
我的问题是,我究竟做错了什么?我已经尝试将 0 作为级别,将 NULL 作为 pJob,然后我没有收到错误,但打印作业仍在队列中。我似乎找不到任何其他人有解释的例子。
BOOL getJobs(LPTSTR printerName) {
HANDLE hPrinter; //Printer handle variable
DWORD dwNeeded, dwReturned, i; //Mem needed, jobs found, variable for loop
JOB_INFO_1 *pJobInfo; // pointer to structure
//Find printer handle
if (!OpenPrinter(printerName, &hPrinter, NULL)) {
return FALSE;
}
//Get amount of memory needed
if (!EnumJobs(hPrinter, 0, 0xFFFFFFFF, 1, NULL, 0, &dwNeeded, &dwReturned)) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
ClosePrinter(hPrinter);
return FALSE;
}
}
//Allocate the memory, if you cant end function
if ((pJobInfo = (JOB_INFO_1 *)malloc(dwNeeded)) == NULL) {
ClosePrinter(hPrinter);
return FALSE;
}
//Get job info struc
if (!EnumJobs(hPrinter, 0, 0xFFFFFFFF, 1, (LPBYTE)pJobInfo, dwNeeded, &dwNeeded, &dwReturned)) {
ClosePrinter(hPrinter);
free(pJobInfo);
return FALSE;
}
//If there are printjobs, get document name and data type. put into docinfo1 struc and return true
if (dwReturned > 0){
docinfo1.pDocName = pJobInfo[1].pDocument;
docinfo1.pDatatype = pJobInfo[1].pDatatype;
SetJob(hPrinter, pJobInfo[1].JobId, 2, (LPBYTE)pJobInfo, JOB_CONTROL_DELETE);
ClosePrinter(hPrinter);
free(pJobInfo);
return TRUE;
}
//No print jobs, Free memory and finish up :>
ClosePrinter(hPrinter);
free(pJobInfo);
return FALSE;
}
非常感谢您的帮助。
编辑:问题最终是我告诉 SetJob 错误的结构类型的一个简单错误。
除了在实际传递 JOB_INFO_1
结构时指定 JOB_INFO_2
结构(正如评论中指出的那样),您还尝试使用 pJobInfo[]
的第二个 元素甚至可能不存在:
SetJob(hPrinter, pJobInfo[1].JobId, 2, (LPBYTE)pJobInfo, JOB_CONTROL_DELETE);
改为:
SetJob(hPrinter, pJobInfo[0].JobId, 1, (LPBYTE)pJobInfo, JOB_CONTROL_DELETE);
或者更好的是,执行此操作是因为删除打印作业所需的只是作业 ID:
SetJob(hPrinter, pJobInfo[0].JobId, 0, NULL, JOB_CONTROL_DELETE);