我正在嘗試使用WinAPI調用從C++控制檯程序安裝虛擬打印機。它在Windows XP上運行良好,但在Windows 7 x64上有一些進程會鎖定系統文件夾中的文件,這些文件是安裝所必需的。我認爲它們只出現在x64的Windows系統上,但我沒有用Windows XP x64進行測試。如何在Win x64上使用WinAPI正確安裝虛擬打印機?
這些是進程splwow64.exe和PrintIsolationHost.exe。我試圖通過程序化方式殺死它們,結果很好(當然,因爲終止了PrintIsolationHost.exe,我設置了調試權限,因爲它是系統進程),但是我開始認爲如果代碼不正確,可能會出現問題不以這種方式工作。顯然,必須有一些安裝方式,而無需終止任何系統進程。
的代碼是類似的東西:
BOOL res = FALSE;
printf("Run install:\n\n");
// Set debug privilages to current process
HANDLE hTokenThis(NULL);
OpenProcessToken(GetCurrentProcess(), TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hTokenThis);
SetPrivilege(hTokenThis, SE_DEBUG_NAME, TRUE);
printf("Stop spooler service...\r\n");
if(!StopService("spooler"))
return FALSE;
// Stop splwow64.exe and PrintIsolationHost.exe - it can prevent some files to be copied
HANDLE process = GetProcessByName("splwow64.exe");
if (process)
TerminateProcess(process, 0);
// Stop PrintIsolationHost.exe (it runs under SYSTEM and requires debug rights to be stopped)
process = GetProcessByName("PrintIsolationHost.exe");
if (process)
TerminateProcess(process, 0);
// Continue install
printf("Copy driver file...\r\n");
if(!CopyInstFile())
{
return FALSE;
}
printf("Start spooler service...\r\n");
if(!StartServices("spooler"))
return FALSE;
printf("Add Port...\r\n");
res = AddPort();
ERROR_CHECK_EXIT(res)
printf("Add Driver...\r\n");
res = AddDriver();
ERROR_CHECK_EXIT(res)
printf("Add print Processor...\r\n");
res = AddProcessor();
ERROR_CHECK_EXIT(res)
printf("Add printer...\r\n");
res = AddPrint();
ERROR_CHECK_EXIT(res)
其中安裝各種東西的功能:
BOOL CPrintInstal::AddDriver()
{
DRIVER_INFO_3 driverInfo;
memset(&driverInfo,0,sizeof(driverInfo));
driverInfo.cVersion = 3;
driverInfo.pName = PRINTERDRIVERNAME;
driverInfo.pEnvironment = NULL;//"Windows NT x86";
driverInfo.pDriverPath="UNIDRV.DLL";
driverInfo.pDataFile=PDFCONVERTED_GPD;
driverInfo.pConfigFile= "UNIDRVUI.DLL";
driverInfo.pHelpFile= "UNIDRV.HLP";
driverInfo.pDependentFiles = NULL;
driverInfo.pDefaultDataType=NULL;
return AddPrinterDriver(NULL,3,(LPBYTE)&driverInfo);
}
BOOL CPrintInstal::AddPrint()
{
PRINTER_INFO_2 printInfo;
memset(&printInfo,0,sizeof(PRINTER_INFO_2));
printInfo.pServerName=NULL;
printInfo.pPrinterName=PRINTERNAME;
printInfo.pShareName=NULL;
printInfo.pPortName=PORTNAME_A;
printInfo.pPrintProcessor =PRINTPROCESSORNAME;
printInfo.pDatatype = "NT EMF 1.008";
printInfo.pDriverName =PRINTERDRIVERNAME;
printInfo.Attributes = PRINTER_ATTRIBUTE_LOCAL | PRINTER_ATTRIBUTE_QUEUED | PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS;
SetLastError(0);
HANDLE handle = AddPrinter(NULL,2,(LPBYTE)&printInfo);
if(handle == NULL)
{
if(GetLastError()!=1802)
return FALSE;
}
ClosePrinter(handle);
return TRUE;
}
有更多的人,有些是很長,所以我不會發布它這裏如果不需要。
有沒有什麼辦法來防止系統鎖定文件和強制打印機安裝?
P.S.我在複製文件時停止假脫機程序服務,然後在對WinAPI進行任何調用之前運行它。
P.P這不是我的代碼。這是我們需要爲客戶維護的遺留代碼。
你有沒有想出一個解決方案,你願意分享嗎? – agarcian
@agarcian很久以前,我不記得我使用了什麼確切的解決方案,但我認爲它是在下面的單一答案中描述的解決方案 - 使用註冊表分支並在重新啓動後運行安裝程序或使用MoveFileEx。 –
此代碼是否安裝虛擬打印機驅動程序或是否模擬虛擬打印機(例如,當我們打印虛擬驅動程序時應使用可用打印機列出) –