Änderung der Programmparameter mit Beibehaltung der persönlichen Einstellungen

Hintergrund

In einer medizinischen Einrichtung wurden Lösungen basierend auf Orthanc PACS-Servern und dem DICOM-Client Radiant implementiert. Bei der Konfiguration stellte sich heraus, dass jeder DICOM-Client in den PACS-Servern wie folgt beschrieben werden muss:

  • Kundenname
  • 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 schickt sie an den Client – initiiert die Verbindung zuerst)
  • IP-Adresse

Nach der Konfiguration der Radiant-Clients erhielten wir folgende Überlegungen – bei jedem Client führte die Softwarekonfiguration mit den oben genannten Parametern zur Erstellung einer Datei pacs.xml, die sich im Benutzerprofil befand (Pfad: %APPDATA%RadiantViewerpacs.xml). Dabei unterschied sich die Konfiguration eines Clients von einem anderen mindestens durch zwei Parameter (AE-Namen sind bei allen unterschiedlich, der Port ist im Allgemeinen identisch, außer bei Terminal-Clients, die auf demselben Server arbeiten – dort mussten die Ports ebenfalls unterschiedlich zugewiesen werden).

Beispiel für die Datei pacs.xml über diesen Link verfügbar:

Etwa ein halbes Jahr lief alles gut, das System funktionierte… und dann erfuhren wir von den „untergründigen Steinen»:

  • Wir müssen mehrere neue PACS-Server in Betrieb nehmen, die die alten ersetzen (wo der Speicherplatz auf den Festplatten zur Neige geht). Es handelt sich um PACS-Server in virtuellen Maschinen, aber darum geht es hier nicht;
  • Wir müssen irgendwie zentral die einzigartigen Konfigurationen (mit zwei unterschiedlichen Parametern) auf 200 Maschinen ändern (deren Anzahl hat sich regelmäßig erhöht);
  • Angesichts des Wachstums der Untersuchungsvolumina ist eine einmalige Lösung nicht ausreichend, sondern muss wiederholbar und regelmäßig sein (zum Beispiel alle 3-5 Monate).

Die Lösung finden Sie unten.

Auswahl der Werkzeuge für die 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 dabei die Liste der PACS-Server aktualisierte, ohne die Einstellungen des AE-Namens und des TCP-Ports zu berühren. Zu diesem Zeitpunkt basierten die Windows-Clients sowohl auf Windows XP als auch auf Windows 7 – daher gab es Bestrebungen, etwas auf Basis von VBScript zu entwickeln. Doch leider gelang es mir nicht, diese Aufgabe erfolgreich zu meistern, da es mir an Erfahrung im Schreiben komplexer und anspruchsvoller Skripte in dieser Sprache mangelte. Die Versuche, eine andere Lösung zu finden und neu zu schreiben, blieben ebenfalls erfolglos (hier sei angemerkt, dass ich bereits einen anderen Plan im Kopf hatte, weshalb ich nicht länger als 3-4 Stunden an VBScript arbeitete).

Letztendlich entschied ich mich für die folgende Lösung:

  • Alle pacs.xml-Dateien durch Gruppenrichtlinien an einem Ort auf einem beliebigen Server im Netzwerkkresource zu sammeln;
  • Die Dateien gesammelt zu ändern (ich hatte bereits Erfahrung mit solchen Lösungen – unter Verwendung von Perl);
  • Die Client-Einstellungen ebenfalls mithilfe von Gruppenrichtlinien zu aktualisieren.

Sammlung von Dateien mittels Gruppenrichtlinien

Der einfachste Teil – beim Anmelden des Clients in seinem Profil wird ein gewisses .bat-Skript mit seinen Berechtigungen ausgeführt, in dem Folgendes festgelegt ist:

echo off
Wenn %APPDATA%RadiantViewerpacs.xml existiert, kopiere %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml

So werden auf dem Server in der versteckten Ressource die Dateien pacs.xml angesammelt, deren Namen Informationen darüber enthalten, von welchem Computer und Benutzer diese Konfiguration kopiert wurde.

Das Schwierigste war, darauf zu warten, dass bei allen Benutzern diese Richtlinie angewendet wurde.

