Controlando a codificação da saída do comando do console win redirecionado

2

Aqui está o que eu quero fazer:

Redirecionando corretamente a saída dos aplicativos de console (eu uso o termo comando no restante da mensagem) em um arquivo com codificação 1252 (para torná-lo legível a partir de qualquer bloco de notas mole na configuração padrão. / p>

O que eu observei:

Chcp é eficaz com comandos internos e algum comando externo (recentes)

Em primeiro lugar, vale a pena notar que a CHCP opera de maneira diferente no Win7 e no Win 10.

Se o lote a seguir for executado a partir de um prompt do cmd, você poderá notar que as saídas do comando são exibidas corretamente no console do win10, enquanto um console do win7 renderiza mal os caracteres do ASCII.

for /f "tokens=2 delims=:" %%G in ('chcp') do Set _cp_=%%G
chcp 1252
@echo test an internal command
dir
@echo test an external (recent) command: Robocopy
robocopy .\ .\ /L
@echo test an external (legacy) command: Xcopy
xcopy test.txt 2>&1
chcp %_cp_%
echo end of test.cmd batch 
A propósito, estou interessado em saber o que causa tal diferença, embora não seja realmente o propósito dessa mensagem e uma vez que é facilmente corrigível, adicionando uma chamada ps chamada “powershell [console] :: outputencoding = [system.text.encoding] :: getencoding (850) ”no lote após o primeiro comando chcp.

Qualquer que seja o problema real, ocorre quando a saída em lote é redirecionada para um arquivo: test.cmd > test.txt.

Nesse caso, o resultado é o mesmo, seja qual for o sistema operacional. A saída de comandos internos e novos comandos externos (Robocopy, Bcdedit, etc) são corretamente codificados 1252. Comandos legados (xcopy, chcp, etc) não são (saída na página de códigos OEM). Em resumo, a maioria dos comandos não são afetados pelo CHCP ou pela mudança equivalente [console] através do powershell.

Várias especulações sobre essa bagunça:

  1. O código de comando herdado é baseado no CRT, enquanto os comandos internos e os mais recentes usam a API do Win32. Ele é baseado na última seção sobre o desenvolvimento de aplicativos do console em Passo a passo de globalização do MSDN !

  2. Como pelo menos win10 o que é exibido no console (mesma codificação para todas as saídas de comando) e armazenado em um arquivo é diferente (codificação de saída muda dependendo do comando), fluxos de saída / entrada podem ser manipulados diferentemente dependendo do tipo de alças apontam. As funções do console podem ser usadas para exibição e funções de arquivo de E / S em caso de redirecionamento. Especulação baseada em Funções de Entrada e Saída de Console de Alto Nível !

  3. A MS recomenda que o código dos aplicativos de console force a codificação OEM do fluxo de saída. Ref. Problemas do aplicativo do console Se a sugestão do MS for aplicada no código de comandos externos, isso poderá explicar por que o redirecionamento de seus fluxos de saída para um arquivo é sempre codificado como OEM_CP, independentemente da aplicação da página de código do console. Estranhamente, readfile e writefile não são mencionados entre as funções afetadas por SetFileApisToOEM

Por fim, não sei se a diferença entre os comandos legados e os recentemente introduzidos é porque o código deles respeita a sugestão do MS e apenas porque os literais de string são codificados como OEM vs ANSI.

Soluções possíveis / solução alternativa

Se 3 estiver correto, eles são certamente muito poucos .: É possível alterar o valor da chave de registro HKLM \ system \ current \ control \ NLS \ codepage OEMCP = 1252. Não é seguro (não tente definir o Unicode 65001, seu sistema pode recusar a inicialização) e inconveniente (reinicialização necessária). Ou preenchendo o arquivo apenas com conteúdo codificado pelo OEM e transcodificando o arquivo com o script PS no final do lote. Simples, mas não muito elegante, se o arquivo tiver que ser acessado e verificado periodicamente.

Se 2 estiver correto, pode existir uma função que controla a codificação da função de arquivo de E / S readfile e writefile .

Se 1 estiver correto, deve ser possível controlar as configurações internacionais ou a cultura da sessão atual do usuário e, assim, controlar a página de código do aplicativo CRT. Desde o Win8, é possível através do Configurações internacionais do Powershell no Windows . Os aplicativos de linha de comando também são capazes de executar tais tarefas. Seja como for, a dificuldade aqui é criar uma “cultura” com a página de códigos OEM definida como 1252 como que não existe em o conjunto predefinido .

Mesmo que não haja uma solução efetiva em relação a esse problema, não hesite em compartilhar seus conhecimentos sobre esse tópico. Estou apenas curioso para entender como o MS implementou essas coisas.

    
por user3528651 28.04.2016 / 18:16

0 respostas