I've made a program that will run on startup asking the users to select their default printer. The code shows all installed printers in a ComboBox and the submit Button will set the Printer selected in the ComboBox as the default printer for that user.
Is there a way I can only show Printers names that contain specific text?
As e.g.:
ABC
printer1ABC
network1 abc
printer2 def
network2def
So it would only show printer1ABC
and network1 abc
?
Here's the code I have so far (one ComboBox and one Button)
Imports System.Drawing.Printing
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim strInstalledPrinters As String
Dim prntDoc As New PrintDocument
'check if there is installed printer
If PrinterSettings.InstalledPrinters.Count = 0 Then
MsgBox("No printer installed")
Exit Sub
End If
'display installed printer into combobox list item
For Each strInstalledPrinters In PrinterSettings.InstalledPrinters
ComboBox1.Items.Add(strInstalledPrinters)
Next strInstalledPrinters
'Display current default printer on combobox texts
ComboBox1.Text = prntDoc.PrinterSettings.PrinterName
Button1.Text = "Set Default Printer"
End Sub
End Class
Function to set a printer as default:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Shell(String.Format("rundll32 printui.dll,PrintUIEntry /y /n ""{0}""", ComboBox1.Text))
MsgBox("You have changed your default printer")
Me.Close()
End Sub
Thanks for any help
PrinterSettings.InstalledPrinters is collection of string that enumerates the available Printer names. You can filter this collection in different ways to select only the Printers that you want to show.
Here, using LINQ's Where() method, the collection is filtered selectin strings that contain part of the name you're looking for:
dim myPrinters = PrinterSettings.InstalledPrinters.OfType(Of String).
Where(Function(p) p.Contains("1ABC")).ToList()
You can add OrElse
conditions to include other filters. E.g., :
.Where(Function(p) p.Contains("1ABC") OrElse p.StartsWith("Network1"))
Before enumerating the Printers, you should verify whether the Spooler Service is actually available. You can use the ServiceController class to check the Status
property of the spooler
service, to see if it's ServiceControllerStatus.Running and act on it. If the Spooler is not running, you get an exception if you try to enumerate the available printers in any way.
▶ Add a Project Reference to the System.ServiceProcess
assembly.
You can also get other exceptions when you try to perform this enumeration, depending on different conditions, so better catch these exceptions and make different choices.
An example:
As a suggestion, give your Controls meaningful names, in case these are the actual names you're using
Imports System.Drawing.Printing
Imports System.Linq
Imports System.ServiceProcess
Private Const RPC_ERROR As Integer = 1722
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Button1.Text = "Set Default Printer"
Button1.Enabled = False
Dim spoolerStatus = New ServiceController("spooler").Status
If spoolerStatus = ServiceControllerStatus.Running Then
Try
Dim myPrinters = PrinterSettings.InstalledPrinters.OfType(Of String).
Where(Function(p) p.Contains("1ABC")).ToList()
If myPrinters.Count > 0 Then
ComboBox1.DataSource = myPrinters
Button1.Enabled = True
Else
ComboBox1.Items.Add("<Printer not installed>")
End If
Catch wEx As Win32Exception
If wEx.NativeErrorCode = RPC_ERROR Then
' RPC Server unavailable
ComboBox1.Items.Add($"<{wEx.Message}>")
Else
' Log Message
MessageBox.Show(wEx.Message)
ComboBox1.Items.Add("<Error>")
End If
Catch ex As Exception
' Log Message
MessageBox.Show(ex.Message)
ComboBox1.Items.Add("<Error>")
End Try
Else
ComboBox1.Items.Add("<Spooler Service not available>")
End If
ComboBox1.SelectedIndex = 0
End Sub
To change the default printer, I suggest to use the SetdefaultPrinter Win32 function or the corresponding WMI's Win32_Printer class SetDefaultPrinter method.
▶ When you click your Button to set the new default Printer, use the GetItemText() method to get the ComboBox1.SelectedItem
content, don't rely on the Text property of that Control.
Imports System.Runtime.InteropServices
<DllImport("winspool.drv", CharSet:=CharSet.Auto, SetLastError:=True)>
Friend Shared Function SetDefaultPrinter(printerName As String) As Boolean
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim printeNname = ComboBox1.GetItemText(ComboBox1.SelectedItem)
If SetDefaultPrinter(printeNname) Then
MessageBox.Show($"Your default printer is now {printeNname}")
Else
MessageBox.Show("Couldn't change the default printer")
End If
Me.Close()
End Sub