window下修改打印机驱动的端口为本地文件

有时候需要修改打印机驱动的端口为本地文件,以方便对打印数据进行修改。
注:代码来源于互联网
1、枚举本地端口,查找是否有需要的本地文件端口(file_path)

	LPBYTE p_port_info = 0;         // 接收端口信息结构体数组指针
	DWORD  pcbNeeded = 0;           // 缓冲区字节指针(必需)
	DWORD  pcReturned = 0;          // 返回结果PORT_INFO_* 结构体缓冲区数量

	if (EnumPortsA(NULL, 2, p_port_info, 0, &pcbNeeded, &pcReturned) && pcbNeeded != 0)
	{
		p_port = new BYTE[pcbNeeded];
		if (!EnumPortsA(nullptr, 2, p_port_info, pcbNeeded, &pcbNeeded, &pcReturned))
		{
			PORT_INFO_2A*  p_port_info_2 = (PORT_INFO_2A*)p_port_info;
			for (DWORD i = 0; i < pcReturned; i++)
			{
				if (_stricmp(p_port_info_2[i].pPortName, file_path.c_str()) == 0)
				{
					b_found = true;
					break;
				}
			}
		}
		delete[] p_port;
	}

2、如果未找到本地文件(file_path)端口,则增加

	HANDLE hXcv = nullptr;
	PRINTER_DEFAULTSA pPrintDef;
	memset(&pPrintDef, 0, sizeof(pPrintDef));
	pPrintDef.DesiredAccess = SERVER_ACCESS_ADMINISTER;

	WCHAR pszPortName[512] = {0};
	WCHAR dwReturn[512];
	DWORD cbNeeded;
	DWORD dwStatus;

	OpenPrinterA(",XcvMonitor Local Port", &hXcv, &pPrintDef);
	if (hXcv == nullptr)
	{
		sprintf_s(error_info_, "Open XcvMonitor Local Port Error:%d", GetLastError());
		return false;
	}
	wcscpy_s(pszPortName, CStrA2CStrW(file_path.c_str()).GetBuffer());
	if (!XcvData(hXcv, L"AddPort", (PBYTE)pszPortName, (int)(wcslen(pszPortName) + 1) * sizeof(WCHAR),
		(PBYTE)dwReturn, 0, &cbNeeded, &dwStatus) || dwStatus != 0)		//注意这里使用宽字节
	{
		sprintf_s(error_info_, "Add Local Port Error:%d", GetLastError());
		ClosePrinter(hXcv);
		return false;
	}
	ClosePrinter(hXcv);

3、设置打印机的端口。

	HANDLE hPrinter = nullptr;
	PRINTER_DEFAULTSA pd = { 0 };
	PRINTER_INFO_2A *p_info2 = nullptr;
	DWORD  pcbNeeded = 0;    // 缓冲区字节指针(必需)

	pd.DesiredAccess = PRINTER_ALL_ACCESS;

	BOOL bFlag = OpenPrinterA(const_cast<char*>(printer_name.c_str()), &hPrinter, &pd);

	if (!bFlag || (hPrinter == nullptr))
	{
		sprintf_s(error_info_, "Open Printer Error:%d", GetLastError());
		return false;
	}
	bFlag = GetPrinterA(hPrinter, 2, 0, 0, &pcbNeeded);

	if ((!bFlag) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
		(pcbNeeded == 0))
	{
		sprintf_s(error_info_, "Get Printer Info Error:%d", GetLastError());
		ClosePrinter(hPrinter);
		return false;
	}

	// Allocate enough space for PRINTER_INFO_2...
	p_info2 = (PRINTER_INFO_2A *)GlobalAlloc(GPTR, pcbNeeded);
	if (p_info2 == nullptr)
	{
		sprintf_s(error_info_, "GlobalAlloc Error:%d", GetLastError());
		ClosePrinter(hPrinter);
		return false;
	}

	// The second GetPrinter fills in all the current settings, so all you
	// need to do is modify what you're interested in...
	bFlag = GetPrinterA(hPrinter, 2, (LPBYTE)p_info2, pcbNeeded, &pcbNeeded);
	if (!bFlag)
	{
		GlobalFree(p_info2);
		sprintf_s(error_info_, "Get Printer Info Error:%d", GetLastError());
		ClosePrinter(hPrinter);
		return false;
	}
	if (_stricmp(p_info2->pPortName, file_path.c_str()) == 0)		//如果已经是本地文件端口,则退出
	{
		GlobalFree(p_info2);
		ClosePrinter(hPrinter);
		return true;
	}
	p_info2->pPortName = const_cast<char*>(file_path.c_str());

	bFlag = SetPrinterA(hPrinter, 2, (LPBYTE)p_info2, 0);
	if (!bFlag)
		// The driver doesn't support, or it is unable to make the change...
	{
		GlobalFree(p_info2);
		sprintf_s(error_info_, "Set Printer Info Error:%d", GetLastError());
		ClosePrinter(hPrinter);
		return false;
	}
	GlobalFree(p_info2);
	ClosePrinter(hPrinter);
	return true;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值