📄 prinstaller.cpp
字号:
// tstr = TEXT("Install //} ::SetWorkInProgress(TEXT("Removing files"), m_pdw, &iss); //tstr += TEXT("Removing files.") //m_pdw->SetStatusString( ); ::DoAllUnInstall(m_pdw, &iss); m_pdw->SetStatusAllDone(); iss.SetAllDone(); m_pdw->SetStatusString(iss.GetStatusString()); m_bFailed = TRUE; //::NotificationMessage(::PrintResizerComponents::eInstaller, } else { m_pdw->SetStatusAllDone(); iss.SetAllDone(); m_pdw->SetStatusString(iss.GetStatusString()); ::Sleep(SLEEP_TO_LET_FOLDER_WINDOWS_OPEN_MS); } m_pdw->CenterWindowAboveParent(); //m_pdw->SetWindowZOrderToTop(); //m_pdw->SetActiveWindow(); m_pdw->SetForegroundWindow(); ::CoUninitialize();}// *************************************************************************************************// ** MODULDE PRIVATE class MyTimer ***************************************************************// *************************************************************************************************MyTimer::MyTimer(DWORD dwElapseMS, ::ProgressDialogWindow *pdw, ::InstallStatusString *piss) { m_dwElapseMS = dwElapseMS; m_dwStartMS = ::GetTickCount(); m_pdw = pdw; m_piss = piss;}void MyTimer::Wait(void) { if (m_pdw != NULL) { while( ! ::CheckUserCanceled(m_pdw, m_piss) && GetTickCount() - m_dwStartMS < m_dwElapseMS ) { DWORD dwMS0 = ::GetTickCount(); // IN ORDER FOR MODAL DIALOG TO TERMINATE, IT MAY HAVE TO ENABLE WINDOWS IN THE CURRENT THREAD // W/O THIS LOOP DEADLOCK RESULTS MSG msg; while (PeekMessage(&msg, (HWND) NULL, 0, 0, PM_REMOVE) && GetTickCount() - m_dwStartMS < m_dwElapseMS) { if ( ! ::DialogWindow::TheirIsDialogMessage(msg) ) { TranslateMessage(&msg); DispatchMessage(&msg); } } DWORD dwMS1 = ::GetTickCount() - dwMS0; if (dwMS1 < WAIT_TIMESLICE_MS) { ::Sleep(WAIT_TIMESLICE_MS - dwMS1); } } }}//private:// DWORD m_dwElapseMS;// DWORD m_dwStartMS;//};// *************************************************************************************************// ** MOCULDE PRIVATE ROUTINES *******************************************************************// *************************************************************************************************BOOL DoAllInstall(HINSTANCE hinst, LPCTSTR lptstrPrinterName, ::ProgressDialogWindow *pdw, ::InstallStatusString *piss) { BOOL bError = FALSE; ::SetWorkInProgress(TEXT("Beginning install"), pdw, piss); if ( ::DoInstallDriver(hinst, pdw, piss)) { if ( ::DoInstallPrintProcessor(pdw, piss)) { PRDRIVER_FILENAME_ALTERNATES altPortNames; ::GeneratePRDriverAlternateNames(altPortNames, PRINTRESIZER_PORTNAME); uint kAltPortName; if (DoInstallOrFindPort(kAltPortName, altPortNames, pdw, piss)) { if ( ! ::DoInstallPrinter(lptstrPrinterName, altPortNames[kAltPortName], pdw, piss) ) { // FAILED ON ADDING THE PRINTER bError = TRUE; } } else { // FAILED FINDING OR INSTALLING A PORT bError = TRUE; } } else { // FAILED INSTALLING THE PRINTPROCESSOR bError = TRUE; } } else { // FAILED INSTALLING THE DRIVER bError = TRUE; } if (!bError) { if ( !CheckUserCanceled(pdw, piss) && !piss->GetTerminalError()) { PDEVMODE pdm = ::GetPrinterDevMode(lptstrPrinterName); if (pdm != NULL) { if (::EXTDM_IsAnExtDevMode(pdm)) { if (pdm->dmDriverVersion != PRINTRESIZER_VERSION) { // OLD VERSION STILL NOT THERE, UPGRADE FAILED bError = TRUE; ::SetErrorItem(TEXT("Driver upgrade failed.\nTry again after restarting Windows."), pdw, piss, FALSE); } } else { // PRINTER FOR SOME REASON ISN'T OURS bError = TRUE; ::SetErrorItem(TEXT("Printer install unexpectedly failed."), pdw, piss); } free(pdm); } else { // CANT GET A DEVMODE bError = TRUE; ::SetErrorItem(TEXT("Printer install unexpectedly failed."), pdw, piss); } } if ( !CheckUserCanceled(pdw, piss) && !piss->GetTerminalError()) { ::DoInstallAdditionalProgramFiles(hinst, pdw, piss); } if ( !CheckUserCanceled(pdw, piss) && !piss->GetTerminalError()) { ::DoInstallLinks(lptstrPrinterName, pdw, piss); } if ( !CheckUserCanceled(pdw, piss) && !piss->GetTerminalError()) { ::DoOpenPrinterFolder(); } if ( !CheckUserCanceled(pdw, piss) && !piss->GetTerminalError()) { ::DoLinksFolderCommand(TEXT("open")); } } return !bError;}// ASSUMES DRIVER, PRINTPROCESSOR, AND PORT ARE ALREADY INSTALLED// IT SELECTS THE PRINTPROCESSOR FOR THE PRINTER AND SET THE DATATYPE//// HOWEVER WE MAY WANT TO SET THE PRINTPROCESSOR AND DATATYPE IN THE UI-DLL ON THE INITIALIZE PRINTER EVENT// WHICH IS EXECUTEED WHEN THE PRINTER IS ADDED, BECAUSE THIS MIGHT ALLOW// THE PRINTER TO CONNECTED TO ACROSS A NETWORK (IM NOT SURE)BOOL DoInstallPrinter(IN LPCTSTR lptstrPrinterName, IN LPCTSTR lptstrPortName, ::ProgressDialogWindow *pdw, ::InstallStatusString *piss) { BOOL bError = FALSE; MyTimer mt(INSTALLUINT_MINTIME_MS, pdw, piss); { tstring tstrWorkItem = TEXT("Installing printer "); tstrWorkItem += lptstrPrinterName; ::SetWorkInProgress(tstrWorkItem.c_str(), pdw, piss); } HANDLE hPrinter; if (::OpenPrinter( const_cast<LPTSTR>(lptstrPrinterName), &hPrinter, NULL) || ::CheckUserCanceled(pdw, piss)) { // THIS PRINTER NAME IS ALREADY IN USE bError = TRUE; if (hPrinter != NULL) { ClosePrinter(hPrinter); } tstring tstrTemp = TEXT("Printer "); tstrTemp += lptstrPrinterName; tstrTemp += TEXT(" already exists, and \ncould not be deleted in order to reinstall it."); ::SetErrorItem(tstrTemp.c_str(), pdw, piss); } else if (! ::CheckUserCanceled(pdw, piss)) { ::PRINTER_INFO_2 pi; ::ZeroMemory(&pi, sizeof(pi)); pi.pDatatype = PRINTRESIZER_DEFAULT_DATATYPE; // DEBUG-FIX WE SHOULD USED MOST ADVANCED FOR GIVEN OS THAT OUR PRINTPROCESSOR ACCEPTS (RECODE) pi.pDriverName = PRINTRESIZER_DRIVERNAME; pi.pPortName = const_cast<LPTSTR>(lptstrPortName); pi.pPrinterName = const_cast<LPTSTR>(lptstrPrinterName); pi.pPrintProcessor = PRINTRESIZER_PRINTPROCESSOR_NAME; //7/9 DEBUG/FIX //pi.Attributes = PRINTER_ATTRIBUTE_QUEUED | PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST | // PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS | PRINTER_ATTRIBUTE_LOCAL; pi.Attributes = PRINTER_ATTRIBUTE_QUEUED | PRINTER_ATTRIBUTE_LOCAL; if (::CheckUserCanceled(pdw, piss) || ! ::AddPrinter(NULL, 2, (LPBYTE) &pi)) { // ERROR ADDING PRINTER - PRESUMABLY BECAUSE THERE IS AN ERROR IN THE DRIVER // OR BECAUSE SOMETHING ISN'T INSTALLED OR IS IN USE // (PORT, PRINTPROCESSOR, DRIVER) bError = TRUE; tstring tstrTemp = TEXT("Printer "); tstrTemp += lptstrPrinterName; tstrTemp += TEXT(" could not be installed."); ::SetErrorItem(tstrTemp.c_str(), pdw, piss); } } else { bError = TRUE; } mt.Wait(); return !bError;}// WE MAY WANT TO PERFORM THIS IN THE UI-DLL "DRIVER EVENT" CALLBACK ON DRIVER INITIALIZE// ASSUMES THE DRIVER IS ALREADY INSTALLED, AND GETS THE PRINTPROCESSOR DLL FROM THAT// DIRECTORY// ASSUMES THAT THE PRINTPROCESSOR IS NOT CURRENTLY INSTALLED (I THINK THE CALL TO "ADD" WILL FAIL OTHERWISE)BOOL DoInstallPrintProcessor(::ProgressDialogWindow *pdw, ::InstallStatusString *piss) { BOOL bError = FALSE; MyTimer mt(INSTALLUINT_MINTIME_MS, pdw, piss); ::SetWorkInProgress(TEXT("Installing print processor"), pdw, piss); ::PDRIVER_INFO_3 pinfoDrivers = NULL; uint kDriver; if ( ! ::CheckUserCanceled(pdw, piss) && ::CheckPrinterDriverInstalled(pinfoDrivers, kDriver, PRINTRESIZER_DRIVERNAME)) { if ( ! ::CheckUserCanceled(pdw, piss) && pinfoDrivers != NULL) { ::PDRIVER_INFO_3 pid = & pinfoDrivers[kDriver]; LPTSTR lptstrPrintProcessorDirectory = ::MyGetPrintProcessorDirectory(); if (lptstrPrintProcessorDirectory != NULL && ! ::CheckUserCanceled(pdw, piss)) { // DEPENDENT FILES HAS THE PRINTPROCESSOR FILE FIRST (THEN PREVIEW APP) LPTSTR lptstrSourceFileName = pid->pDependentFiles; LPTSTR lptstrDestFileName = ::MakeFullFileName(lptstrPrintProcessorDirectory, PRINTRESIZER_PRINTPROCESSOR_FILENAME); if (lptstrDestFileName != NULL) { if (::CopyFile(lptstrSourceFileName, lptstrDestFileName, FALSE)) { if (::CheckUserCanceled(pdw, piss) || ! ::AddPrintProcessor(NULL, NULL, PRINTRESIZER_PRINTPROCESSOR_FILENAME, PRINTRESIZER_PRINTPROCESSOR_NAME)) { // ERROR ON SPOOLER REQUEST TO ADD THE PRINTPROCESSOR bError = TRUE; ::SetErrorCode(TEXT("Error installing print processor: "), pdw, piss); } } else { // UNABLE TO WRITE PRINTPROCESSOR DLL FILE bError = TRUE; ::SetErrorItem(TEXT("Error installing print processor:\nUnable to write driver."), pdw, piss); } free(lptstrDestFileName); } else { // OUT OF MEMORY ERROR bError = TRUE; ::SetErrorCode( TEXT("Error installing print processor: "), pdw, piss ); } free(lptstrPrintProcessorDirectory); } else { // ERROR GETTING BUFFER WITH PRINT PROCESSOR DIRECTORY NAME bError = TRUE; ::SetErrorCode(TEXT("Error installing print processor: "), pdw, piss); } free(pinfoDrivers); } else { // DRIVER WAS NOT INSTALLED, OR COULD NOT ENUMERATE bError = TRUE; ::SetErrorItem(TEXT("Error installing print processor:\nPrinter driver is not installed."), pdw, piss); } } else { // UNABLE TO CHECK IF DRIVER IS INSTALLED bError = TRUE; ::SetErrorCode(TEXT("Error installing print processor: "), pdw, piss); } mt.Wait(); return !bError;}BOOL DoInstallDriver(HINSTANCE hinst, ::ProgressDialogWindow *pdw, ::InstallStatusString *piss) { ::SYSTEMTIME systimeStamp = PRINTRESIZER_INSTALLED_TIMESTAMP; BOOL bError = FALSE; // DEBUG / FIX ::SYSTEMTIME stTemp; ::GetSystemTime(&stTemp); MyTimer mt(INSTALLUINT_MINTIME_MS, pdw, piss); ::SetWorkInProgress(TEXT("Installing printer driver"), pdw, piss); ::PDRIVER_INFO_3 pinfoDriversTemp = NULL; uint kTemp; if (! ::CheckUserCanceled(pdw, piss) && ::CheckPrinterDriverInstalled(pinfoDriversTemp, kTemp, PRINTRESIZER_DRIVERNAME)) { if (pinfoDriversTemp == NULL && ! ::CheckUserCanceled(pdw, piss)) { // OUR DRIVER ISN'T CURRENLTY INSTALLED, WE CAN PROCEED LPTSTR lptstrPrinterDriverDirectory = ::MyGetPrinterDriverDirectory(); if (lptstrPrinterDriverDirectory != NULL) { static const WORD awID[] = { IDF_PRINTRESIZER_GRAPHICSDLL, IDF_PRINTRESIZER_UIDLL, IDF_PRINTRESIZER_DATAFILE, //IDF_PRINTRESIZER_HELPFILE, IDF_PRINTRESIZER_PRINTPROCESSOR, IDF_PRINTRESIZER_PREVIEWAPP }; static const LPCTSTR alptstrFileNames[] = { PRINTRESIZER_GRAPHICSDLL_FILENAME, PRINTRESIZER_UIDLL_FILENAME, PRINTRESIZER_DATAFILE_NAME, //PRINTRESIZER_HELPFILE_NAME, PRINTRESIZER_PRINTPROCESSOR_FILENAME, PRINTRESIZER_PREIVEAPP_FILENAME }; LPTSTR alptstrBuff[ARRCOUNT(alptstrFileNames)+1]; ::ZeroMemory( &alptstrBuff, sizeof(alptstrBuff)); BOOL bBuffErr = FALSE; uint k; for(k = 0; k < ARRCOUNT(alptstrBuff); ++k) { if (k != ARRCOUNT(alptstrBuff) - 1) { alptstrBuff[k] = ::MakeFullFileName(lptstrPrinterDriverDirectory, alptstrFileNames[k]); } else { //alptstrBuff[k] = ::MakePrinterDriverDependentFiles(alptstrBuff[k-2], alptstrBuff[k-1]); alptstrBuff[k] = ::MakePrinterDriverDependentFiles(); } if (alptstrBuff[k] == NULL) { bBuffErr = TRUE; break; } } if (!bBuffErr && ! ::CheckUserCanceled(pdw, piss)) { BOOL bWriteError = FALSE; for(k = 0; k < ARRCOUNT(alptstrBuff) - 1 && ! ::CheckUserCanceled(pdw, piss); ++k) { if (! ::MyWriteResourceToFile(hinst, alptstrBuff[k], awID[k], RC_BINARYTYPE, &systimeStamp)) { bWriteError = TRUE; break; } } if (!bWriteError && ! ::CheckUserCanceled(pdw, piss)) { ::DRIVER_INFO_3 di; ::ZeroMemory(&di, sizeof(di)); k = 0; di.pDriverPath = alptstrBuff[k ++ ]; di.pConfigFile = alptstrBuff[k ++ ]; di.pDataFile = alptstrBuff[k ++ ]; //di.pHelpFile = alptstrBuff[k ++ ]; k = ARRCOUNT(alptstrBuff) - 1; di.pDependentFiles = alptstrBuff[k]; di.pName = PRINTRESIZER_DRIVERNAME; // DOUBLE CHECKED - IT FAILS ON MY SYSTEM IF IT'S "EMF" OR "EMF 1.008", WORKS IF "RAW" DEBUG / FIX di.pDefaultDataType = PRINTRESIZER_DEFAULT_DRIVER_DATATYPE; di.cVersion = PRINTRESIZER_ADDPRINTERDRIVER_VERSION; // NOTE FIELDS "pEnvironment" AND "pMonitorName" ARE LEFT NULL if (::CheckUserCanceled(pdw, piss) || ! ::AddPrinterDriver(NULL, 3, (LPBYTE) &di)) { // ERROR ADDING THE DRIVER // THIS WOULD MOST LIKELY BE BECAUSE // 1. WRONG DRIVER FOR THIS OS // 2. WE'VE CHECKED THIS DRIVER NAME DOESN'T EXIST, SO THAT CAN'T BE THE CONFLICT // 3. IT'S UNABLE TO OVERWRITE THE DLL'S IN THE OS-SPECIFIC DIRECTORY // THEY ARE ACTUALLY INSTALLED TO <-- * MOST LIKELY REASON // #3 IS FIXED BY HAVING USER RESTART WINDOWS, AND THEN IMMEDIATELY, BEFORE // RUNNING ANY OTHER PROGRAMS, UNINSTALL AND THEN TRY INSTALLING AGAIN // A MORE ROBUST METHOD WOULD BE TO ITERATE PROCESSES THAT USE // THE DLL'S THAT NEED TO BE OVERWRITTEN AND QUERY THE USER TO TERMINATE THEM bError = TRUE; ::SetErrorCode(TEXT("Error installing driver: "), pdw, piss); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -