
有时您需要快速打印很多
带有文件
盖章的
图片 ,但是我不想为此打开每个文件。 建议的第一件事是使用资源管理器上下文菜单,但是此方法有其局限性和细微差别。 因此,我不得不寻找替代方案。 有关详细信息-请在目录下。
我们分析情况并收集数据
批打印的主题已经
在互联网文章
的伟大学者的
著作中反复提及。 例如,在
this和
this中 。

我们将首先弄清最终用户需要什么功能。 通过与同事的交流,我们得到了以下清单:
- 仅需要打印XML文件。
- 不需要XML格式;
- 在纸上,除内容外,还应注明要打印文件的名称;
- 文件应按名称排序,以便于在存档中归档纸张。
也许最简单和最明显的方法是从Explorer上下文菜单进行打印,可以在
此处和
此处阅读。 第二个链接提供了有关删除某些类型文件的“打印”项的信息,但是智能阅读器将很容易从中了解如何相反地添加丢失的文件。
但是此方法至少有两个缺点:
- 一次最多只能打印15个文件;
- 文件以随机顺序打印(也许仍然有逻辑,但是我没有找到),而不是以资源管理器中的排序方式打印。
第一个缺点很
容易通过调整注册表来解决。 为了解决第二个问题,有人
建议用铃鼓跳舞,但在我们中间,众神很严厉,这些仪式没有帮助。
有现成的第三方解决方案(上面提供了具有相关信息的文章的链接)。 但是,如果要用于商业用途,则必须购买这些产品,并且
锤击优雅的拐杖并发明另一辆自行车来自己动手做总是很高兴的。
我们选择一种工具并开发解决方案
注意事项 为了不翻译纸张,在准备和测试脚本阶段使用虚拟打印机很方便。 我对常规的Microsoft XPS Document Writer感到满意,但是还有
PDF24 Creator ,
doPDF和
CutePDF 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以及其他安全软件可能会干扰脚本启动,但这不在本文讨论范围之内。
您可以通过为快捷方式设置漂亮的图标来增加光泽。 我选择了这个:
如果脚本的用户很多,您可以使用
组策略首选项大量分发该快捷方式。
总结

如果在没有事先测试的情况下推出,则会发生这种情况。
我们将像这样:

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