我们要实现此功能,首先需要获取到打印机的名称,其次是将获取到的打印机名称依次删除。
一、获取打印机副本名称
1.我们获取打印机副本名称,可以使用windows API中的EnumPrinters函数,该函数可以枚举出我们电脑中的打印机设备信息,该函数使用方法如下:
DWORD Flags = PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL;
DWORD cbBuf;
DWORD pcReturned;
DWORD Level = 2;
TCHAR Name[4096] = { 0 };
HANDLE hPrinter = NULL;
PRINTER_DEFAULTS defaults = { NULL, NULL, PRINTER_ALL_ACCESS };
::EnumPrinters(Flags, Name, Level, NULL, 0, &cbBuf, //需要多少内存
&pcReturned);
const LPPRINTER_INFO_2 pPrinterEnum = (LPPRINTER_INFO_2)LocalAlloc(LPTR, cbBuf + 4);
if (!pPrinterEnum)
{
setSearchResult("false", "打印机信息获取内存失败,请重试");
return -1;
}
if (!EnumPrinters(Flags, Name, Level, (LPBYTE)pPrinterEnum, cbBuf, &cbBuf, &pcReturned))
{
setSearchResult("false", "打印机信息获取内存失败,请重试");
return -1;
}
2.我们获取到打印机信息以后,需要对获取到的打印机信息进行处理,然后就可进行删除功能实现
二、删除获取到的打印机副本
1.删除打印机功能,我们可以使用windows API中的DeletePrinter函数,但是使用DeletePrinter函数之前,我们需要使用OpenPrinter函数来打开打印机,OpenPrinter函数使用如下:
if (!OpenPrinter(pPrinterEnum[i].pPrinterName, &hPrinter, &defaults))
{
printf("Error opening printer : %d\n", GetLastError());
return -1;
}
2.DeletePrinter函数使用如下:
dataChangeToJson(printName, PrintSum);
if (!OpenPrinter(pPrinterEnum[i].pPrinterName, &hPrinter, &defaults))
{
printf("Error opening printer : %d\n", GetLastError());
return -1;
}
BOOL result = DeletePrinter(hPrinter);
ClosePrinter(hPrinter);
三、重启打印服务
我们删除打印机后,需要重启打印机服务后,打印机枚举函数才能枚举出更新的打印机设备,否则我们再次使用EnumPrinters函数时,效果与我们的预期不符。重启打印机服务如下:
标签:打印机,副本,return,Format,C++,CString,PrintSum,jsonData From: https://blog.csdn.net/qq_57661075/article/details/139201608完整代码如下:
CopyFunction.h文件
#include <atlstr.h>
#include <iostream>
#include <windows.h>
#include <tchar.h>
#include <string>
#include <io.h>
#include <fstream>
#include <filesystem>
#include<vector>
#include <Winspool.h>#include <stdio.h>
#include <locale.h>
#pragma comment(lib, "Winspool.lib")
#include <setupapi.h>
#pragma comment(lib, "setupapi.lib")using namespace std;
extern "C"{
__declspec(dllexport) int GetPrintName(CString *PrintName , int &PrintSum);
//__declspec(dllexport) BOOL DeletePrint(const wchar_t* printerName);
__declspec(dllexport) BOOL RestartSpoolerService();
__declspec(dllexport) int DeleteLocalPrinter(char *PrinterName);
}CopyFunction.c文件
#include "CopyFunction.h"
CString jsonData;
void setSearchResult(CString sFlag , CString sState);
bool dataChangeToJson(CString printerName , int PrintSum);
int DeleteLocalPrinter(char *PrinterName)
{
try
{
int res = 0;
int PrintSum = 0;
CString *PrintName = new CString[4096];
jsonData.Format(_T("{\n\t\"PrintName\":["));
res = GetPrintName(PrintName, PrintSum);
if (res == -1)
{
//jsonData.Format(jsonData + _T("\n\t]\,\n\t\"DeleteCount\":") + _T("%d\,"), PrintSum);
//jsonData.Format(jsonData + _T("\n\t\"message\":") + _T("\"删除USB打印副本失败,接口未成功执行\"\n}"));
jsonData.Format(jsonData + _T("\n\t\t\t\"删除USB打印副本失败,接口未成功执行\"\n\t]\n}"));
memcpy(&PrinterName[0], jsonData, jsonData.GetLength());
return -1;
}
if (PrintSum == 0)
{
setSearchResult("false", "打印机副本删除失败");
//jsonData.Format(jsonData + _T("\n\t]\,\n\t\"DeleteCount\":") + _T("%d\,"), PrintSum);
//jsonData.Format(jsonData + _T("\n\t\"message\":") + _T("\"接口未搜索到打印机副本\"\n}"),PrintSum);
jsonData.Format(jsonData + _T("\n\t\t\t\"接口未搜索到打印机副本\"\n\t]\n}"), PrintSum);
memcpy(&PrinterName[0], jsonData, jsonData.GetLength());
return -1;
}
int flag = jsonData.ReverseFind(','); //移除最后一个多余“,”
if (flag > 0)
{
jsonData = jsonData.Mid(0, flag);
}
setSearchResult("true", "打印机副本删除成功");
/*if (PrintSum>10)
jsonData.Format(jsonData + _T("\n\t..............."));*/
jsonData.Format(jsonData + _T("\n\t\t\t......"));
jsonData.Format(jsonData + _T("\n\t\t\t\"删除USB打印副本成功, 总共删除了%d个\"\n\t]\n}"),PrintSum);
/*jsonData.Format(jsonData + _T("\n\t\t\t\"DeleteCount\":") + _T("%d"),PrintSum);
jsonData.Format(jsonData + _T("\n\t\t\t\"message\":") + _T("\"删除USB打印副本成功, 总共删除了%d个\"\n\t]\n}"),
PrintSum);*/
memcpy(&PrinterName[0], jsonData, jsonData.GetLength());
if (!RestartSpoolerService())
{
printf("StartService failed with spooler.\n");
}
//cout << jsonData << endl;
}
catch (exception &e)
{
cout << "ERROR:" << e.what() << endl;
}
return 0;
}void setSearchResult(CString sFlag, CString sState)
{
CString jdata; //转存jsonData数据
CString searchFlag;
CString searchState;
jdata = jsonData.Mid(1);
searchFlag.Format(_T("\n\t\"searchFlag\":\"") + sFlag + _T("\","));
searchState.Format(_T("\n\t\"searchState\":\"") + sState + _T("\","));
jsonData.Format(_T("{") + searchFlag + searchState + jdata);
}bool dataChangeToJson(CString printerName, int PrintSum)
{
CString jdata;//用于存储打印机名称及twain名的键值对数据
if (PrintSum !=0)
{
jdata.Format(_T("\t\t\n\t\t\t\"%d、")+ printerName + _T("\","), PrintSum);
jsonData += jdata;
}
else
{
jdata.Format(_T("\t\t\n\t\t\t\"") + printerName + _T("\","), PrintSum);
}
return true;
}int GetPrintName(CString *PrintName,int &PrintSum)
{
try
{
CString strDescription;
CString printName;
CString PLocation;
CString NETName;
DWORD Flags = PRINTER_ENUM_FAVORITE | PRINTER_ENUM_LOCAL;
DWORD cbBuf;
DWORD pcReturned;
DWORD Level = 2;
TCHAR Name[4096] = { 0 };
HANDLE hPrinter = NULL;
PRINTER_DEFAULTS defaults = { NULL, NULL, PRINTER_ALL_ACCESS };
::EnumPrinters(Flags, Name, Level, NULL, 0, &cbBuf, //需要多少内存
&pcReturned);
const LPPRINTER_INFO_2 pPrinterEnum = (LPPRINTER_INFO_2)LocalAlloc(LPTR, cbBuf + 4);
if (!pPrinterEnum)
{
setSearchResult("false", "打印机信息获取内存失败,请重试");
return -1;
}
if (!EnumPrinters(Flags, Name, Level, (LPBYTE)pPrinterEnum, cbBuf, &cbBuf, &pcReturned))
{
setSearchResult("false", "打印机信息获取内存失败,请重试");
return -1;
}
for (unsigned int i = 0, j = 0; i < pcReturned; i++)
{
LPPRINTER_INFO_2 pInfo = &pPrinterEnum[i];
strDescription.Format(_T("pPrinterName: %s,pDriverName: %s ,pLocation: %s, Status: %ld"),
(LPCTSTR)pInfo->pPrinterName,
(LPCTSTR)pInfo->pDriverName, (LPCTSTR)pInfo->pLocation,
pInfo->Attributes);
printName.Format(_T("%s"), (LPCTSTR)pInfo->pPrinterName);
int PrintSign = printName.Find("(");
if (PrintSign != -1)
{
PrintName[j] = printName;
//dataChangeToJson(printName);
PrintSum++;
if (PrintSum <= 10)
dataChangeToJson(printName, PrintSum);
if (!OpenPrinter(pPrinterEnum[i].pPrinterName, &hPrinter, &defaults))
{
printf("Error opening printer : %d\n", GetLastError());
return -1;
}
BOOL result = DeletePrinter(hPrinter);
ClosePrinter(hPrinter);
j++;
//PrintSum++;
}
}
}
catch (exception &e)
{
cout << "ERROR:" << e.what() << endl;
}
return 0;
}/*函数功能:重启Spooler服务
函数参数:无
函数返回:打印服务重启与否*/
BOOL RestartSpoolerService()
{
try
{
// 打开服务控制管理器
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, GENERIC_EXECUTE);
if (hSCManager == NULL) {
cerr << "OpenSCManager failed with error: " << GetLastError() << endl;
return false;
}
// 打开Spooler服务
SC_HANDLE hService = OpenService(hSCManager, _T("Spooler"), SERVICE_START | SERVICE_QUERY_STATUS | SERVICE_STOP);
if (hService == NULL) {
cerr << "OpenService failed with error: " << GetLastError() << endl;
CloseServiceHandle(hSCManager);
return false;
}
//查询spooler服务的状态
SERVICE_STATUS status;
if (QueryServiceStatus(hService, &status) == FALSE)
{
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return false;
}
// 停止服务
if (ControlService(hService, SERVICE_CONTROL_STOP, &status) == FALSE)
{
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
cerr << "ControlService STOP failed with error: " << GetLastError() << endl;
}
else
{
// 等待服务停止
while (QueryServiceStatus(hService, &status) && status.dwCurrentState != SERVICE_STOPPED)
{
Sleep(1000); // 暂停1秒再检查
}
}// 启动服务
if (status.dwCurrentState == SERVICE_STOPPED)
{
if (StartService(hService, NULL, NULL) == FALSE)
{
CloseServiceHandle(hService); // 关闭服务句柄
CloseServiceHandle(hSCManager); // 关闭服务控制管理器句柄
cerr << "StartService failed with error: " << GetLastError() << endl;
}
}
CloseServiceHandle(hService); // 关闭服务句柄
CloseServiceHandle(hSCManager); // 关闭服务控制管理器句柄
}
catch (exception &e)
{
cout << "ERROR:" << e.what() << endl;
}
return true;
}