我的应用程序在用户卸载应用程序时删除虚拟打印机。 可以使用用户交互(向导)或在Windows Server 2003中设置组策略来完成应用程序的安装和卸载(域管理员在服务器中设置策略,客户端PC中的域用户需要更新组策略并重新启动客户端PC以进行安装或卸载应用程序)。 卸载应用程序时,应用程序中的以下代码将删除打印机和打印机驱动程序。
void CPrinterDriver::DeletePrinterIfExists()
{
// Delete old printer driver if existing
ControlSpoolService(TRUE);
HANDLE hPrinter = NULL;
PRINTER_DEFAULTS pDefaults = { NULL, NULL, PRINTER_ALL_ACCESS };
// Ignore error codes
OpenPrinter(m_driverInfo.pName, &hPrinter, &pDefaults);
if (hPrinter)
{
// deleting jobs
SetPrinter(hPrinter, 0, NULL, PRINTER_CONTROL_PURGE);
// Delete printer
DeletePrinter(hPrinter);
// Get printer driver name and delete it
DWORD dwNeeded = 0;
GetPrinter(hPrinter, 2, NULL, 0, &dwNeeded);
if (dwNeeded)
{
PRINTER_INFO_2 *pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, sizeof(PRINTER_INFO_2)*dwNeeded);
if (pi2)
{
GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
DeletePrinterDriver(NULL, NULL, pi2->pDriverName);
GlobalFree(pi2);
}
}
ClosePrinter(hPrinter);
}
}
在卸载的两种情况下(用户交互式安装和使用组策略),上述代码在Windows 7中运行良好。在Windows 8中,它可以很好地使用用户交互式安装和卸载。 但是在Windows 8中,上面的OpenPrinter()正在撤回ERROR_INVALID_PRINTER_NAME。
我们发现使用“SYSTEM”帐户调用OpenPrinter()。 请帮助。
答案 0 :(得分:0)
我们发现在系统启动期间,组策略尝试在PC中的可用打印机列表填充之前卸载打印机(列表填充在下面的注册表项下。如果列表未填充,则下面的键不存在)。
“HKEY_LOCAL_MACHINE \ SYSTEM \ CURRENTCONTROLSET \控制\打印\打印机”
因此我们在调用openPrinter()之前添加了2分钟的延迟(不少于2分钟)。 延迟后,注册表项存在,OpenPrinter()成功。 因此,我们可以卸载打印机。
注意:Microsoft声称某些支持的硬件的Windows 8启动时间减少到7秒。但插入2分钟的延迟会降低Windows 8 PC的启动性能。 有关Windwos 8 OS启动时间改进的更多详细信息,请参阅以下链接。 http://blogs.msdn.com/b/b8/archive/2012/05/22/designing-for-pcs-that-boot-faster-than-ever-before.aspx 因此,延迟2分钟可以作为解决方法。 需要在10/26之后检查Windows 8 OS版本中的行为。
答案 1 :(得分:0)
如果您遇到以下问题:
然后您可以尝试通过其完整的UNC路径打开打印机。
因此,当打开MYPRINTER
无效时,请将其打开为\\MYSERVER\MYPRINTER
。
当然,这仍然假设您已经可以正常从其他应用程序打印到此打印机!