Vorgeschichte
In einer medizinischen Einrichtung wurden Lösungen auf Basis von PACS-Servern Orthanc und DICOM-Client Radiant implementiert. WÀhrend der Konfiguration stellte sich heraus, dass jeder DICOM-Client in den PACS-Servern wie folgt beschrieben werden muss:
- Client-Name
- AE-Name (muss einzigartig sein)
- TCP-Port, der automatisch auf der Client-Seite geöffnet wird und DICOM-Untersuchungen vom PACS-Server empfĂ€ngt (d.h. der Server schiebt sie quasi in Richtung Client â indem er die Verbindung zuerst initiiert)
- IP-Adresse
Nach der Konfiguration der Radiant-Clients erhielten wir folgende Informationen zum Nachdenken â bei jedem Client fĂŒhrte die Softwarekonfiguration mit den oben genannten Parametern zur Erstellung der Datei pacs.xml, die im Benutzerprofil gespeichert war (Pfad: %APPDATA%RadiantViewerpacs.xml). Dabei unterschied sich die Konfiguration eines Clients von der eines anderen mindestens in zwei Parametern (AE-Name war bei allen unterschiedlich, wĂ€hrend der Port hauptsĂ€chlich derselbe war, auĂer bei Terminal-Clients, die auf demselben Server arbeiteten â dort mussten die Ports ebenfalls unterschiedlich zugewiesen werden).
Beispiel einer pacs.xml-Datei laut :
Etwa ein halbes Jahr lang lief alles gut, das System funktionierte... und dann erfuhren wir von den âunterwasser Steinen»:
- Wir mĂŒssen mehrere neue PACS-Server in Betrieb nehmen, die die alten ersetzen (bei denen der Speicherplatz auf den Festplatten knapp wird). PACS-Server in virtuellen Maschinen, aber darum geht es hier nicht;
- Wir mĂŒssen irgendwo zentral die einzigartigen Konfigurationen (mit zwei unterschiedlichen Parametern) auf 200 Maschinen Ă€ndern (deren Anzahl regelmĂ€Ăig zunahm);
- Angesichts des Wachstums des Volumens der Untersuchungen brauchen wir eine Lösung, die nicht nur einmalig, sondern skalierbar und regelmĂ€Ăig ist (z.B. einmal alle 3-5 Monate).
Die Lösung finden Sie unten.
Auswahl der Werkzeuge zur Lösung der Aufgabe
ZunĂ€chst gab es Versuche, eine Lösung zu finden, die auf der Client-Seite die Datei pacs.xml Ă€nderte und die Ănderungen in die Liste der PACS-Server einfĂŒgte, ohne die Einstellungen des AE-Namens und des TCP-Ports zu berĂŒhren. Zu diesem Zeitpunkt liefen die Windows-Clients sowohl auf Windows XP als auch auf Windows 7 â daher gab es Versuche, etwas auf der Basis von VBScript zu schreiben. Aber leider â ich konnte diese Aufgabe nicht meistern, da ich keinerlei Erfahrung im Schreiben von komplexen und umfangreichen Dingen in dieser Sprache hatte. Auch die Versuche, etwas zu finden und umzuschreiben, waren nicht von Erfolg gekrönt (hier muss ich anmerken, dass ich bereits einen anderen Plan im Kopf hatte, weshalb ich nicht lĂ€nger als 3-4 Stunden mit VBScript experimentiert habe).
SchlieĂlich entschied ich mich fĂŒr die folgende Lösung:
- Alle Dateien pacs.xml mithilfe von Gruppenrichtlinien an einem Ort auf einem Server in einer Netzwerkressource zusammenzufĂŒhren;
- Die Dateien maschinell zu Ă€ndern (ich hatte bereits Erfahrung mit solchen Aufgaben â mit Perl);
- ZusĂ€tzlich sollten die Client-Einstellungen ebenfalls ĂŒber Gruppenrichtlinien aktualisiert werden.
Dateisammlung mit Hilfe von Gruppenrichtlinien
Der einfachste Teil â beim Einloggen des Clients in sein Profil fĂŒhrt er mit seinen Rechten eine bestimmte .bat-Datei aus, in der Folgendes steht:
echo off
If exist %APPDATA%RadiantViewerpacs.xml copy %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml
So werden auf dem Server in der versteckten Ressource Dateien pacs.xml gesammelt, deren Namen Informationen darĂŒber enthalten, von welchem Computer und welchem Benutzer die Konfiguration kopiert wurde.
Die gröĂte Herausforderung war es, zu warten, bis diese Richtlinie bei allen Benutzern wirksam wurde.
Ănderung der Konfigurationen mit Hilfe eines Perl-Skripts
Wir benötigen von ActiveState fĂŒr Windows sowie das Modul XML::Writer, das mit dem Befehl installiert werden kann ppm install XML-Writer.
Das Skript selbst ist ziemlich einfach geworden:
use XML::Writer;
# Ăffnen des Ordners mit Berichten, bearbeiten der Liste (ĂŒberflĂŒssiges entfernen):
$report_dir = "C:Perl64WORKPACS-xml3";
opendir(DIR, "$report_dir") or die "Kann den Ordner mit Berichten nicht öffnen!";
@report_files = readdir DIR;
shift (@report_files); # entfernt den Punkt aus den Array-Elementen (.)
shift (@report_files); # entfernt zwei Punkte aus den Array-Elementen (..)
# print "@report_files";
closedir(DIR);
# Beginnen mit der Verarbeitung der Dateien - eine nach der anderen. Es ist notwendig, den AET-Parameter und die Portnummer in Variablen zu lesen.
foreach $analiz_file (@report_files)
{
$full_path_to_file="C:Perl64WORKPACS-xml3".$analiz_file;
open (INFO, $full_path_to_file);
while ($line = )
{
# Die Variablen $aet und $port enthalten eindeutige Daten fĂŒr jede XML-Datei:
my ($other1, $aet, $other2, $port, $other3) = split /"/, $line, 5;
# Wenn die Zeile listener erscheint, haben wir die gewĂŒnschte Zeile erreicht und können ein neues XML erstellen:
if ($other1 =~ 'listener')
{
# Erstellen eines neuen XML mit den benötigten Feldern und Daten:
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');
# Speichern des fertigen XML in einer Variablen:
my $xml = $writer->end();
# Vorbereiten der Datei zum Ăberschreiben:
$rewritexml = $full_path_to_file;
# Schreiben der XML-Dateien mit neuen Daten:
open (NEWXML, "> $rewritexml");
print NEWXML $xml;
close (NEWXML);
}
}
}
Funktionsweise:
- Wir öffnen das Verzeichnis, in dem wir die pacs.xml-Konfigurationen von Kunden gesammelt haben, und fĂŒgen die Liste der Dateien in das Array der Skalare (@report_files) ein;
- Wir verarbeiten die Dateien in einer Schleife einzeln und lesen sie zeilenweise ein;
- Mit Hilfe von split zerlegen wir jede Zeile in 5 Teile und verwenden AnfĂŒhrungszeichen als Trennzeichen;
- Wir suchen die Zeile mit dem Wort listener und speichern die einzigartigen Daten fĂŒr jede Datei in zwei Variablen (AE-Name des Kunden und die TCP-Portnummer);
- Danach erstellen wir einfach eine neue XML-Datei, fĂŒgen die einzigartigen Parameter ein und fĂŒgen die erforderliche Anzahl an PACS-Servern mit ihren Parametern hinzu â d.h. der Grund, warum das alles erstellt wurde)
- Wir ĂŒberschreiben die neue XML-Datei mit der alten.
Es ist anzumerken, dass ich dieses Skript tatsĂ€chlich nicht vollstĂ€ndig automatisch benutze â im Grunde kopiere ich die gesammelten Konfigurationen in ein separates Verzeichnis und starte dann das Skript, um sie alle auf einmal zu Ă€ndern. Danach erfolgt eine stichprobenartige ĂberprĂŒfung â und die Konfigurationen können dann wieder auf die Maschinen verteilt werden.
Verbreitung der geÀnderten pacs.xml-Dateien an die Kunden
Das einfachste, was mir in den Sinn kam, war, die Ănderungen in eine bereits funktionierende .bat-Datei einzufĂŒgen, die die Konfigurationen von den Kunden sammelt, und eine Zeile hinzuzufĂŒgen:
If exist %APPDATA%RadiantViewerpacs.xml copy /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml
Die endgĂŒltige .bat-Datei sieht so aus:
@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
Fazit
So eine "Ad-hoc" Lösung. Wir haben es bereits zweimal getestet (im September 2018 und im Februar 2019), bisher lĂ€uft es gut. NatĂŒrlich aktualisiert es nicht 100 % der Kunden, aber es kommt dieser Zahl nahe â den Rest vervollstĂ€ndigen wir remote. Das Skript ist .
Quelle: habr.com
