Windows中的批量打印

有时您需要快速打印很多带有文件盖章图片 ,但是我不想为此打开每个文件。 建议的第一件事是使用资源管理器上下文菜单,但是此方法有其局限性和细微差别。 因此,我不得不寻找替代方案。 有关详细信息-请在目录下。

我们分析情况并收集数据


批打印的主题已经互联网文章的伟大学者著作中反复提及。 例如,在thisthis中

我们将首先弄清最终用户需要什么功能。 通过与同事的交流,我们得到了以下清单:

  • 仅需要打印XML文件。
  • 不需要XML格式;
  • 在纸上,除内容外,还应注明要打印文件的名称;
  • 文件应按名称排序,以便于在存档中归档纸张。

也许最简单和最明显的方法是从Explorer上下文菜单进行打印,可以在此处此处阅读。 第二个链接提供了有关删除某些类型文件的“打印”项的信息,但是智能阅读器将很容易从中了解如何相反地添加丢失的文件。

但是此方法至少有两个缺点:

  1. 一次最多只能打印15个文件;
  2. 文件以随机顺序打印(也许仍然有逻辑,但是我没有找到),而不是以资源管理器中的排序方式打印。

第一个缺点很容易通过调整注册表来解决。 为了解决第二个问题,有人建议用铃鼓跳舞,但在我们中间,众神很严厉,这些仪式没有帮助。
有现成的第三方解决方案(上面提供了具有相关信息的文章的链接)。 但是,如果要用于商业用途,则必须购买这些产品,并且锤击优雅的拐杖并发明另一辆自行车来自己动手做总是很高兴的。

我们选择一种工具并开发解决方案


注意事项 为了不翻译纸张,在准备和测试脚本阶段使用虚拟打印机很方便。 我对常规的Microsoft XPS Document Writer感到满意,但是还有PDF24 CreatordoPDFCutePDF Writer -正如他们所说,它的味道和颜色...

选择PowerShell作为语言。 在基本配置中,脚本如下所示:

