2017-10-19 105 views
1

由于来自Microsoft的最新安全更新已将Jet OLEDB Provider无法使用,因此我必须重写几个较老的VBScript。在没有prnadmin.dll的情况下使用powershell安装“打印机窗体”?

是否有更好的方法在Windows Server 2008 R2和2012 R2上安装打印机表单,然后通过regsvr32/COM/VBscript调用过时的prnadmin.dll

prnadmin.dll最初与Windows Server 2000 Resource Kit一起引入,我想将整个脚本迁移到PowerShell。

不幸的是我找不到模块PrintManagement内的任何有用的PowerShell cmdlet。那么如何使用PSH将自定义表单添加到打印机服务器?

+0

也许[此](https://social.technet.microsoft.com/Forums/azure/en-US/5784736a-a4f1-41cf-9767-ed7b993557a2/add-and-delete-custom-printer-forms-using-powershell?forum = ITCG)help。它似乎是供应商特定的。 – DarkLite1

回答

1

添加系统表单定义的编程方法是致电AddForm。我知道这个电话没有很好的包装,但是P/Invoking为AddForm。我写了一个快速包装和posted it on GitHub

实施例使用包装:

Windows PowerShell 
Copyright (C) 2016 Microsoft Corporation. All rights reserved. 

PS C:\Drop> Import-Module .\PowershellPrinterFormsModule.dll 
PS C:\Drop> Add-SystemForm -Name 'Demo User Form try 1' -Units Inches -Size '4,5' 
PS C:\Drop> Add-SystemForm -Name 'Demo User Form try 2' -Units Inches -Size '4,5' -Margin '0.25,0.5' 
PS C:\Drop> Add-SystemForm -Name 'Demo User Form try 3' -Units Millimeters -Size '80,50' -Margin '10,10,0,0' 

实际P /调用调用AddForm

SafePrinterHandle hServer; 
if (!OpenPrinter(null, out hServer, IntPtr.Zero)) 
{ 
    throw new Win32Exception(); 
} 
using (hServer) 
{ 
    var form = new FORM_INFO_1() 
    { 
     Flags = 0, 
     Name = this.Name, 
     Size = (SIZEL)pageSize, 
     ImageableArea = (RECTL)imageableArea 
    }; 

    if (!AddForm(hServer, 1, ref form)) 
    { 
     throw new Win32Exception(); 
    } 
} 

internal static class NativeMethods 
{ 
    #region Constants 

    internal const int ERROR_INSUFFICIENT_BUFFER = 0x7A; 

    #endregion 

    #region winspool.drv 

    private const string Winspool = "winspool.drv"; 

    [DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)] 
    internal static extern bool OpenPrinter(string szPrinter, out SafePrinterHandle hPrinter, IntPtr pd); 

    public static SafePrinterHandle OpenPrinter(string szPrinter) 
    { 
     SafePrinterHandle hServer; 
     if (!OpenPrinter(null, out hServer, IntPtr.Zero)) 
     { 
      throw new Win32Exception(); 
     } 
     return hServer; 
    } 

    [DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)] 
    internal static extern bool ClosePrinter(IntPtr hPrinter); 

    [DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)] 
    internal static extern bool EnumForms(SafePrinterHandle hPrinter, int level, IntPtr pBuf, int cbBuf, out int pcbNeeded, out int pcReturned); 

    [DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)] 
    internal static extern bool AddForm(SafePrinterHandle hPrinter, int level, [In] ref FORM_INFO_1 form); 

    [DllImport(Winspool, SetLastError = true, CharSet = CharSet.Unicode)] 
    internal static extern bool DeleteForm(SafePrinterHandle hPrinter, string formName); 

    #endregion 

    #region Structs 

    [StructLayout(LayoutKind.Sequential)] 
    internal struct FORM_INFO_1 
    { 
     public int Flags; 
     [MarshalAs(UnmanagedType.LPWStr)] 
     public string Name; 
     public SIZEL Size; 
     public RECTL ImageableArea; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    internal struct SIZEL 
    { 
     public int cx; 
     public int cy; 

     public static explicit operator SIZEL(Size r) 
      => new SIZEL { cx = (int)r.Width, cy = (int)r.Height }; 
     public static explicit operator Size(SIZEL r) 
      => new Size(r.cx, r.cy); 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    internal struct RECTL 
    { 
     public int left; 
     public int top; 
     public int right; 
     public int bottom; 

     public static explicit operator RECTL(Rect r) 
      => new RECTL { left = (int)r.Left, top = (int)r.Top, right = (int)r.Right, bottom = (int)r.Bottom }; 
     public static explicit operator Rect(RECTL r) 
      => new Rect(new Point(r.left, r.top), new Point(r.right, r.bottom)); 
    } 

    #endregion 
} 

internal sealed class SafePrinterHandle : SafeHandleZeroOrMinusOneIsInvalid 
{ 
    public SafePrinterHandle() 
     : base(true) 
    { 
    } 

    protected override bool ReleaseHandle() 
    { 
     return NativeMethods.ClosePrinter(handle); 
    } 
} 
+0

感谢您的努力! – Matze

相关问题