我已经写了几个安装打印机为新用户的脚本。
我想改变一些的这些设置,以便他们可以在纸张的两面打印。
我认为,这涉及到修改与printui属性,但它可能需要VB脚本或者可能是其他.NET语言(我要么使用VB,C#或IronPython的)。
我可以添加注释于指定的打印机,但如何选择的偏好并进行修改?
伪代码是这样的:
printui.exe / N打印机名称/ ??? [如何改变质量所需]
或调用相关的Windows API。
我已经写了几个安装打印机为新用户的脚本。
我想改变一些的这些设置,以便他们可以在纸张的两面打印。
我认为,这涉及到修改与printui属性,但它可能需要VB脚本或者可能是其他.NET语言(我要么使用VB,C#或IronPython的)。
我可以添加注释于指定的打印机,但如何选择的偏好并进行修改?
伪代码是这样的:
printui.exe / N打印机名称/ ??? [如何改变质量所需]
或调用相关的Windows API。
你也许可以做到这一点使用printui,设置打印机进行双面打印,然后使用printui / SS将设置拖放到一个文件中。 通过各种选项去,即2,7,d ...看看哪些文件保存双工设置。
另一种方法是使用打印机的API,并请使用PRINTER_INFO_8(全球)或PRINTER_INFO_9(用户)结构- MSDN链接 。 然后使用DEVMODE结构设置dmDuplex到双面的。
首先打开打印机,然后关闭它,当你完成:
[DllImport("winspool.drv", EntryPoint = "OpenPrinter", SetLastError = true)]
internal static extern bool OpenPrinter(string pPrinterName, ref IntPtr phPrinter, PRINTER_DEFAULTS pDefault);
[DllImport("winspool.drv", EntryPoint = "ClosePrinter", SetLastError = true)]
internal static extern int ClosePrinter(IntPtr hPrinter);
使用GETPRINTER检索当前的打印机设置,并SetPrinter放回修改后的设置:
[DllImport("winspool.drv", CharSet = CharSet.Auto, EntryPoint = "GetPrinter", SetLastError = true)]
internal static extern bool GetPrinter(IntPtr hPrinter, uint Level, IntPtr pPrinter, uint cbBuf, out uint pcbNeeded);
[DllImport("winspool.drv", CharSet = CharSet.Auto, EntryPoint = "SetPrinter", SetLastError = true)]
internal static extern bool SetPrinter(IntPtr hPrinter, uint Level, IntPtr pPrinter, uint Command);
该代码真正做到这一点应该是这个样子:
var oldPrinter = printerFunctions.OpenPrinterHandle(String.Format(@"{0}\{1}", oldServerName, oldPrinterName));
var printerInfo8 = printerFunctions.GetPrinterInfo<PRINTER_INFO_8>(oldPrinter, 8);
// Change the dmDuplex value here.
printerFunctions.SetPrinter(oldPrinter, printerInfo8, 8);
printerFunctions.ClosePrinterHandle(oldPrinter);
public IntPtr OpenPrinterHandle(string printerName)
{
var def = new PRINTER_DEFAULTS { pDatatype = null, pDevMode = IntPtr.Zero, DesiredAccess = OpenPrinterAccessCodes.PRINTER_ALL_ACCESS };
var hPrinter = IntPtr.Zero;
if (!PrinterNativeMethods.OpenPrinter(printerName, ref hPrinter, def))
{
var lastWin32Error = new Win32Exception(Marshal.GetLastWin32Error());
Logger.Log("Failed open Printer: " + lastWin32Error.Message);
throw lastWin32Error;
}
return hPrinter;
}
public void ClosePrinterHandle(IntPtr hPrinter)
{
PrinterNativeMethods.ClosePrinter(hPrinter);
}
public void SetPrinter<T>(IntPtr hPrinter, T printerInfo, uint level)
{
var size = (uint)Marshal.SizeOf(printerInfo);
var printerInfoPtr = Marshal.AllocHGlobal((int)size);
Marshal.StructureToPtr(printerInfo, printerInfoPtr, true);
var result = PrinterNativeMethods.SetPrinter(hPrinter, level, printerInfoPtr, 0);
if (!result)
{
var win32Error = Marshal.GetLastWin32Error();
var lastWin32Error = new Win32Exception(win32Error);
Logger.Log("Failed set printer: " + lastWin32Error.Message);
throw lastWin32Error;
}
Marshal.FreeHGlobal(printerInfoPtr);
}
public T GetPrinterInfo<T>(IntPtr hPrinter, uint level)
{
uint pcbNeeded;
var bFlag = PrinterNativeMethods.GetPrinter(hPrinter, level, IntPtr.Zero, 0, out pcbNeeded);
var win32Error = Marshal.GetLastWin32Error();
if ((!bFlag) && (win32Error != PrinterNativeMethods.ERROR_INSUFFICIENT_BUFFER) || (pcbNeeded == 0))
{
var lastWin32Error = new Win32Exception(win32Error);
Logger.Log("Failed get printer: " + lastWin32Error.Message);
throw lastWin32Error;
}
var currentPrinterInfoPtr = Marshal.AllocHGlobal((int)pcbNeeded);
bFlag = PrinterNativeMethods.GetPrinter(hPrinter, level, currentPrinterInfoPtr, pcbNeeded, out pcbNeeded);
if (!bFlag)
{
var lastWin32Error = new Win32Exception();
Logger.Log("Failed get printer: " + lastWin32Error.Message);
throw lastWin32Error;
}
return (T)Marshal.PtrToStructure(currentPrinterInfoPtr, typeof(T));
}