Hello! I'm new here, so please be gentle. I'm working on a small program to map network printers for an enterprise I work for. My ability to access the printers is limited to standard user permissions and I can make no changes to the network whatsoever.
I got this working fairly easily using PowerShell's Get-Printer and Add-Printer cmdlets, but when I attempted to use the same commands in C# I discovered that those two cmdlets do not seem to be included in the System.Management.Automation library. The PowerShell code I am attempting to adapt is below:
Function mapPrinter () {
try {
$title = "Printer Mapping Status"
$message = "Printer successfully mapped! Please allow some time for printer to appear as an option."
if ($PrinterListBox.SelectedItems.Count -gt 0) {
foreach ($printer in $PrinterListBox.SelectedItems) {
$printerPath = "\\" + $printer.SERVER + "\" + $printer.PRINTER
Add-Printer -ConnectionName $printerPath -ErrorAction Stop
}
displayMessage -msg $message -ttl $title
$PrinterMapButton.IsEnabled = $false
}
}
catch {
$message = ""
$title = "Printer Mapping Error"
displayMessage -msg $message -ttl $title
}
}
I attempted to import the PrintManagement module into the runspace of the PowerShell instance, but every attempt I made failed. The latest attempt is below:
private void mapPrinter(object sender, RoutedEventArgs e)
{
if (PrinterListBox.SelectedItems.Count > 0)
{
foreach (PrinterObject printer in PrinterListBox.SelectedItems)
{
InitialSessionState iss = InitialSessionState.CreateDefault();
iss.ImportPSModule("PrintManagement");
using (Runspace runSpace = RunspaceFactory.CreateRunspace(iss))
{
runSpace.Open();
using (var pipeline = runSpace.CreatePipeline())
{
string printerPath = "\\\\" + printer.Server + "\\" + printer.Printer;
var parameters = new Dictionary
{
{"ComputerName", printer.Server},
{"ConnectionName", printerPath},
{"ErrorAction", "Stop"}
};
Command cmd = new Command("Add-Printer");
cmd.Parameters.Add("ComputerName", printer.Server);
cmd.Parameters.Add("ConnectionName", printerPath);
cmd.Parameters.Add("ErrorAction", "Stop");
pipeline.Commands.Add(cmd);
pipeline.Invoke();
}
}
}
}
}
I have also attempted to use CimSession for this purpose. In that case, I managed to get the mapping functionality working, but when attempting to do connection validation it has thus far failed. I can't assume the paths fed to the program are valid, so I need to be able to test them prior to presenting them to users as an option. The "easiest" way to do this is the Add- and Get-Printer cmdlets, but they have thus far proven to be very far from easy.
My question / request is this: how the devil do you get Add- and Get-Printer working in C#?
Jayraj ChhayaPosted Oct 23, 2024, 7:41 AM
To utilize PowerShell's
Add-PrinterandGet-Printercmdlets in a C# WPF application, you can leverage theSystem.Management.Automationnamespace to create a PowerShell runspace. However, ensure that the PrintManagement module is correctly imported. Below is a refined approach to achieve this:Import the PrintManagement Module: Ensure that the module is available on the system where the application runs. You can check this by running
Get-Module -ListAvailablein PowerShell.Modify the C# Code: Here’s an updated version of your
mapPrintermethod that includes error handling and validation:Get-Printerin a similar manner to check if the printer exists:This approach allows you to check if the printer is valid before attempting to add it. By handling errors effectively and ensuring the module is imported, you can streamline the printer mapping process in your application.