Programos nustatymų keitimas išsaugant asmeninius parametrus

priešistorė

Viena medicinos organizacija įdiegė sprendimus, pagrįstus Orthanc PACS serveriais ir Radiant DICOM klientu. Sąrankos metu išsiaiškinome, kad kiekvienas DICOM klientas turi būti aprašytas PACS serveriuose taip:

  • Kliento vardas
  • AE pavadinimas (turi būti unikalus)
  • TCP prievadas, kuris automatiškai atsidaro kliento pusėje ir gauna DICOM apklausas iš PACS serverio (t. y. serveris stumia juos link kliento – pirmiausia inicijuoja ryšį)
  • IP adresas

Sukūrę Radiant, klientai gavo peno apmąstymams: kiekvienam klientui nustačius programinę įrangą su aukščiau nurodytais parametrais, failas buvo užpildytas pacs.xml, kuris buvo vartotojo profilyje (kelias: %APPDATA%RadiantViewerpacs.xml). Tuo pačiu metu vieno kliento konfigūracija nuo kito skyrėsi bent dviem parametrais (AE pavadinimas visiems skirtingas, o prievadas iš esmės tas pats, išskyrus terminalo klientus, veikiančius tame pačiame serveryje – ten prievadai taip pat turėjo priskirti kitokiam).

Pacs.xml failo pavyzdys nuoroda:

Apie šešis mėnesius viskas buvo gerai, sistema pradėjo veikti... ir tada ji atėjo pas mus “po vandeniu akmenys"

  • Turime pradėti eksploatuoti kelis naujus PACS serverius, kurie pakeis senuosius (kur pradėjo trūkti vietos diske). PACS serveriai virtualiose mašinose, bet ne apie tai kalbame;
  • Turime kažkaip centralizuotai pakeisti unikalias konfigūracijas (su dviem skirtingais parametrais) 200 mašinų (jų skaičius nuolat didėjo);
  • Atsižvelgiant į apklausų apimčių augimo tempą, sprendimas reikalingas ne vieną kartą, o kartoti ir reguliariai (pavyzdžiui, kartą per 1-3 mėnesius).

Sprendimas yra žemiau.

Įrankių pasirinkimas problemai išspręsti

Iš pradžių buvo bandoma rasti sprendimą, kuris pakeistų pacs.xml failą kliento pusėje ir pakeistų PACS serverių sąrašą nepažeidžiant AE pavadinimo ir TCP prievado nustatymų. „Windows“ klientai tuo metu buvo pagrįsti ir „Windows XP“, ir „Windows 7“, todėl buvo bandoma kažką panašaus parašyti remiantis VBScript. Deja, tokios užduoties atlikti nepavyko, nes visiškai trūko patirties rašant ką nors sudėtingo ir visapusiško šia kalba. Bandymai surasti ir perrašyti taip pat buvo nesėkmingi (reikia pastebėti, kad mano galvoje jau buvo kitoks planas, todėl su VBScript nesikišau ilgiau nei 3-4 valandas).

Galiausiai apsistojau ties tokiu sprendimu:

  • Naudodami grupės politiką, surinkite visus pacs.xml failus vienoje vietoje bet kuriame tinklo išteklių serveryje;
  • Masiškai keisti failus (jau turėjau patirties sprendžiant tokias problemas naudojant Perl);
  • Taip pat naudokite grupės politiką, kad atnaujintumėte kliento nustatymus.

Failų rinkimas naudojant grupės politiką

Paprasčiausia dalis yra tai, kad kai klientas prisijungia prie savo profilio, jis su savo teisėmis paleidžia tam tikrą .bat failą, kuriame sakoma:

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

Taigi pacs.xml failai kaupsis serveryje paslėptame resurse, kurio pavadinime yra informacija, iš kurio kompiuterio ir iš kurio vartotojo ši konfigūracija buvo nukopijuota.

Sunkiausia buvo palaukti, kol ši politika pasiteisins visiems vartotojams.

Konfigūracijų keitimas naudojant Perl scenarijų

Mums reikės Aktyvus Perlas Windows iš ActiveState, taip pat XML::Writer modulį, kurį galima įdiegti naudojant komandą ppm įdiegti XML-Writer.

Pats scenarijus pasirodė gana paprastas:

use XML::Writer;
 
# Открываем папку с отчетами, обрабатываем ссписок (удаляем лишнее):
	$report_dir = "C:Perl64WORKPACS-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:Perl64WORKPACS-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);				
			}
	}
 
}

Jo veikimo principas:

  • Atidarome katalogą, kuriame surinkome pacs.xml konfigūracijas iš klientų, ir failų sąrašą įdedame į skaliarų masyvą (@report_files);
  • Ciklo metu apdorojame po vieną failą ir skaitome eilutę po eilutės;
  • Naudodami split, kiekvieną eilutę suskaidome į 5 dalis, naudodami kabutes kaip skyriklį;
  • Surandame eilutę su žodžiu klausytojas ir kiekvieno failo duomenis (AE kliento pavadinimą ir TCP prievado numerį) pateikiame į du kintamuosius;
  • Po to mes tiesiog sugeneruojame naują XML failą, įvedame į jį unikalius parametrus ir įdedame reikiamą skaičių PACS serverių su jų parametrais - tie. nuo ko viskas prasidėjo)
  • Perrašome naują XML failą ant senojo.

Reikia pastebėti, kad iš tikrųjų aš šio scenarijaus nenaudoju visiškai automatiškai – iš tikrųjų surinktas konfigūracijas nukopijuoju į atskirą katalogą ir tada paleidžiu scenarijų ir keičiu visas masiškai. Tada atsitiktinis patikrinimas - ir konfigūracijos gali būti paskirstytos atgal į mašinas.

Modifikuotų pacs.xml failų platinimas klientams

Paprasčiausias dalykas, kuris atėjo į galvą, buvo pakeisti jau veikiantį .bat failą, kuris renka konfigūracijas iš klientų, ir pridėti eilutę:

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

Galutinis .bat failas atrodo taip:

@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

išvada

Tai taip"kelio“ sprendimas. Jau bandėme du kartus (2018 rugsėjį ir 2019 vasarį), kol kas skrydis normalus. Žinoma, ne 100% klientų atnaujina, bet tai artima šiai vertei – visa kita atliekame nuotoliniu būdu. Scenarijaus autorius nuoroda.

Šaltinis: www.habr.com

Добавить комментарий