选项0
$FolderToPrint = "\\server\share\Folder" $FileMask = "*.xml" $FolderToPrint | Get-ChildItem -File -Filter $FileMask | Sort-Object Name | ForEach-Object { Write-Output ("  `"" + $_.FullName + "`"") Start-Process -FilePath notepad -ArgumentList ("/P `"" + $_.FullName + "`"") -Wait } 


通过常规的Windows记事本进行打印(以免闲置)。
从第三行可以看到,示例中的排序是通过文件名( Name )进行的。 相反,您可以将大小( Length )或更改日期( LastWriteTime )作为基础。 如果您需要更奇特的东西,可以到这里

若要以相反的顺序进行排序 ,则Sort-Object cmdlet具有-Descending开关

在此选项下,默认情况下将打印发送到打印机,我们对此行为感到满意。 如果您需要使用默认打印机以外的其他打印机进行打印,则记事本具有/ PT选项。

因此,代码将采用以下形式:

 <...> $PrinterName = "\\server2\Network Printer" <...> Start-Process -FilePath notepad -ArgumentList ("/PT `"$PrinterName`" `"" + $_.FullName + "`"") -Wait <...> 

同样,可以使用任何其他程序来代替记事本,这取决于要打印的文件格式。 最主要的是它支持通过命令行界面进行打印。

注意事项 如果您要驯服Adobe Reader,请记住这个旧错误。 在我们的环境中,它仍在显现,也许您更幸运。 关于从PowerShell打印PDF也有一篇不错的文章

如果在输出中您只需要来自常规文本引擎的“裸露”文本,那么选项0的第五行将采用以下形式:

  Get-Content $_.FullName | Out-Printer -Name $PrinterName 

要使用默认打印机进行打印, 必须省略-Name参数。

我们的任务需要从多个位置打印文件。 稍微添加选项0,我们得到

选项1
 $FolderToPrint = @( "\\server1\share\Folder1", "\\server1\share\Folder2", "\\server1\share\Folder3" ) $FileMask = "*.xml" $ErrorActionPreference = "Stop" Try { $FolderToPrint | Get-ChildItem -File -Filter $FileMask | Sort-Object Name | ForEach-Object { Write-Output ("  `"" + $_.FullName + "`"") Start-Process -FilePath notepad -ArgumentList ("/P `"" + $_.FullName + "`"") -Wait } } Catch { Write-Host "    :" Write-Host $Error[0] -ForegroundColor Red Read-Host " ENTER  " } 


为了礼貌起见,添加了异常处理功能。 并且,例如,如果无法从中打印文件的文件夹,则打印将被中断,并且将相应地通知用户。 顺便说一句,注意到即使尝试打印不存在/不可访问的文件,笔记本在退出代码中仍返回0,但是在GUI中发誓。

尝试了选项1后,要求用户提供选择文件夹和其中特定文件的选项,因此,在文件选择对话框中添加了一些交互性。 所以它出现了

选项2
 Add-Type -AssemblyName System.Windows.Forms | Out-Null $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog $OpenFileDialog.InitialDirectory = "\\server\share" $OpenFileDialog.Multiselect = $True $OpenFileDialog.Filter = "XML- (*.xml)|*.xml|  (*.*)|*.*" $OpenFileDialog.ShowHelp = $true $OpenFileDialog.ShowDialog() | Out-Null $FilesToPrint = $OpenFileDialog.FileNames | Sort-Object ForEach ($FullFileName in $FilesToPrint) { Write-Output "  `"$FullFileName`"" Start-Process -FilePath notepad -ArgumentList ("/P `"$FullFileName`"") -Wait } 


现在,在启动时,我们将获得熟悉的Windows资源管理器窗口,并可以方便地选择必要的文件:

点击


您可以在官方文档中阅读有关使用文件打开对话框的更多信息,任何想进一步了解PowerShell GUI的人都可以轻松地在网络上找到很多资料,甚至还有在线表单设计器

自第二个选项以来,异常处理已被删除 交互式用户信息留给了指挥和记事本。

当您从ISE运行代码时,文件选择对话框会在后台显示( 按Ctrl + Tab即可获得帮助),但是从命令行来看,所有操作均按预期进行。 另请注意, ShowHelp属性必须为$ true才能解决错误。

我还想提请注意InitialDirectory属性。 上限会提示您确定文件夹的路径,脚本启动时将默认选择该路径。 但是,假设浏览器“记住”了用户在文件选择对话框中指定的最后一个选定位置,则InitialDirectory仅在首次运行脚本时才有用。

选项2完全适合我们的用户,因此我们停止使用它。 但是,如果您需要具有女士和偏好交互性且与名称不同的排序选项 (例如,按更改日期排序),这也是可行的。 我们得到

选项3
 Add-Type -AssemblyName System.Windows.Forms | Out-Null $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog $OpenFileDialog.InitialDirectory = "\\server\share" $OpenFileDialog.Multiselect = $True $OpenFileDialog.Filter = "XML- (*.xml)|*.xml|  (*.*)|*.*" $OpenFileDialog.ShowHelp = $true $OpenFileDialog.ShowDialog() | Out-Null $SelectedFiles = $OpenFileDialog.FileNames #   ,   If (!($SelectedFiles)) { Break } #         $SelectedDir = (Split-Path -Parent $OpenFileDialog.FileName) #       $FilesToPrint = Get-ChildItem -Path $SelectedDir -Force | #    ,       Where-Object {$_.FullName -in $OpenFileDialog.FileNames} | #  Sort-Object -Property LastWriteTime ForEach ($File in $FilesToPrint) { $FullFileName = $File.FullName Write-Output "  `"$FullFileName`"" Start-Process -FilePath notepad -ArgumentList ("/P `"$FullFileName`"") -Wait } 


因为 不能直接从$ OpenFileDialog对象中提取文件大小或创建日期之类的参数,然后我们使用Get-ChildItem cmdlet获取用户选择的文件夹中所有文件的列表,然后仅保留用户选择的文件并进行排序他们以我们需要的形式。

我们屈服生产


确保一切正常后,将脚本放入网络文件夹中,并为用户显示桌面快捷方式。

为了使我们的小型无防御脚本不会受到邪恶的执行策略的攻击 ,我们将其隐藏在这样的外壳中:

 powershell.exe -NoLogo -ExecutionPolicy Bypass -File "\\server\share\Scripts\BulkPrint.ps1" 

点击


或者,您可以将其包装在热管批处理文件中。

除其他事项外,在公司环境中,苛刻的软件限制策略和无情的AppLocker以及其他安全软件可能会干扰脚本启动,但这不在本文讨论范围之内。

您可以通过为快捷方式设置漂亮的图标来增加光泽。 我选择了这个:

点击


如果脚本的用户很多,您可以使用组策略首选项大量分发该快捷方式。

总结




如果在没有事先测试的情况下推出,则会发生这种情况。

我们将像这样:



最后,还有煽动性的思想:如果您以不同的方向思考,而不是与上述所有内容进行沟通,并与老板沟通并重新组织工作流程,该怎么办?

Source: https://habr.com/ru/post/zh-CN441384/


All Articles