Thay đổi cài đặt chương trình trong khi lưu thông số cá nhân

thời tiền sử

Một tổ chức y tế đã triển khai các giải pháp dựa trên máy chủ Orthanc PACS và máy khách Radiant DICOM. Trong quá trình thiết lập, chúng tôi phát hiện ra rằng mỗi máy khách DICOM phải được mô tả trong máy chủ PACS như sau:

  • Tên khách hàng
  • Tên AE (phải là duy nhất)
  • Cổng TCP tự động mở ở phía máy khách và nhận các khảo sát DICOM từ máy chủ PACS (tức là máy chủ đẩy chúng về phía máy khách - bắt đầu kết nối trước)
  • Địa chỉ IP

Sau khi thiết lập Radiant, khách hàng nhận được thông tin cần suy nghĩ sau: đối với mỗi khách hàng, việc thiết lập phần mềm với các thông số trên dẫn đến tệp bị lấp đầy pacs.xml, nằm trong hồ sơ người dùng (đường dẫn: %APPDATA%RadiantViewerpacs.xml). Đồng thời, cấu hình của một máy khách khác với cấu hình khác ở ít nhất hai tham số (tên AE khác nhau đối với mọi người và cổng về cơ bản giống nhau, ngoại trừ các máy khách đầu cuối chạy trên cùng một máy chủ - ở đó các cổng cũng có được chỉ định khác nhau).

Ví dụ về tệp pacs.xml của liên kết:

Trong khoảng sáu tháng, mọi thứ đều ổn, hệ thống bắt đầu hoạt động... và sau đó nó đến với chúng tôi “dưới nước đá»:

  • Chúng ta cần đưa vào hoạt động một số máy chủ PACS mới để thay thế các máy chủ cũ (nơi dung lượng ổ đĩa đã bắt đầu hết). Máy chủ PACS trong máy ảo, nhưng đó không phải là điều chúng ta đang nói đến;
  • Chúng ta cần bằng cách nào đó thay đổi tập trung các cấu hình duy nhất (với hai tham số khác nhau) trên 200 máy (số lượng của chúng thường xuyên tăng lên);
  • Xét đến tốc độ tăng trưởng của khối lượng khảo sát, cần có giải pháp không chỉ một lần mà cần nhân rộng và thường xuyên (ví dụ 1-3 tháng một lần).

Giải pháp là dưới đây.

Lựa chọn công cụ để giải quyết vấn đề

Lúc đầu, đã có những nỗ lực tìm kiếm một số giải pháp có thể sửa đổi tệp pacs.xml ở phía máy khách và thực hiện các thay đổi đối với danh sách máy chủ PACS mà không ảnh hưởng đến cài đặt tên AE và cổng TCP. Các máy khách Windows vào thời điểm đó dựa trên cả Windows XP và Windows 7 - vì vậy đã có những nỗ lực viết một cái gì đó tương tự như thế này dựa trên VBScript. Nhưng than ôi, không thể thành thạo một nhiệm vụ như vậy, do hoàn toàn thiếu kinh nghiệm viết bất cứ thứ gì phức tạp và toàn diện bằng ngôn ngữ này. Những nỗ lực tìm kiếm và viết lại cũng không thành công (cần lưu ý rằng trong đầu tôi đã có sẵn một kế hoạch khác nên tôi đã không loay hoay với VBScript quá 3-4 giờ).

Cuối cùng tôi đã giải quyết được giải pháp sau:

  • Sử dụng chính sách nhóm, thu thập tất cả các tệp pacs.xml ở một nơi trên bất kỳ máy chủ nào trong tài nguyên mạng;
  • Thay đổi tập tin hàng loạt (tôi đã có kinh nghiệm giải quyết những vấn đề như vậy bằng Perl);
  • Đồng thời sử dụng chính sách nhóm để cập nhật cài đặt máy khách.

Thu thập tệp bằng Chính sách nhóm

Phần đơn giản nhất là khi khách hàng đăng nhập vào hồ sơ của mình, anh ta với quyền của mình sẽ thực thi một tệp .bat nhất định, trong đó nêu rõ:

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

Do đó, các tệp pacs.xml sẽ tích lũy trên máy chủ trong một tài nguyên ẩn, tên của tài nguyên này chứa thông tin từ máy tính nào và từ người dùng nào mà cấu hình này đã được sao chép.

Điều khó khăn nhất là phải đợi cho đến khi chính sách này có hiệu lực đối với tất cả người dùng.

Thay đổi cấu hình bằng tập lệnh Perl

Chúng tôi sẽ cần Hoạt động Perl dành cho Windows từ ActiveState, cũng như mô-đun XML::Writer, có thể được cài đặt bằng lệnh ppm cài đặt XML-Writer.

Bản thân kịch bản hóa ra khá đơn giản:

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

Nguyên lý hoạt động của nó:

  • Chúng tôi mở thư mục mà chúng tôi đã thu thập cấu hình pacs.xml từ máy khách và đặt danh sách tệp vào một mảng vô hướng (@report_files);
  • Trong một vòng lặp, chúng tôi xử lý từng tệp một và đọc từng dòng một;
  • Sử dụng tính năng chia tách, chúng tôi chia mỗi dòng thành 5 phần, sử dụng dấu ngoặc kép làm dấu phân cách;
  • Chúng tôi tìm một dòng có trình nghe từ và đặt dữ liệu duy nhất cho mỗi tệp (tên máy khách AE và số cổng TCP) vào hai biến;
  • Sau đó, chúng tôi chỉ cần tạo một tệp XML mới, nhập các tham số duy nhất vào đó và sau đó chèn số lượng máy chủ PACS cần thiết cùng với các tham số của chúng - những thứ kia. tất cả bắt đầu vì cái gì)
  • Chúng tôi viết lại tệp XML mới lên trên tệp cũ.

Cần lưu ý rằng trên thực tế, tôi không sử dụng tập lệnh này hoàn toàn tự động - thực tế, tôi sao chép các cấu hình đã thu thập vào một thư mục riêng rồi chạy tập lệnh và thay đổi tất cả chúng. Tiếp theo, kiểm tra ngẫu nhiên - và các cấu hình có thể được phân phối trở lại máy.

Phân phối các tệp pacs.xml đã sửa đổi cho khách hàng

Điều đơn giản nhất tôi nghĩ đến là thực hiện các thay đổi đối với tệp .bat đang hoạt động để thu thập cấu hình từ máy khách và thêm dòng:

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

Tệp .bat cuối cùng trông như thế này:

@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

Kết luận

Nó như thế này “đầu gối" giải pháp. Chúng tôi đã thử 2018 lần (vào tháng 2019 năm 100 và tháng XNUMX năm XNUMX), đến nay chuyến bay vẫn diễn ra bình thường. Tất nhiên, không phải XNUMX% khách hàng cập nhật, nhưng nó gần với giá trị này - chúng tôi hoàn thành phần còn lại từ xa. Kịch bản bởi liên kết.

Nguồn: www.habr.com

Thêm một lời nhận xét