Schimbarea setărilor aplicațiilor păstrând preferințele personale

Povestea

Într-o organizație medicală, au fost implementate soluții bazate pe servere PACS Orthanc și client DICOM Radiant. În timpul configurării, s-a constatat că fiecare client DICOM trebuie descris în serverele PACS în următorul mod:

  • Numele clientului
  • Numele AE (trebuie să fie unic)
  • Portul TCP, care se deschide automat pe partea clientului și primește examene DICOM de la serverul PACS (adică, serverul le împinge către client – inițiind conexiunea prima dată)
  • Adresă IP

După configurarea clienților Radiant, am primit următoarele informații de reflectare – fiecare client avea o configurație software cu parametrii menționați mai sus, care ducea la completarea fișierului pacs.xml, care se afla în profilul utilizatorului (calea: %APPDATA%RadiantViewerpacs.xml). În acest sens, configurația unui client se deosebea de alta prin cel puțin doi parametri (numele AE fiind diferit pentru toți, iar portul în principal identic, cu excepția clienților terminali care funcționează pe același server – acolo porturile trebuiau de asemenea atribuite diferit).

Exemplu de fișier pacs.xml pentru linkul:

Aproximativ șase luni totul a mers bine, sistemul a funcționat... și apoi au ajuns la noi „capcanele subterane»:

  • Trebuie să introducem în funcțiune câteva servere PACS noi, care vor înlocui pe cele vechi (unde s-a terminat spațiul pe discuri). Serverele PACS sunt în mașini virtuale, dar nu despre asta este vorba;
  • Trebuie să schimbăm cumva centralizat configurațiile unice (cu cele două parametrii diferiți) pe 200 de mașini (numărul acestora crescând constant);
  • Având în vedere ritmul de creștere a volumului de examinări, soluția trebuie să fie nu o singură dată, ci replicabilă și regulată (de exemplu, o dată la 3-5 luni).

Soluția este mai jos.

Alegerea instrumentelor pentru soluționarea sarcinii

La început, au fost încercări de a găsi o soluție care să modifice fișierul pacs.xml pe partea clientului și să facă modificări în lista serverelor PACS, fără a altera setările numelui AE și portului TCP. Clienții Windows, în acel moment, erau atât pe Windows XP, cât și pe Windows 7 – prin urmare, au fost încercări de a scrie ceva pe baza VBScript. Dar din păcate – nu am reușit să duc la bun sfârșit o astfel de sarcină, din cauza lipsei totale de experiență în scrierea ceva complex pe acest limbaj. Încercările de a găsi și a rescrie de asemenea nu au avut succes (aici trebuie menționat că deja aveam un alt plan în minte, așa că nu am insistat pe VBScript mai mult de 3-4 ore).

În cele din urmă, m-am oprit la următoarea soluție:

  • Adună toate fișierele pacs.xml într-un singur loc pe un server din resursa de rețea;
  • Schimbă fișierele în grup (avem experiență în soluționarea unor astfel de sarcini – folosind Perl);
  • De asemenea, actualizează setările clienților folosind politici de grup.

Strângerea fișierelor cu ajutorul politicii de grup

Cea mai simplă parte – atunci când clientul se conectează la profilul său, cu drepturile sale execută un anumit fișier .bat, în care este specificat:

echo off
If exist %APPDATA%RadiantViewerpacs.xml copy %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml

Astfel, pe server în resursa ascunsă vor acumula fișierele pacs.xml, în numele cărora există informații din ce calculator și de la ce utilizator a fost copiat acest config.

Cea mai dificilă parte a fost – să așteptăm până când politica a fost aplicată tuturor utilizatorilor.

Modificarea configurațiilor cu ajutorul unui script Perl

Ne va trebui Active Perl pentru Windows de la ActiveState, precum și modulul XML::Writer, care poate fi instalat folosind comanda ppm install XML-Writer.

Scriptul în sine este destul de simplu:

use XML::Writer;
 
# Deschidem folderul cu rapoarte, procesăm lista (îndepărtăm surplusul):
	$report_dir = "C:Perl64WORKPACS-xml3";
	opendir(DIR, "$report_dir") or die "Nu pot deschide folderul cu rapoarte!";
	@report_files = readdir DIR;
	shift (@report_files); # îndepărtăm punctul din elementele array-ului (.)
	shift (@report_files); # îndepărtăm două puncte din elementele array-ului (..)
#	print "@report_files";
	closedir(DIR);
 
# Începem să procesăm fișierele - unul câte unul. Trebuie să citim parametrul AET și numărul portului în variabile.
foreach $analiz_file (@report_files) 
{
	$full_path_to_file="C:Perl64WORKPACS-xml3".$analiz_file;
	open (INFO, $full_path_to_file);
 
	while ($line = )
	{
		# Variabilele $aet și $port conțin date unice pentru fiecare fișier XML:
		my ($other1, $aet, $other2, $port, $other3) = split /"", $line, 5;
		# Dacă întâlnim linia listener - atunci am ajuns la linia dorită și putem forma un nou XML:
		if ($other1 =~ 'listener')
			{
				# Formăm un nou XML cu câmpurile și datele necesare:
				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');
 
				# Plasăm XML-ul generat în variabilă:
				my $xml = $writer->end();
				# Pregătim fișierul pentru rescriere:
				$rewritexml = $full_path_to_file;
				# Rescriem fișierele XML cu noile date:
				open (NEWXML, ">>$rewritexml");
				print NEWXML $xml;
				close (NEWXML);				
			}
	}
 
}

Principiul său de funcționare:

  • Deschidem catalogul în care avem configurările pacs.xml de la clienți și plasăm lista fișierelor în un array scalari (@report_files);
  • Într-un ciclu, procesăm câte un fișier și citim linie cu linie;
  • Folosind split, împărțim fiecare linie în 5 părți, folosind ghilimelele ca separator;
  • Găsim linia cu cuvântul listener și plasăm în două variabile date unice pentru fiecare fișier (numele AE al clientului și numărul portului TCP);
  • După aceea, pur și simplu formăm un nou fișier XML, introducem parametrii unici și apoi inserăm numărul necesar de servere PACS cu parametrii lor - adică, ceea ce se urma de la bun început)
  • Scriem noul fișier XML peste cel vechi.

Trebuie menționat că, de fapt, eu folosesc acest script nu complet automat – practic, copiez configurațiile adunate într-un catalog separat și apoi, rulând scriptul, le modific în întregime. Apoi, fac o verificare selectivă – și configurațiile pot fi distribuite înapoi pe mașini.

Distribuția fișierelor pacs.xml modificate către clienți

Cel mai simplu lucru care mi-a venit în minte – să fac modificări în fișierul .bat deja funcțional, care adună configurațiile de la clienți și să adaug o linie:

If exist %APPDATA%RadiantViewerpacs.xml copy /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml

Fișierul .bat final arată așa:

@echo off
If exist %APPDATA%RadiantViewerpacs.xml copy %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml
If exist %APPDATA%RadiantViewerpacs.xml copy /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml

Concluzie

Așa-numitul „soluție artizanală„. L-am testat deja de două ori (în septembrie 2018 și februarie 2019), până acum zborul este normal. Desigur, nu actualizează 100% dintre clienți, dar se apropie de acest procent — pe ceilalți îi finalizăm de la distanță. Scriptul linkul.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster