2012-05-22 110 views
1

我已經編寫了一個腳本,爲新用戶安裝了幾臺打印機。以編程方式在Windows中更改打印機首選項

我想更改其中某些設置,以便它們可以在頁面的兩面打印。

我相信這涉及到修改一個屬性與printui,但它可能需要VB腳本或可能另一個.NET語言(我會使用VB,C#或IronPython)。

我可以給給定打印機添加註釋,但是如何選擇偏好並修改它們?

僞代碼是這樣的:

printui.exe/N打印機名稱/ ??? [如何更改所需的質量]

或調用相關的Windows API。

回答

1

您可以使用printui完成此操作,將打印機設置爲雙面打印,然後使用printui/S將設置放入文件。瀏覽各種選項,即2,7,d ...並查看哪個文件保存了雙面打印設置。

另一種方法是使用打印機API,並使用PRINTER_INFO_8(全局)或PRINTER_INFO_9(用戶)結構 - MSDN link。然後使用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)); 
} 
相關問題