Я пытаюсь установить виртуальный принтер из консольной программы C ++, используя вызовы WinAPI.Он отлично работает в Windows XP, но в Windows 7 x64 есть некоторые процессы, которые блокируют файлы в системных папках, необходимые для установки.Я думаю, что они появляются только в 64-разрядных системах Windows, но я не проверял это с Windows XP x64.
Это процессы 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;
}
Их больше, а некоторые очень длинные, поэтому я не буду публиковать их здесь, если они не нужны.
Есть ли способ предотвратить блокировку файлов системы и принудительную установку принтера?
PS Я прекращаю службу спулера при копировании файлов, а затем запускаю его перед любыми вызовами WinAPI.
PPS Это не мой код.Это устаревший код, который нам нужно сохранить для клиента.