【问题标题】:C++: Deleting a printer queueC++:删除打印机队列
【发布时间】:2014-05-14 13:23:30
【问题描述】:

我正在尝试从打印机中删除队列中的所有文件。我找到了this piece of code,这看起来很简单。

我尝试使用以下代码删除队列。它可以编译,但 SetPrinter 返回 false。我收到的错误消息是 5,我尝试使用 from this question 方法将其解码为“正常”错误消息。但我无法编译,因为 STR_ELEMS 未定义。在 Google 上搜索“STR_ELEMS 未定义”,但遇到了死胡同。

有人可以帮我解码错误消息并删除打印机队列吗?

BOOL bStatus = false;
HANDLE     hPrinter = NULL;
DOC_INFO_1 DocInfo;

bStatus = OpenPrinter((LPTSTR)_T("CN551A"), &hPrinter, NULL);

if(bStatus) {

    DWORD dwBufsize=0;

    GetPrinterA(hPrinter, 2, NULL, 0, &dwBufsize); // Edit: Returns false

    PRINTER_INFO_2* pinfo = (PRINTER_INFO_2*)malloc(dwBufsize);
    long result = GetPrinterA(hPrinter, 2, 
        (LPBYTE)pinfo, dwBufsize, &dwBufsize);

    if ( pinfo->cJobs==0 ) // Edit: pinfo->cJobs is not 0
    {
        printf("No printer jobs found.");
    }
    else
    {
        if ( SetPrinter(hPrinter, 0, 0, PRINTER_CONTROL_PURGE)==0 )
            printf("SetPrinter call failed: %x\n", GetLastError() );
        else printf("Number of printer jobs deleted: %u\n",
            pinfo->cJobs);
    }

    ClosePrinter( hPrinter );

}

我的包括:

#include <windows.h>
#include <winspool.h>

【问题讨论】:

  • GetPrinter 返回什么?应该是BOOL0表示失败。
  • 实际返回false。没查那个。那么我是否以某种方式定义了错误的 hPrinter 句柄?
  • dwBufsize 的值是多少?顺便说一句,没有理由 malloc PRINTER_INFO_2 结构。只需将其声明为非指针并将其地址传递给GetPrinter,如(LPBYTE)&amp;pinfo
  • 如果我将其更改为 PRINTER_INFO2 pinfo,然后按照您的建议检索地址 &pinfo,那么我认为没有足够的可用内存(我收到异常错误)。如果我计算 dwBufSize 我得到 3080,我猜这是 pinfo 的字节数?
  • PRINTER_INFO_2 是对的。但是有两个电话给GetPrinter。两次调用后打印出返回值和dwBufsize的值。

标签: c++ winapi printing error-handling


【解决方案1】:

错误代码 5 表示“访问被拒绝”。 (System Error Codes)

尝试以管理员权限运行。

要根据GetLastError 的返回值格式化可打印的错误消息,请使用FormatMessage 类似这样的内容:

  TCHAR buffer[256];
  if (0 == FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0,
           GetLastError(), 0, buffer, 256, 0)) {
    // FormatMessage failed.
  }

另外,您可以尝试将PRINTER_DEFAULTS 结构体传递给OpenPrinter,可能是这样的:

PRINTER_DEFAULTS PrnDefs;
PrnDefs.pDataType = "RAW";
PrnDefs.pDevMode = 0;
PrnDefs.DesiredAccess = PRINTER_ALL_ACCESS;

bStatus = OpenPrinter((LPTSTR)_T("CN551A"), &hPrinter, &PrnDefs);

【讨论】:

  • 谢谢。我以管理员模式打开项目。不幸的是,SetPrinter 仍然返回 false。如果我输出缓冲区的值 (cout
  • 打印buffer(整个字符串),而不是*buffer(第一个字符)。
  • 我一开始试过了,结果输出:00E2FA48(内存地址?)
  • 知道了! std::wcout
  • 我猜你打开它时没有访问权限,或者至少不足以清除队列。所以你必须将最后一个参数设置为你想要的访问类型。
猜你喜欢
  • 1970-01-01
  • 2012-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多