Alterar as configurações do programa enquanto mantém as configurações pessoais

Antecedentes


Em uma organização médica, eles implementaram soluções baseadas nos servidores Orthanc PACS e no cliente DICOM da Radiant. Durante a instalação, descobrimos que cada cliente DICOM deve ser descrito nos servidores PACS da seguinte maneira:

  • Nome do cliente
  • Nome do AE (deve ser exclusivo)
  • Uma porta TCP que se abre automaticamente no lado do cliente e recebe exames DICOM do servidor PACS (ou seja, o servidor os envia para o cliente, por assim dizer, iniciando a conexão primeiro)
  • Endereço IP

Após a configuração, os clientes Radiant receberam as seguintes informações para consideração - para cada cliente, a configuração do software com os parâmetros acima levou ao preenchimento do arquivo pacs.xml , localizado no perfil do usuário (caminho: % APPDATA% \ RadiantViewer \ pacs.xml ). Ao mesmo tempo, a configuração de um cliente de outro diferia em pelo menos dois parâmetros (o nome do AE é diferente para todos e a porta é basicamente a mesma, exceto para clientes de terminal em execução no mesmo servidor - lá você também precisava atribuir portas diferentes).

Exemplo de arquivo pacs.xml no link :

Por cerca de meio ano, tudo correu bem, o sistema funcionou ... e as " armadilhas " chegaram até nós:

  • Precisamos colocar em operação vários novos servidores PACS, que substituirão os antigos (onde o espaço em disco começou a acabar). Servidores PACS em máquinas virtuais, mas isso não é sobre isso;
  • Precisamos, de alguma forma, alterar as configurações exclusivas centralmente (com dois parâmetros diferentes) em 200 máquinas (o número delas aumenta regularmente);
  • Dada a taxa de crescimento do volume de exames, a solução não é uma solução única, mas replicada e regular (por exemplo, uma vez a cada 3-5 meses).

A solução está abaixo.

A escolha de ferramentas para resolver o problema


Inicialmente, houve tentativas de encontrar alguma solução que alterasse o arquivo pacs.xml no lado do cliente e fizesse alterações na lista de servidores PACS sem tocar no nome do AE e nas configurações da porta TCP. Os clientes Windows da época eram baseados no Windows XP e no Windows 7 - portanto, houve tentativas de escrever algo parecido com o VBScript. Mas, infelizmente, não foi possível dominar essa tarefa, tendo em vista a completa falta de experiência em escrever algo complicado e complexo nessa linguagem. As tentativas de encontrar e reescrever também não tiveram êxito (observe que já havia um plano diferente em minha cabeça, por isso não me incomodei com o VBScript por mais de 3-4 horas).

No final, decidi pela seguinte solução:

  • Colete todos os arquivos pacs.xml pela política de grupo em um local em qualquer servidor em um compartilhamento de rede;
  • Modifique arquivos em massa (já existe experiência na solução de tais problemas - usando Perl);
  • Além disso, use diretivas de grupo para atualizar as configurações do cliente.

Coletando arquivos usando a Diretiva de Grupo


A parte mais simples é que, quando um cliente efetua login em seu perfil, ele com seus direitos executa um certo arquivo .bat no qual está escrito:

echo off If exist %APPDATA%\RadiantViewer\pacs.xml copy %APPDATA%\RadiantViewer\pacs.xml \\srv.test.local\pconfigs$\pacs-%COMPUTERNAME%-%USERNAME%.xml 

Portanto, os arquivos pacs.xml serão acumulados no servidor em um recurso oculto, cujo nome contém informações de qual computador e de qual usuário essa configuração foi copiada.

O mais difícil foi esperar que todos os usuários concluíssem essa política.

Alterando configurações usando um script Perl


Precisamos do Active Perl para Windows do ActiveState, bem como do módulo XML :: Writer, que pode ser instalado usando o comando ppm install XML-Writer .