Änderung der Konfigurationen mithilfe eines Perl-Skripts

Wir benötigen Active Perl unter Windows von ActiveState sowie das Modul XML::Writer, das mit dem Befehl installiert werden kann ppm install XML-Writer.

Das Skript selbst ist recht einfach geraten:

use XML::Writer;
 
# Wir öffnen den Ordner mit den Berichten und verarbeiten die Liste (überflüssige Einträge entfernen):
	$report_dir = "C:Perl64WORKPACS-xml3";
	opendir(DIR, "$report_dir") or die "Kann den Ordner mit den Berichten nicht öffnen!";
	@report_files = readdir DIR;
	shift (@report_files); # Entferne den Punkt aus den Arrayelementen (.)
	shift (@report_files); # Entferne die beiden Punkte aus den Arrayelementen (..)
#	print "@report_files";
	closedir(DIR);
 
# Wir beginnen mit der Verarbeitung der Dateien - eine nach der anderen. Wir müssen die Parameter AET und Port in Variablen einlesen.
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" auftaucht - dann haben wir die Zielzeile erreicht und können das neue XML erstellen:
		if ($other1 =~ 'listener')
			{
				# Neues XML mit den nötigen Feldern und Daten erstellen:
				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');
 
				# Das fertige XML in eine Variable speichern:
				my $xml = $writer->end();
				# Datei für das Überschreiben vorbereiten:
				$rewritexml = $full_path_to_file;
				# XML-Dateien mit neuen Daten überschreiben:
				open (NEWXML, "> $rewritexml");
				print NEWXML $xml;
				close (NEWXML);				
			}
	}
 
}

Funktionsprinzip:

  • Wir öffnen das Verzeichnis, in dem die pacs.xml-Konfigurationen unserer Kunden gesammelt sind, und speichern die Dateiliste in einem Array (@report_files);
  • Im Loop verarbeiten wir jede Datei einzeln und lesen sie zeilenweise ein;
  • Mit split zerlegen wir jede Zeile in 5 Teile, wobei wir Anführungszeichen als Trennzeichen verwenden;
  • Wir suchen die Zeile mit dem Wort listener und speichern die einzigartigen Daten für jede Datei in zwei Variablen (AE-Kundenname und TCP-Portnummer);
  • Danach erstellen wir einfach eine neue XML-Datei, fügen die einzigartigen Parameter ein und fügen die benötigte Anzahl von PACS-Servern mit deren Parametern hinzu - d.h. das, weshalb das Ganze ins Leben gerufen wurde.)
  • Wir überschreiben die neue XML-Datei über die alte.

Es sei erwähnt, dass ich dieses Skript nicht vollständig automatisch verwende – ich kopiere die gesammelten Konfigurationen in ein separates Verzeichnis und starte das Skript dann, um sie in einem Rutsch zu ändern. Danach erfolgt eine stichprobenartige Überprüfung – und die Konfigurationen können wieder auf die Maschinen verteilt werden.

Verteilung der geänderten pacs.xml-Dateien an die Kunden.

Eine der einfachsten Ideen war es, Änderungen an der bereits funktionierenden .bat-Datei vorzunehmen, die Konfigurationen von Clients sammelt, und eine Zeile hinzuzufügen:

Wenn %APPDATA%RadiantViewerpacs.xml existiert, kopieren Sie /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml

Die endgültige .bat-Datei sieht so aus:

@echo off
Wenn %APPDATA%RadiantViewerpacs.xml existiert, kopieren Sie %APPDATA%RadiantViewerpacs.xml srv.test.localpconfigs$pacs-%COMPUTERNAME%-%USERNAME%.xml
Wenn %APPDATA%RadiantViewerpacs.xml existiert, kopieren Sie /Y srv.test.localpconfigsnew$pacs-%COMPUTERNAME%-%USERNAME%.xml %APPDATA%RadiantViewerpacs.xml

Fazit

So ein „Bastellösung“ haben wir gefunden. 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 Clients, aber es ist nah dran – die restlichen erledigen wir remote. Das Skript befasst sich mit über diesen Link verfügbar.

Quelle: habr.com

Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster