Změna nastavení programu při ukládání osobních parametrů

pravěk

Jedna lékařská organizace implementovala řešení založená na serverech Orthanc PACS a klientovi Radiant DICOM. Během nastavování jsme zjistili, že každý DICOM klient musí být na serverech PACS popsán následovně:

  • Jméno klienta
  • Název AE (musí být jedinečný)
  • TCP port, který se automaticky otevírá na straně klienta a přijímá průzkumy DICOM ze serveru PACS (tj. server je posouvá směrem ke klientovi – nejprve zahájí připojení)
  • IP adresa

Po nastavení Radiantu dostali klienti následující podněty k zamyšlení: pro každého klienta nastavení softwaru s výše uvedenými parametry vedlo k naplnění souboru pacs.xml, který byl umístěn v uživatelském profilu (cesta: %APPDATA%RadiantViewerpacs.xml). Zároveň se konfigurace jednoho klienta od druhého lišila minimálně ve dvou parametrech (název AE je u každého jiný a port je v podstatě stejný, kromě terminálových klientů běžících na stejném serveru - tam měly porty také být přiřazen jinak).

Příklad souboru pacs.xml od odkaz:

Asi šest měsíců bylo vše v pořádku, systém začal fungovat... a pak nám to došlo “pod vodou kameny»:

  • Potřebujeme zprovoznit několik nových PACS serverů, které nahradí ty staré (kde již začal docházet diskový prostor). PACS servery ve virtuálních strojích, ale to není to, o čem mluvíme;
  • Potřebujeme nějak centrálně změnit unikátní konfigurace (se dvěma různými parametry) na 200 strojích (jejich počet se pravidelně zvyšoval);
  • Vzhledem k rychlosti růstu objemů průzkumů je potřeba řešení nejen jednorázově, ale replikovat a pravidelně (například jednou za 1–3 měsíců).

Řešení je uvedeno níže.

Výběr nástrojů k vyřešení problému

Nejprve byly pokusy najít nějaké řešení, které by upravilo soubor pacs.xml na straně klienta a provedlo změny v seznamu serverů PACS bez ovlivnění názvu AE a nastavení TCP portu. Klienti Windows v té době byli založeni jak na Windows XP, tak na Windows 7 – byly tedy pokusy něco takového napsat na základě VBScriptu. Ale bohužel, nebylo možné zvládnout takový úkol, kvůli naprostému nedostatku zkušeností s psaním čehokoli složitého a komplexního v tomto jazyce. Pokusy o nalezení a přepsání byly také neúspěšné (nutno podotknout, že už jsem měl v hlavě jiný plán, takže jsem se s VBScriptem nehrabal déle než 3-4 hodiny).

Nakonec jsem se rozhodl pro následující řešení:

  • Pomocí zásad skupiny shromážděte všechny soubory pacs.xml na jednom místě na libovolném serveru v síťovém prostředku;
  • Hromadně měňte soubory (již jsem měl zkušenosti s řešením takových problémů pomocí Perlu);
  • K aktualizaci nastavení klienta použijte také zásady skupiny.

Shromažďování souborů pomocí zásad skupiny

Nejjednodušší na tom je, že když se klient přihlásí do svého profilu, se svými právy spustí určitý .bat soubor, který říká:

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

Soubory pacs.xml se tedy budou hromadit na serveru ve skrytém zdroji, jehož název obsahuje informace, ze kterého počítače a od kterého uživatele byla tato konfigurace zkopírována.

Nejtěžší bylo počkat, až tato politika bude fungovat pro všechny uživatele.

Změna konfigurací pomocí skriptu Perl

Budeme potřebovat Aktivní Perl pro Windows od ActiveState a také modul XML::Writer, který lze nainstalovat pomocí příkazu ppm instalace XML-Writer.

Samotný skript se ukázal být docela jednoduchý:

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);				
			}
	}
 
}

Princip jeho fungování:

  • Otevřeme adresář, ve kterém jsme shromáždili konfigurace pacs.xml od klientů, a umístíme seznam souborů do pole skalárů (@report_files);
  • Ve smyčce zpracováváme vždy jeden soubor a čteme jej řádek po řádku;
  • Pomocí rozdělení rozdělíme každý řádek na 5 částí, přičemž jako oddělovač použijeme uvozovky;
  • Najdeme řádek se slovem posluchač a umístíme data jedinečná pro každý soubor (název klienta AE a číslo portu TCP) do dvou proměnných;
  • Poté jednoduše vygenerujeme nový XML soubor, zadáme do něj unikátní parametry a následně vložíme požadovaný počet PACS serverů s jejich parametry - těch. čím to všechno začalo)
  • Nový soubor XML přepíšeme na starý soubor.

Nutno podotknout, že ve skutečnosti tento skript nepoužívám úplně automaticky – ve skutečnosti nasbírané configy zkopíruji do samostatného adresáře a následně skript spustím a všechny hromadně změním. Dále náhodná kontrola - a konfigurace mohou být distribuovány zpět do strojů.

Distribuce upravených souborů pacs.xml klientům

Nejjednodušší věc, která mě napadla, bylo provést změny v již fungujícím souboru .bat, který shromažďuje konfigurace od klientů, a přidat řádek:

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

Výsledný soubor .bat vypadá takto:

@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

Závěr

Je to jako tohle "koleno" řešení. Už jsme to zkoušeli dvakrát (v září 2018 a únoru 2019), zatím je let normální. Neaktualizuje se samozřejmě 100 % klientů, ale této hodnotě se to blíží – zbytek doděláváme na dálku. Autor scénáře odkaz.

Zdroj: www.habr.com

Přidat komentář