O script em si acabou sendo bastante simples:

 use XML::Writer; #    ,   ( ): $report_dir = "C:\\Perl64\\WORK\\PACS-xml3\\"; opendir(DIR, "$report_dir") or die "     !"; @report_files = readdir DIR; shift (@report_files); #      (.) shift (@report_files); #       (..) # print "@report_files"; closedir(DIR); #    -    .    AET     . foreach $analiz_file (@report_files) { $full_path_to_file="C:\\Perl64\\WORK\\PACS-xml3\\".$analiz_file; open (INFO, $full_path_to_file); while ($line = <INFO>) { #  $aet  $port      XML : my ($other1, $aet, $other2, $port, $other3) = split /\"/, $line, 5; #    listener -           XML: if ($other1 =~ 'listener') { #   XML c    : my $writer = XML::Writer->new(OUTPUT => 'self', DATA_MODE => 1, DATA_INDENT => 2, ); $writer->xmlDecl('utf-8'); $writer->startTag('pacs'); $writer->startTag('listener', ae => $aet, port => $port); $writer->endTag(); $writer->startTag('hosts'); $writer->startTag('host', name => 'MRT', ae => 'ORTHANC', ip => 'XX.YY.214.17', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0'); $writer->endTag(); $writer->startTag('host', name => 'KT', ae => 'ORTHANC2', ip => 'XX.YY.215.253', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0'); $writer->endTag(); $writer->startTag('host', name => 'R', ae => 'ORTHANC3', ip => 'XX.YY.215.252', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0'); $writer->endTag(); $writer->startTag('host', name => 'KT-20180501-20180831', ae => 'ORTHANC4', ip => 'XX.YY.215.251', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0'); $writer->endTag(); $writer->startTag('host', name => 'KT-20180901-20181130', ae => 'ORTHANC5', ip => 'XX.YY.215.250', ts => '1.2.840.10008.1.2.1', port => '4242', maxassoc => '1', allpres => '0', search => '1', protocol => '1', searchcharset => '', wildcards => '3', carets => '0'); $writer->endTag(); $writer->endTag('hosts'); $writer->startTag('presets'); $writer->endTag(); $writer->startTag('lastsearch', dt => '4', mfid => '1048592'); $writer->endTag(); $writer->endTag('pacs'); #   XML  : my $xml = $writer->end(); #    : $rewritexml = $full_path_to_file; #  XML   : open (NEWXML, ">$rewritexml"); print NEWXML $xml; close (NEWXML); } } } 

O princípio do seu trabalho:

  • Abrimos o diretório em que coletamos as configurações pacs.xml dos clientes e colocamos a lista de arquivos em uma matriz de escalares (@report_files);
  • Em um loop, processamos um arquivo de cada vez e o lemos linha por linha;
  • Usando divisão, divida cada linha em 5 partes, usando aspas como separador;
  • Encontramos a linha com a palavra listener e inserimos duas variáveis, dados exclusivos para cada arquivo (nome do cliente AE e número da porta TCP);
  • Depois disso, simplesmente criamos um novo arquivo XML, inserimos parâmetros exclusivos nele e inserimos o número necessário de servidores PACS com seus parâmetros - ou seja, algo para o qual tudo foi iniciado )
  • Reescreva o novo arquivo XML em cima do antigo.

Deve-se observar que, na verdade, eu não uso esse script completamente automaticamente - na verdade, copio as configurações coletadas em um diretório separado, depois executo o script e as altero todas juntas. Em seguida, uma verificação aleatória - e as configurações podem ser colocadas de volta nas máquinas.

Distribuindo arquivos pacs.xml modificados para clientes


A coisa mais simples que me ocorreu foi fazer alterações em um arquivo .bat já em funcionamento que coleta configurações de clientes e adiciona uma linha:

 If exist %APPDATA%\RadiantViewer\pacs.xml copy /Y \\srv.test.local\pconfigsnew$\pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%\RadiantViewer\pacs.xml 

O arquivo .bat resultante é assim:

 @echo off If exist %APPDATA%\RadiantViewer\pacs.xml copy %APPDATA%\RadiantViewer\pacs.xml \\srv.test.local\pconfigs$\pacs-%COMPUTERNAME%-%USERNAME%.xml If exist %APPDATA%\RadiantViewer\pacs.xml copy /Y \\srv.test.local\pconfigsnew$\pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%\RadiantViewer\pacs.xml 

Conclusão


Essa é a solução "até o joelho ". Já o testamos duas vezes (em setembro de 2018 e fevereiro de 2019), enquanto o voo era normal. Obviamente, ele não atualiza 100% dos clientes, mas próximo a esse valor - finalizamos o resto remotamente. Script por referência .

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


All Articles