Als Erweiterung zu https://roman.gallauner.at/default-papiergroesse-papersize-eines-druckers-mit-powershell-aendern/ hier eine Funktion mit der man benutzerdefinierte Etikettengrößen pro Drucker setzen kann (wenn PaperSize im vordefinierten Layout mal “fluktuiert” – soll ja angeblich passieren…):
param([switch]$Debug)
# https://www.codeproject.com/Articles/6899/Changing-printer-settings-using-C
$c=@'
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using Microsoft.Win32;
public class PrinterSettings
{
[DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern Int32 GetLastError();
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint="DocumentPropertiesA", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter, [MarshalAs(UnmanagedType.LPStr)] string pDeviceName, IntPtr pDevModeOutput, ref IntPtr pDevModeInput, int fMode);
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr PrinterDefaults);
[DllImport("winspool.drv", CharSet = CharSet.Ansi, SetLastError = true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int Command);
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_INFO_9
{
public IntPtr pDevMode;
}
private const short CCDEVICENAME = 32;
private const short CCFORMNAME = 32;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCDEVICENAME)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCFORMNAME)]
public string dmFormName;
public short dmUnusedPadding;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
}
private const int PRINTER_ACCESS_USE = 0x8;
private const int DM_OUT_BUFFER = 0x2;
private const int DM_MODIFY = 0x8;
private const int DM_PAPERSIZE = 0x2;
private const int DM_PAPERLENGTH = 0x4;
private const int DM_PAPERWIDTH = 0x8;
public static bool ChangePaperSize(string sPrinterName, short nSize, short nWidth, short nHeight, out string sDebug)
{
DEVMODE oDM;
IntPtr pNativeDM = IntPtr.Zero;
int nBytesNeeded = 0;
IntPtr hPrinter = new System.IntPtr();
PRINTER_INFO_9 oPrinterInfo;
IntPtr pNativePrinterInfo = IntPtr.Zero;
IntPtr pDummy=IntPtr.Zero;
bool bChanged=false;
sDebug="";
//Console.WriteLine("Open printer");
if (!OpenPrinter(sPrinterName, out hPrinter, IntPtr.Zero))
{
Console.WriteLine("OpenPrinter() failed with error "+Marshal.GetLastWin32Error()+", aborting.");
sDebug += "OpenPrinter() failed with error "+Marshal.GetLastWin32Error()+", aborting.\n";
return false;
}
//Console.WriteLine("Getting bytes needed for DEVMODE via DocumentProperties");
nBytesNeeded=DocumentProperties(IntPtr.Zero,hPrinter,sPrinterName,IntPtr.Zero,ref pDummy,0);
//Console.WriteLine("Bytes needed: "+nBytesNeeded+", allocating.");
pNativeDM=Marshal.AllocHGlobal(nBytesNeeded);
//Console.WriteLine("Fetching DEVMODE via DocumentProperties");
DocumentProperties(IntPtr.Zero,hPrinter,sPrinterName,pNativeDM,ref pDummy,DM_OUT_BUFFER);
oDM = (DEVMODE)Marshal.PtrToStructure(pNativeDM, typeof(DEVMODE));
//Console.WriteLine("Free native DM");
Marshal.FreeHGlobal(pNativeDM);
//Console.WriteLine("Old size: "+oDM.dmPaperSize);
if (oDM.dmPaperSize != nSize)
{
Console.WriteLine("dmPaperSize="+oDM.dmPaperSize+" => "+nSize);
sDebug += "dmPaperSize="+oDM.dmPaperSize+" => "+nSize + "\n";
oDM.dmPaperSize = nSize;
oDM.dmFields |= DM_PAPERSIZE;
bChanged=true;
}
if (nWidth != 0 && oDM.dmPaperWidth != nWidth)
{
Console.WriteLine("dmPaperWidth="+oDM.dmPaperWidth+" => " +nWidth);
sDebug += "dmPaperWidth="+oDM.dmPaperWidth+" => " +nWidth + "\n";
oDM.dmPaperWidth=nWidth;
oDM.dmFields |= DM_PAPERWIDTH;
bChanged=true;
}
if (nHeight != 0 && oDM.dmPaperLength != nHeight)
{
Console.WriteLine("dmPaperLength="+oDM.dmPaperLength+" => " +nHeight);
sDebug += "dmPaperLength="+oDM.dmPaperLength+" => " +nHeight + "\n";
oDM.dmPaperLength=nHeight;
oDM.dmFields |= DM_PAPERLENGTH;
bChanged=true;
}
if (bChanged)
{
//Console.WriteLine("Allocating memory for new native DEVMODE");
pNativeDM = Marshal.AllocHGlobal(Marshal.SizeOf(oDM));
//Console.WriteLine("Copy managed DEVMODE to native memory");
Marshal.StructureToPtr(oDM, pNativeDM, true);
//Console.WriteLine("Modifying DEVMODE with DocumentProperties");
DocumentProperties(IntPtr.Zero,hPrinter,sPrinterName,pNativeDM,ref pDummy,DM_MODIFY);
oPrinterInfo.pDevMode = pNativeDM;
//Console.WriteLine("Copy managed PRINTER_INFO_9 to native memory");
pNativePrinterInfo = Marshal.AllocHGlobal(Marshal.SizeOf(oPrinterInfo));
Marshal.StructureToPtr(oPrinterInfo, pNativePrinterInfo, true);
//Console.WriteLine("Writing new PRINTER_INFO_9 to printer");
if (!SetPrinter(hPrinter, 9, pNativePrinterInfo, 0))
{
Console.WriteLine("SetPrinter() failed with error "+Marshal.GetLastWin32Error()+", aborting.");
sDebug += "SetPrinter() failed with error "+Marshal.GetLastWin32Error()+", aborting.\n";
Cleanup(pNativeDM, pNativePrinterInfo, hPrinter);
return false;
}
Cleanup(pNativeDM, pNativePrinterInfo, hPrinter);
}
else
{
Console.WriteLine("Nothing to do, exiting.");
sDebug += "Nothing to do, exiting.\n";
}
return true;
}
public static void Cleanup(IntPtr pNativeDM,IntPtr pNativePrinterInfo,IntPtr hPrinter)
{
try
{
//Console.WriteLine("Memory and handle cleanup");
if (hPrinter != IntPtr.Zero) ClosePrinter(hPrinter);
if (pNativeDM != IntPtr.Zero) Marshal.FreeHGlobal(pNativeDM);
if (pNativePrinterInfo != IntPtr.Zero) Marshal.FreeHGlobal(pNativePrinterInfo);
}
catch (Exception)
{
}
}
}
'@
if ($Debug)
{
Start-Transcript "$($env:Temp)\PaperSize.log"
}
Add-Type -TypeDefinition $c -ReferencedAssemblies System.Runtime.InteropServices,System.ComponentModel
Add-Type -AssemblyName System.Drawing
$printers="\\printserver\printer1~495~360#\\printserver\printer2~USER~495~360"
foreach ($printerinfo in $printers.Split('#'))
{
Write-Host "====================================================="
$printer=$printerinfo.Split('~')[0]
$paper=$printerinfo.Split('~')[1]
$width=$printerinfo.Split('~')[2]
$height=$printerinfo.Split('~')[3]
$ps=New-Object System.Drawing.Printing.PrinterSettings
$ps.PrinterName=$printer
$size=$ps.PaperSizes|? PaperName -eq $paper
if ($null -ne $size)
{
Write-Host "$($printer): size (raw): $($size.RawKind)"
$messages=""
$success=[PrinterSettings]::ChangePaperSize($printer,$size.RawKind,$width,$height,[ref]$messages)
if ($Debug) { $messages }
if ($success)
{
Write-Host " ==> SUCCESS"
}
else
{
Write-Host " ==> ERROR"
}
}
else
{
Write-Host "$($printer): PaperSize $($paper) not found."
}
}
if ($Debug)
{
Stop-Transcript
}