我通过
pnputil /a my.inf
致电 CreateProcess()
,成功了。我放弃了使用 Windows API 的尝试。然后我尝试使用 AddPrinterDriver()
添加打印机,但始终失败:
if (RunWindowsPnpUtil(thePrinterInfo))
{
//std::vector<std::wstring> vecInstallPaths = GetInstalledDriverPaths();
//std::vector<std::wstring> vecInstanceIDs = GetDeviceInstanceIDsUsingDriver(thePrinterInfo);
wstring wsDriverName = thePrinterInfo.GetPrinterName(), wsInfPath = thePrinterInfo.GetINFPath();
wstring wsDir = wsInfPath.substr(0, wsInfPath.find_last_of(L'\\')), wsINFName = wsInfPath.substr(wsInfPath.find_last_of(L'\\') + 1);
DRIVER_INFO_4 driverInfo = { 0 };
memset(&driverInfo, 0, sizeof(DRIVER_INFO_3));
wstring wsConfigFile = thePrinterInfo.GetConfigFile(), wsDataFile = thePrinterInfo.GetDataFile();
driverInfo.cVersion = thePrinterInfo.GetPrinterClassVersionInt(); // Specify the version of the structure
driverInfo.pName = const_cast<wchar_t*>(wsDriverName.c_str()); // Driver name
driverInfo.pEnvironment = NULL; // Use the current environment
driverInfo.pDriverPath = const_cast<wchar_t*>(L"UNIDRV.DLL"); // The path to the driver files (optional)
driverInfo.pDataFile = const_cast<wchar_t*>(thePrinterInfo.GetGPDFile().c_str()); // NULL; // const_cast<wchar_t*>(wsInfPath.c_str()); // Path to the INF file
driverInfo.pConfigFile = const_cast<wchar_t*>(wsConfigFile.empty() ? L"UNIDRVUI.DLL" : wsConfigFile.c_str());; // The path to the configuration file (optional)
driverInfo.pHelpFile = const_cast<wchar_t*>(L"UNIDRV.HLP"); // The path to the help file (optional)
driverInfo.pDependentFiles = NULL; // Array of dependent files (optional)
driverInfo.pMonitorName = NULL; // Monitor name (optional)
driverInfo.pDefaultDataType = NULL; // Default data type (optional)
// Add the printer driver
//DWORD level = driverInfo.cVersion;
if (AddPrinterDriver(NULL, driverInfo.cVersion, reinterpret_cast<BYTE*>(&driverInfo)) == 0) {
// Failed to add printer driver
DWORD dwErr = GetLastError();
return false;
}
就上下文而言,这是一个 XPS 迷你驱动程序 (
filter.dll
)。
如果您需要更多信息,我很乐意提供。我很绝望,Google、Reddit 和 ChatGPT 都没有帮助。
您在评论中说:
AddPrinterDriver 返回 FAILURE 且 dwErr == 2 或 dwErr == 87,具体取决于 driverInfo.pDataFile 是 NULL 还是指向有效文件名。
我看到的一个问题是这一行:
driverInfo.pDataFile = const_cast<wchar_t*>(thePrinterInfo.GetGPDFile().c_str());
如果
GetGPDFile()
按值而不是按引用返回 wstring
,这将产生一个 悬挂指针 导致 未定义的行为。您应该首先将 GetGPDFile()
的结果保存到局部变量中,就像处理其他字符串一样,例如:
wstring wsGPDFile = thePrinterInfo.GetGPDFile();
driverInfo.pDataFile = const_cast<wchar_t*>(wsGPDFile.c_str());
顺便说一句,如果您正在为 C++17 或更高版本编译
wstring
作为非常量 data()
方法,您可以使用它来代替 const_cast
,例如:
driverInfo.pDataFile = wsGPDFile.data();