2

新しいユーザー用に複数のプリンターをインストールするスクリプトを作成しました。

これらのいくつかの設定を変更して、ページの両面に印刷できるようにしたいと考えています。

これにはprintuiで属性を変更することが含まれると思いますが、VBスクリプトまたは別の.NET言語が必要になる場合があります(VB、C#、またはIronPythonのいずれかを使用します)。

特定のプリンタにコメントを追加できますが、設定を選択して変更するにはどうすればよいですか?

擬似コードは次のようになります。

printui.exe /n プリンター名 /??? 【希望品質の変更方法】

または、関連する Windows API への呼び出し。

4

1 に答える 1

2

おそらく、printui を使用してこれを行い、プリンターを両面印刷に設定してから、printui /Ss を使用して設定をファイルにドロップすることができます。さまざまなオプション、つまり 2、7、d... を調べて、どのファイルが二重設定を保持しているかを確認します。

もう 1 つの方法は、プリンター 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));
}
于 2012-12-18T23:02:09.400 に答える