Frustration with PrinterSetup Strings

I was wondering if anyone has a class for reading and modifying (which is supposedly disallowed) printer setup strings?

This morning I had a terrible time trying to extract the printer name before I realized that the printer string contains non-printable characters.

I ended up with this method just to get the printer name.

Function ExtractPrinterName(PrinterSetupString as String) As String dim PrinterName as String if PrinterSetupString.InStr(0,"DevModeStructurePS=") > 0 Then PrinterName = PrinterSetupString.right(PrinterSetupString.Len - (PrinterSetupString.InStr(0,"DevModeStructurePS=") + 18)) PrinterName = PrinterName.Left(PrinterName.InStr(0,chr(0))-1) end if Return PrinterName End Function

On windows I can get the default printer like this:

Sub GetDefaultPrinter()
  Dim reg As New RegistryItem("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows")
  dim p as string = reg.Value("Device")
  dim p1() as string = p.split(",")
  if DefaultPrinter.Text <> p1(0) Then DefaultPrinter.Text = p1(0)
  
  Exception err as RegistryAccessErrorException
    MsgBox "Error getting default printer."
End Sub

Get a list of available printers like this:

[code]Public Sub GetPrinters()
Dim objNetwork As OLEObject
Dim objPrinters As OLEObject
objNetwork = New OLEObject(“WScript.Network”)
objPrinters = objNetwork.EnumPrinterConnections
Dim nDrives As Integer = (objPrinters.Count)
PrinterList.DeleteAllRows
For i as integer = 0 to nDrives -1 Step 2
PrinterList.AddRow objPrinters.Item(i + 1)
Next

exception err as oleexception
msgbox err.message
End Sub
[/code]

And then set the default printer like this:

[code]Public Sub SetDefaultPrinter()
Dim objNetwork As OLEObject
objNetwork = New OLEObject(“WScript.Network”)
objNetwork.SetDefaultPrinter(PrinterList.Text)

exception err as oleexception
msgbox err.message
End Sub
[/code]

Is there no way to read / edit printer settings without displaying the printer dialogs?
What a cross platform solution (which I don’t need at this time)?

not fully tested but this should work, on mac,linux and widows.

Structure PrinterDefinition printerName as string*80 printerModel as string*50 printerURI as string*127 End Structure

Public Property mPrinters() as PrinterDefinition

[code]Public Sub SystemScanPrinters()
ReDim mPrinters(-1)
dim p as PrinterDefinition

dim myShell as new shell
#if TargetMacOS or TargetLinux
myShell.Execute “lpstat -p”
#Elseif TargetWindows
myShell.Execute “wmic printer get name,default”
#endif
dim result as String = myShell.Result
dim reslines() as String = result.ReadFields(EndOfLine)

for each line as String in reslines
#if TargetMacOS or TargetLinux
p.printerName = MotNumero(line,2)
mPrinters.Append p
#Elseif TargetWindows
p.printerName = MotNumero(line,2)
if p.printerName<>“Name” then
mPrinters.Append p
end if
#endif

next
End Sub
[/code]

[code]Public Function SystemCountPrinters() as Integer
’ returns the number of defined printers on the running system

SystemScanPrinters
Return UBound(mPrinters)+1

End Function
[/code]

[code]Public Sub SystemSetDefaultPrinter(aPrinterName as String)
if UBound(mPrinters)<0 then
SystemScanPrinters
end if

if UBound(mPrinters)>=0 then
dim printer,foundPrinter as PrinterDefinition

' recherche l'imprimante
for each printer in mPrinters
  if printer.printerName = aPrinterName then
    foundPrinter = printer
    Exit For
  end if
next

if foundPrinter.printerName<>"" then
  dim myShell as new shell
    
  #if TargetMacOS or TargetLinux
    myShell.Execute "lpoptions -d "+aPrinterName
  #Elseif TargetWindows
    myShell.Execute "wmic printer where name='"+aPrinterName+"' call setdefaultprinter"
  #endif
else
  Alerte "SystemSetDefaultPrinter: Printer "+aPrinterName+" is unknown."
end if

Else
Alerte “SystemSetDefaultPrinter: No printer defined.”
end if

End Sub
[/code]

@Jean-Yves Pochez ReadFields, MotNumero and Alerte ?

Thanks for the fun :wink: (You have widows, but what about orphans ?)

oups !
alerte, you can use msgbox instead
otherwise,

[code]Attributes ( extendsString ) Public Function ReadFields(extends s as string, eofChar as String = “”) as String()
’ split a string into fields if you know the field separator
dim myeof as String = kTabulation

if eofChar<>“” then
myeof = eofChar
end if

Return Split( s, myeof)

End Function
[/code]
and

Public Function MotNumero(theString as string, theNumero as integer) as string ' retourne le nieme mot dans une chaine return NthField(theString," ",theNumero) End Function
and also

Public Const kTabulation as Number = &u09

You could use WindowsDeviceModeMBS class on Windows to work with Printersetup and change all settings:
http://www.monkeybreadsoftware.net/class-windowsdevicemodembs.shtml

For Mac same with NSPrintInfoMBS:
http://www.monkeybreadsoftware.net/class-nsprintinfombs.shtml

It can also tell you printer name.