Reputation: 167
I'm using a modified version of the script I found at https://monadblog.blogspot.com/2006/02/msh-print-image.html. It allows you to print by using PowerShell.
Something that I have been unable to figure out is how to print borderless, I have removed margins and I tried adding a custom paper size or sending a bigger image than the allowed image to the printer but it didn't work. Is there a way to enable the borderless flag?
$imageName = 'C:\image.png'
$printer = "Canon SELPHY CP1500"
$fitImageToPaper = $true
trap { break; }
# check out Lee Holmes' blog(http://www.leeholmes.com/blog/HowDoIEasilyLoadAssembliesWhenLoadWithPartialNameHasBeenDeprecated.aspx)
# on how to avoid using deprecated "LoadWithPartialName" function
# To load assembly containing System.Drawing.Printing.PrintDocument
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
# Bitmap image to use to print image
$bitmap = $null
$doc = new-object System.Drawing.Printing.PrintDocument
$doc.DefaultPageSettings.Margins.Left = 0
$doc.DefaultPageSettings.Margins.Right = 0
$doc.DefaultPageSettings.Margins.Top = 0
$doc.DefaultPageSettings.Margins.Bottom = 0
Write-Host $doc.DefaultPageSettings.PaperSize
# if printer name not given, use default printer
if ($printer -ne "") {
$doc.PrinterSettings.PrinterName = $printer
}
$doc.DocumentName = [System.IO.Path]::GetFileName($imageName)
$doc.add_BeginPrint({
Write-Host "==================== $($doc.DocumentName) ===================="
})
# clean up after printing...
$doc.add_EndPrint({
if ($bitmap -ne $null) {
$bitmap.Dispose()
$bitmap = $null
}
Write-Host "xxxxxxxxxxxxxxxxxxxx $($doc.DocumentName) xxxxxxxxxxxxxxxxxxxx"
})
# Adjust image size to fit into paper and print image
$doc.add_PrintPage({
Write-Host "Printing $imageName..."
$g = $_.Graphics
$pageBounds = $_.PageBounds
$img = new-object Drawing.Bitmap($imageName)
$adjustedImageSize = $img.Size
$ratio = [double] 1;
# Adjust image size to fit on the paper
if ($fitImageToPaper) {
$fitWidth = [bool] ($img.Size.Width > $img.Size.Height)
if (($img.Size.Width -le $_.MarginBounds.Width) -and
($img.Size.Height -le $_.MarginBounds.Height)) {
$adjustedImageSize = new-object System.Drawing.SizeF($img.Size.Width, $img.Size.Height)
} else {
if ($fitWidth) {
$ratio = [double] ($_.MarginBounds.Width / $img.Size.Width);
} else {
$ratio = [double] ($_.MarginBounds.Height / $img.Size.Height)
}
$adjustedImageSize = new-object System.Drawing.SizeF($img.Size.Width, $img.Size.Height)
}
}
# calculate destination and source sizes
$recDest = new-object Drawing.RectangleF($pageBounds.Location, $adjustedImageSize)
$recSrc = new-object Drawing.RectangleF(0, 0, $img.Width, $img.Height)
# Print to the paper
$_.Graphics.DrawImage($img, $recDest, $recSrc, [Drawing.GraphicsUnit]"Pixel")
$_.HasMorePages = $false; # nothing else to print
})
$doc.Print()
Thanks!
Upvotes: 0
Views: 331
Reputation: 675
While I can't fully test borderless printing since I don't have a printer to test it with, I was able to test enable duplex printing using the same method.
We can accomplish this using the System.Printing
namespace. Specifically, we will use PrintServer
, PrintQueue
, and UserPrintTicket
to edit the PageBorderless
property.
We first create a PrintServer
object. You can either use LocalPrintServer
for locally connected device or you can specify a print server name:
$PrintServer = New-Object System.Printing.LocalPrintServer
#$PrintServer = New-Object System.Printing.PrintServer("\\somePrintserver")
We then create a PrintQueue
specifying the PrintServer object, a printer name, and PrintSystemDesiredAccess
which specifies access right for printing objects. I set the access to AdministratePrinter
.
$desiredAccess = New-Object System.Printing.PrintSystemDesiredAccess
# AdministratePrinter value
$desiredAccess.value__ = 983052
$printerName = "TEST"
# Create PrintQueue object using the PrintServer, printer name, and the desired access as parameters
$PrintQueue = New-Object System.Printing.PrintQueue($PrintServer,$printerName,$desiredAccess)
Once the queue is created we can get the UserPrintTicket, which we will use to modify the PageBorderless
property
# get UserPrintTicket from the PrintQueue
$PrintTicket = $PrintQueue.UserPrintTicket
I did add some checks to make sure that the printer has the capability before changing that setting. Using $PrintQueue.GetPrintCapabilities()
we can see the capabilities and verify before changing them. Due to limitation of my printer I was only able to verify this was working for changing the Duplexing
property but since it's the same as editing the PageBorderless property I believe it should still work. I left the example for Duplexing in here. You will need to add back in the code to handle actual printing since this just modifies the setting.
$exitOnNotEnabled = $true
Add-Type -AssemblyName System.Printing
# Specify desired access to modify settings
$desiredAccess = New-Object System.Printing.PrintSystemDesiredAccess
# AdministratePrinter value
# https://learn.microsoft.com/en-us/dotnet/api/system.printing.printsystemdesiredaccess?view=windowsdesktop-7.0
$desiredAccess.value__ = 983052
# change to your printer name
$printerName = "TEST"
# Create PrintServer object. Can specify a print server but here I just have printer connected locally.
$PrintServer = New-Object System.Printing.LocalPrintServer
#$PrintServer = New-Object System.Printing.PrintServer("\\somePrintserver")
# Create PrintQueue object using the PrintServer, printer name, and the desired access as parameters
$PrintQueue = New-Object System.Printing.PrintQueue($PrintServer,$printerName,$desiredAccess)
# get UserPrintTicket from the PrintQueue
$PrintTicket = $PrintQueue.UserPrintTicket
# get printer capabilities. Going to use to make sure we only change setting that the printer has
$PrintCapabilities = $PrintQueue.GetPrintCapabilities()
# check if the PageBorderlessCapability exists
if ($PrintCapabilities.PageBorderlessCapability -ne $null){
Write-Output "-------------------------"
Write-Output "PageBorderless is currently set to $($PrintTicket.PageBorderless)"
Write-Output "-------------------------"
# check if the PageBorderlessCapability contains 'Borderless'
if ($PrintCapabilities.PageBorderlessCapability.Contains("Borderless")){
Write-Output "Borderless printing capability found"
Write-Output "Enable Borderless printing"
# set to borderless printing
$PrintTicket.PageBorderless = 1
$PrintQueue.Commit()
$PrintQueue.Refresh()
Write-Output "-------------------------"
Write-Output "PageBorderless is currently set to $($PrintTicket.PageBorderless)"
Write-Output "-------------------------"
}
else{
Write-Output "Borderless printing capability NOT found"
}
}
else{
Write-Output "PageBorderlessCapability is null. Printer may not support it."
}
# example for duplexing since I couldn't test borderless printing
# https://learn.microsoft.com/en-us/dotnet/api/system.printing.duplexing?view=windowsdesktop-7.0
if ($PrintCapabilities.DuplexingCapability -ne $null){
Write-Output "-------------------------"
Write-Output "Duplex is currently set to $($PrintTicket.Duplexing)"
Write-Output "-------------------------"
if ($PrintCapabilities.DuplexingCapability.Contains("TwoSidedLongEdge")){
Write-Output "Duplexing capability TwoSidedLonEdge found."
Write-Output "Enabling duplex TwoSidedLonEdge"
# change duplexing to "TwoSidedLonEdge"
$PrintTicket.Duplexing = 3
$PrintQueue.Commit()
$PrintQueue.Refresh()
Write-Output "-------------------------"
Write-Output "Duplex is currently set to $($PrintTicket.Duplexing)"
Write-Output "-------------------------"
}
else{
Write-Output "Duplexing capability TwoSidedLonEdge NOT found."
}
}
if (($PrintQueue.UserPrintTicket.PageBorderless -ne 1) -and $exitOnNotEnabled){
Write-Output "Borderless Printing was not enabled..exiting"
exit
}
if (($PrintQueue.UserPrintTicket.Duplexing -ne 3) -and $exitOnNotEnabled){
Write-Output "Duplexing printing TwoSidedLonEdge was not enabled..exiting"
exit
}
### do stuff you were doing to print ###
### change back setting if you wanted
# something like
# $PrintTicket.PageBorderless = 0
# $PrintQueue.Commit()
PageBorderlessCapability is null. Printer may not support it.
-------------------------
Duplex is currently set to OneSided
-------------------------
Duplexing capability TwoSidedLonEdge found.
Enabling duplex TwoSidedLonEdge
-------------------------
Duplex is currently set to TwoSidedLongEdge
-------------------------
Borderless Printing was not enabled..exiting
Code will exit if the settings for PageBorderless or Duplexing were not able to be change. $exitOnNotEnabled = $true
you can change that to $false
so that doesn't happen. You could also just remove the duplexing parts since that example doesn't pertain to the setting you actually want to change.
"Classes within the System.Printing namespace are not supported for use within a Windows service or ASP.NET application or service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions"ref
Upvotes: 0