Impressão em massa no Windows

Às vezes, você precisa imprimir rapidamente muitas fotos com selos de documentos, mas não quero abrir todos os arquivos para isso. A primeira coisa que sugere é o uso do menu de contexto do Explorer, mas esse método tem suas limitações e nuances. Portanto, eu tive que procurar uma alternativa. Para detalhes - por favor, abaixo do gato.

Analisamos a situação e coletamos dados


O tópico da impressão em lotes foi repetidamente abordado nas obras de grandes estudiosos em artigos da Internet. Por exemplo, neste e isto .

Começaremos descobrindo que funcionalidade os usuários finais precisam. Como resultado da comunicação com colegas, obtivemos a seguinte lista:

  • Somente arquivos XML precisam ser impressos.
  • a formatação para XML não é necessária;
  • no papel, além do conteúdo, também deve ser indicado o nome do arquivo a ser impresso;
  • os arquivos devem ser classificados por nome, para que seja conveniente arquivar folhas de papel no arquivo morto.

Talvez o mais simples e mais óbvio seja a impressão no menu de contexto do Explorer, que pode ser lido aqui e aqui . O segundo link fornece informações sobre a remoção do item "Imprimir" para certos tipos de arquivos, mas o leitor inteligente entenderá facilmente com ele como, pelo contrário, você pode adicionar o que está faltando.

Mas esse método tem pelo menos duas desvantagens:

  1. Você não pode imprimir mais de 15 arquivos por vez;
  2. os arquivos são impressos em ordem aleatória (talvez ainda haja lógica, mas eu não a encontrei) e não da maneira como são classificados no Explorer.

A primeira desvantagem é facilmente corrigida pelo registro de ajustes. Para resolver o segundo, existem recomendações na forma de danças com um pandeiro, mas em nosso meio os deuses são severos e esses rituais não ajudaram.
Existem soluções de terceiros prontas (links para artigos com informações sobre eles são fornecidos acima). Mas para uso comercial, você terá que pagar por esses produtos, e sempre é bom martelar uma muleta elegante e inventar outra bicicleta para fazer algo com suas próprias mãos.

Selecionamos uma ferramenta e desenvolvemos uma solução


Nota Para não traduzir o papel, é conveniente usar uma impressora virtual na fase de preparação e teste do script. Fiquei satisfeito com o Microsoft XPS Document Writer comum, mas também há PDF24 Creator , doPDF , CutePDF Writer - como eles dizem, tem sabor e cor ...

O PowerShell foi escolhido como o idioma. Na configuração básica, o script fica assim:

Opção 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 } 


A impressão é feita por meio de um bloco de notas normal do Windows (para não ficar ocioso).
Como você pode ver na 3ª linha, a classificação no exemplo ocorre pelo nome do arquivo ( Nome ). Em vez disso, você pode tomar como base o tamanho ( comprimento ) ou a data da alteração ( LastWriteTime ). Se você precisar de algo mais exótico, pode ir aqui .

Para classificar na ordem inversa, o cmdlet Sort-Object possui a opção -Descending .

Nesta opção, a impressão vai para a impressora por padrão e estamos satisfeitos com esse comportamento. Se você precisar imprimir em uma impressora diferente da padrão, o bloco de notas possui a opção / PT .

Por conseguinte, o código terá o seguinte formato:

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

Da mesma forma, em vez do bloco de notas, você pode usar qualquer outro programa, dependendo do formato do arquivo que deseja imprimir. O principal é que ele suporta impressão através da interface da linha de comandos.

Nota Se você quiser domar o Adobe Reader, lembre-se desse bug antigo. Em nosso ambiente, ele ainda está se manifestando, talvez você tenha mais sorte. Também há um bom artigo sobre impressão de PDFs no PowerShell.

Se na saída você precisar apenas de texto "vazio" de um mecanismo de texto normal, a quinta linha da opção 0 assumirá o seguinte formato:

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

Para imprimir na impressora padrão, o parâmetro -Name deve ser omitido.

Nossa tarefa exigia a impressão de arquivos de vários locais. Adicionando ligeiramente a opção 0, obtemos

Opção 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  " } 


Por decência, uma função de tratamento de exceção foi adicionada. E se, por exemplo, a pasta na qual os arquivos são impressos se tornar inacessível, a impressão será interrompida e o usuário será notificado em conformidade. A propósito, percebe-se que o notebook retorna 0 no código de saída, mesmo ao tentar imprimir um arquivo inexistente / inacessível, mas jura na GUI.

Depois de tentar a opção 1, os usuários foram solicitados a dar a opção de selecionar uma pasta e arquivos específicos nela, para que um pouco de interatividade fosse adicionado como uma caixa de diálogo de seleção de arquivo. Então apareceu

Opção 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 } 


Agora, na inicialização, obtemos a janela familiar do Windows Explorer com uma seleção conveniente dos arquivos necessários:

clique


Você pode ler mais sobre como trabalhar com a caixa de diálogo de abertura de arquivo na documentação oficial , e quem quiser saber mais sobre a GUI do PowerShell pode encontrar facilmente muito material na rede, há até um designer de formulários on - line .

O tratamento de exceções na segunda opção foi removido desde as informações interativas do usuário foram deixadas para o condutor e o bloco de notas.

Quando você executa o código no ISE, a caixa de diálogo de seleção de arquivo é exibida em segundo plano ( Ctrl + Tab para ajudar), mas a partir da linha de comando tudo funciona conforme o esperado. Observe também que a propriedade ShowHelp deve ser $ true para contornar esse bug.

Também gostaria de chamar a atenção para a propriedade InitialDirectory . A tampa indica que ele determina o caminho para a pasta, que será selecionada por padrão quando o script iniciar. Porém, considerando que o explorador “lembra” o último local selecionado especificado pelo usuário na caixa de diálogo de seleção de arquivo, o InitialDirectory pode ser útil apenas quando o script é executado pela primeira vez.

A opção 2 era completamente adequada para nossos usuários, então paramos nela. Mas se você precisar de uma opção com mulheres e interatividade preferencial e classificação diferente do nome (por exemplo, na data da mudança), isso também é possível. Nós temos

Opção 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 } 


Porque parâmetros como tamanho do arquivo ou data de criação não podem ser extraídos diretamente do objeto $ OpenFileDialog , usamos o cmdlet Get-ChildItem para obter uma lista de todos os arquivos na pasta selecionada pelo usuário e deixar apenas os que foram selecionados pelo usuário e classificar eles na forma que precisamos.

Damos em produção


Depois de garantir que tudo funcione como deveria, coloque o script em uma pasta de rede e exiba um atalho na área de trabalho para os usuários.

E para que nosso pequeno script indefeso não seja ofendido pelas políticas de execução ruins, nós o ocultamos dessa maneira:

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

clique


Ou você pode agrupar um arquivo em lote de tubos quentes.

Entre outras coisas, em um ambiente corporativo, as Políticas de Restrição de Software e o AppLocker implacável, bem como outros softwares de segurança, podem interferir na inicialização do script, mas isso está além do escopo deste artigo.

Você pode adicionar brilho definindo um ícone bonito para o atalho. Eu escolhi isso:

clique


Se houver muitos usuários do nosso script, você poderá distribuir massivamente o atalho usando as Preferências de Diretiva de Grupo .

Sumário




Isso acontece se implementado sem testes anteriores.

E teremos assim:



E, finalmente, pensamento sedicioso: e se você pensar em uma direção diferente e, em vez de tudo descrito acima, se comunicar com os chefes e reorganizar o processo de trabalho?

Source: https://habr.com/ru/post/pt441384/


All Articles