Changing Windows default printer
Sometimes it's necessary to change Windows default printer from within VFP application. It can be done with Windows API, WSH or WMI
.
WIN API SetDefaultPrinter function is available in Windows 2000 and later. WSH SetDefaultPrinter method is supported under Win98 and later but WSH has to be present on PC. WMI SetDefaultPrinterclass method is available in Windows XP and later.
The WinApiErrMsg function in the code below is from Retrieving Windows system error message.
$SAMPLECODE$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 * New default printer lcPrinterName = "Microsoft XPS Document Writer" * Save current Windows default printer in case we would want to restore it later lcSaveWinDefPrinter = SET("PRINTER", 2) *------------------------------------------ * Windows API DECLARE Long GetLastError IN WIN32API DECLARE Long SetDefaultPrinter In WINSPOOL.DRV String pPrinterName IF SetDefaultPrinter(lcPrinterName) = 0 * Error ? WinApiErrMsg(GetLastError()) ELSE ? "New default printer: " + SET("PRINTER", 2) * ... * Restore default printer SetDefaultPrinter(lcSaveWinDefPrinter) ? "Restored default printer: " + SET("PRINTER", 2) ENDIF *------------------------------------------ * WSH loNet = CREATEOBJECT("WScript.Network") TRY loNet.SetDefaultPrinter(lcPrinterName + "") ? "New default printer: " + SET("PRINTER", 2) *... loNet.SetDefaultPrinter(lcSaveWinDefPrinter) ? "Restored default printer: " + SET("PRINTER", 2) CATCH TO oExp WHEN oExp.ErrorNo = 1429 * Error ? oExp.ErrorNo, oExp.Message ENDTRY *------------------------------------------ * WMI loLocator = CREATEOBJECT('WBEMScripting.SWBEMLocator') * Local computer, logged on user loWMI = loLocator.ConnectServer() loWMI.Security_.ImpersonationLevel = 3 && Impersonate * Retrieve info about new printer loPrinters = loWMI.ExecQuery([Select * from Win32_Printer Where Name = '] + STRTRAN(lcPrinterName, [\], [\\]) + [']) * Check if new printer exists IF loPrinters.Count > 0 * FOR EACH loop is only way to access collection item(s) FOR EACH loPrinter IN loPrinters loPrinter.SetDefaultPrinter() ENDFOR ? "New default printer: " + SET("PRINTER", 2) *... loPrinters = loWMI.ExecQuery([Select * from Win32_Printer Where Name = '] + STRTRAN(lcSaveWinDefPrinter, [\], [\\]) + [']) FOR EACH loPrinter IN loPrinters loPrinter.SetDefaultPrinter() ENDFOR ? "Restored default printer: " + SET("PRINTER", 2) ENDIF
Comments
Forcing application objects to refresh default printer setting
Is there a way to force the new setting to be respected?
Cannot refresh default printer setting
Re: Forcing application objects to refresh default printer setti
Changing Windows default printer (Problem)
Re: Changing Windows default printer (Problem)
WMI requires to double any backslashes in the strings passed to it and I forgot to do that. It's fixed now.
Thanks for letting me know.
set printer to name
Does this "logic" apply to
set printer to name
report form
as well?
re: set printer to name
I'm not sure what logic are you referring to. 'set printer to name' changes printer for VFP application. It does not affect default Windows printer.
win10 set printer to name
GetDefaultPrinter()
Just thought I would add in this code for the next guy. I got here from UT while looking for a better way to change printers. For my code, I also did not want to be changing printers unnecessarily so I needed to get the default printer name (and I did not want to mix VFP code with the Win 32 api type calls - just in case). So here is how to use GetDefaultPrinter()
DECLARE INTEGER GetDefaultPrinter IN winspool.drv STRING @pszBuffer, INTEGER @pcchBuffer
* default buffer string to something really long (can be spaces or nulls)
STORE REPLICATE(CHR(0),250) TO lcCurrentPrinter
STORE GetDefaultPrinter(@lcCurrentPrinter,250) TO lnResult
* if error occurred, result is zero
IF lnResult = 0
STORE .T. TO llGeneralError
ELSE
* pull out the name from the string up to the first null character
* you can figure that one out yourself :-)
ENDIF