PDA

Показать полную графическую версию : [решено] Автоматическое редактирование файла.config


Armsinglom
12-02-2017, 14:28
Добрый день.
Вообщем создал инсталятор которые распаковывает приложение в определенную папку. Приложение периодически обновляется (добавляются новые библиотеки и т.д.) в связи с чем в конфигурационный файлик добавляются новые строки. Так как приложение находится на разных объектах и имеет разные коммутационные настройки то запихнуть в инсталятор общий файлик конфигурации я не могу. Идея в том что бы при запуске инсталятора запускался как нибудь .bat или другое средство, который бы добавлял в тестовый фаил нужные строчки, при этом не трогая остальную часть файла.
Конфигурационный файл выглядит примерно так(маленькая часть):
<add key="SkipPreSelect" value="false" />
<add key="RefundLockTime" value="20" />
<add key="UseSverkaDiff" value="false" />
</appSettings>
т.е. новые параметры нужно добавлять между строк <add key="UseDiff" value="false" /> и </appSettings>, а так же учесть что если данные параметры есть то их трогать не нужно.
Подскажите каким способом это можно реализовать? и если есть готовые решения то я буду рад их принять:)
Заранее большое спасибо.

Iska
12-02-2017, 14:45
Вообщем создал инсталятор которые распаковывает приложение в определенную папку. »
Чем именно создавали?

добавлял в тестовый фаил нужные строчки, при этом не трогая остальную часть файла. »
Образец реального файла упакуйте в архив, каковой приложите к сообщению.

Конфигурационный файл выглядит примерно так(маленькая часть): »
Этого недостаточно. Сделайте то, что я прошу в предыдущем абзаце.

т.е. новые параметры »
Какие именно «новые параметры»?

Подскажите каким способом это можно реализовать? »
Надо полагать, конфигурационный файл — это xml-файл. Посему проще и надёжнее всего будет использовать WSH или PoSH (в случае отсутствия систем на XP и ниже).

Armsinglom
12-02-2017, 15:31
Чем именно создавали?
Smart Install Maker 5.04

Образец реального файла упакуйте в архив, каковой приложите к сообщению.
сделал. 143405

Какие именно «новые параметры»?
Они постоянно разные, предоставляются разработчиком, выглядят примерно так:
<add key="SkipPreSelect" value="false" />
<add key="RefundLockTime" value="20" />
<add key="UseSverkaDiff" value="false" />
и закрываются командой </appSettings>


Надо полагать, конфигурационный файл — это xml-файл. Посему проще и надёжнее всего будет использовать WSH или PoSH (в случае отсутствия систем на XP и ниже).
На точках Win7 32 битка. Доменных политик на данный момент нет, будут в не скором будущем.....

Armsinglom
13-02-2017, 10:33
Перефразирую немного что бы было понятнее, каким образом можно в текстовом файле добавить между строк
<add key="UseSverkaDiff" value="false" />
</appSettings>
добавить строчки
<add key="SkipPreSelect" value="false" />
<add key="RefundLockTime" value="20" />
что бы получилось :
<add key="UseSverkaDiff" value="false" />
<add key="SkipPreSelect" value="false" />
<add key="RefundLockTime" value="20" />
</appSettings>
Естественно что бы при этом не пострадала информация сверху и снизу данного файла, и в случае если на момент применения скрипта там были уже эти строчки то они просто заменились бы.

megaloman
13-02-2017, 16:05
Armsinglom, если данные параметры есть то их трогать не нужно.если на момент применения скрипта там были уже эти строчки то они просто заменились бы.Чему верить?Они постоянно разные, предоставляются разработчиком, выглядят примерно так:
<add key="SkipPreSelect" value="false" />
<add key="RefundLockTime" value="20" />
<add key="UseSverkaDiff" value="false" />
и закрываются командой </appSettings>
В каком виде они поставляются? В виде файла? Какая структура того, что поставляется? Или эти поставляемые строки будут Вами каким-то образом вбиты в скрипт для обновления имеющегося конфига?

Armsinglom
13-02-2017, 18:31
Armsinglom,
Цитата Armsinglom:
если данные параметры есть то их трогать не нужно.
Цитата Armsinglom:
если на момент применения скрипта там были уже эти строчки то они просто заменились бы.
Чему верить? »
Лучше заменять. так как информация может быть внесена ранее руками не корректно.

В каком виде они поставляются? В виде файла? Какая структура того, что поставляется? Или эти поставляемые строки будут Вами каким-то образом вбиты в скрипт для обновления имеющегося конфига? »
Всё верно, просто на почту приходит сообщение что нужно подкинуть пару новых библиотек и добавить в cfg новые параметры.
Вот и хотел бы автоматизировать наполнение файла cfg, так как обновляют третьи лица которым доверия нет, хотел как можно больше исключить человеческий фактор....

megaloman
13-02-2017, 20:47
var Conf = 'Z:\\Box_In\\cfg.Config'
var ConfOut = 'Z:\\Box_In\\cfg.Config'

var Snew = new Array (
' <add key="SkipPreSelect" value="kuku" />',
' <add key = "RefundLockTime" value="33" />',
' <add key = "iiiUseSverkaDiff" value="false" />'
);
var Send='</appSettings>';
var Skey='<add key';
var Skeyend='>';

var l=Snew.length;
var rn = String.fromCharCode(13,10);

var FSO,FConf,SConf;

FSO=WScript.CreateObject("Scripting.FileSystemObject");

FConf = FSO.OpenTextFile(Conf,1);
SConf = FConf.ReadAll();

FConf.Close();

while (SConf.indexOf(Skey+' ')>0) SConf = SConf.replace(Skey+' ',Skey);
while (SConf.indexOf(Skey+'= ')>0) SConf = SConf.replace(Skey+'= ',Skey+'=');

var Nend,NNend,SSnew,j,jfind,Tkey,Told;
NNend = SConf.indexOf(Send);

Nend = SConf.lastIndexOf(String.fromCharCode(13),NNend);
SSold = SConf.slice(Nend,NNend)+Send;

SSnew = SSold;
for (var i=l-1; i >=0; i--) {
while (Snew[i].indexOf(Skey+' ')>0) Snew[i] = Snew[i].replace(Skey+' ',Skey);
while (Snew[i].indexOf(Skey+'= ')>0) Snew[i] = Snew[i].replace(Skey+'= ',Skey+'=');

Tkey = Skey + '="';
j = Snew[i].lastIndexOf(Tkey);
Tkey = Snew[i].slice(j,Snew[i].indexOf('"',j+Tkey.length)+1);

jfind = SConf.indexOf(Tkey);
if (jfind<0) {
SSnew = rn+Snew[i]+SSnew;
} else {
Told = SConf.slice(jfind,SConf.indexOf(Skeyend,jfind)+1);
Tkey = Snew[i].slice(j,Snew[i].indexOf(Skeyend,j)+1);
SConf = SConf.replace(Told,Tkey);
// WScript.Echo(Told+rn+Tkey);
};
}
SConf = SConf.replace(SSold,SSnew);

FConf = FSO.CreateTextFile(ConfOut,2);
FConf.Write(SConf);

FConf.Close();
Ключи задаются массивом, их надо вбить вручную. Пробелы - это сделано для тестирования, они не нужны, но не вредны. Не забудьте прописать полный путь к исходному конфиг-файлу и изменённому. Они могут совпадать

Armsinglom
14-02-2017, 09:06
Спасибо огромное, работает как надо!!!!
Данный скрипт можно использовать в случае изменения параметра с true на false и наоборот, что не может не радовать...
Еще раз спасибо!!!

Armsinglom
14-02-2017, 15:02
megaloman не сочти за наглость, а можно этот скрипт заставить что бы он удалял все строки между
<add key="UseSverkaDiff" value="false" />
и
</appSettings>
и прописывал то что я укажу, т .е. не важно какие между этими строками были параметры и строки, он их затрёт и впишет нужные мне.

megaloman
14-02-2017, 17:45
var Conf = 'Z:\\Box_In\\cfg.Config'
var ConfOut = 'Z:\\Box_In\\cfg.Config'

var Snew = new Array (
' <add key="SkipPreSelect" value="tra la la" />',
' <add key="RefundLockTime" value="777" />',
' <add key="aaaRefundLockTime" value="111777" />',
' <add key="bbbRefundLockTime" value="222777" />',
' <add key="UseSverkaDiff" value="false" />'
);
var Sdel;
Sdel = '<add key="UseSverkaDiff"';
//Sdel = '<appSettings>';

var Send='</appSettings>';
var Skey='<add key';
var Skeyend='>';

var l=Snew.length;
var rn = String.fromCharCode(13,10);

var FSO,FConf,SConf;

FSO=WScript.CreateObject("Scripting.FileSystemObject");

FConf = FSO.OpenTextFile(Conf,1);
SConf = FConf.ReadAll();
FConf.Close();

while (SConf.indexOf(Skey+' ')>0) SConf = SConf.replace(Skey+' ',Skey);
while (SConf.indexOf(Skey+'= ')>0) SConf = SConf.replace(Skey+'= ',Skey+'=');

var Ndel = SConf.indexOf(Sdel);
Ndel = SConf.indexOf(String.fromCharCode(10),Ndel);

var Nend,NNend,SSnew,j,jfind,Tkey,Told;
NNend = SConf.indexOf(Send);
Nend = SConf.lastIndexOf(String.fromCharCode(13),NNend);

if (Ndel>=0) {
SConf = SConf.replace(SConf.slice(Ndel,Nend+1),'');
NNend = SConf.indexOf(Send);
Nend = SConf.lastIndexOf(String.fromCharCode(13),NNend);
}

SSold = SConf.slice(Nend,NNend)+Send;

SSnew = SSold;
for (var i=l-1; i >=0; i--) {
while (Snew[i].indexOf(Skey+' ')>0) Snew[i] = Snew[i].replace(Skey+' ',Skey);
while (Snew[i].indexOf(Skey+'= ')>0) Snew[i] = Snew[i].replace(Skey+'= ',Skey+'=');

Tkey = Skey + '="';
j = Snew[i].lastIndexOf(Tkey);
Tkey = Snew[i].slice(j,Snew[i].indexOf('"',j+Tkey.length)+1);

jfind = SConf.indexOf(Tkey);
if (jfind<0) {
SSnew = rn+Snew[i]+SSnew;
} else {
Told = SConf.slice(jfind,SConf.indexOf(Skeyend,jfind)+1);
Tkey = Snew[i].slice(j,Snew[i].indexOf(Skeyend,j)+1);
SConf = SConf.replace(Told,Tkey);
// WScript.Echo(Told+rn+Tkey);
};
}
SConf = SConf.replace(SSold,SSnew);

FConf = FSO.CreateTextFile(ConfOut,2);
FConf.Write(SConf);
FConf.Close();
Можно вообще убить всё в секции appSettings, если указать
Sdel = '<appSettings>'; (сейчас это закомментировано и не работает)
и заново вбить скриптом всё что нужно. Сейчас
Sdel = '<add key="UseSverkaDiff"';
Я не стал писАть как Вы указали: <add key="UseSverkaDiff" value="false" />
посчитал это избыточным. Но если Вам надо именно так - делайте.
Сначала делается удаление, а затем вставка (замена)

Armsinglom
14-02-2017, 18:22
ДА!!!, вот теперь всё как надо!!! Инсталлятор после распаковки автоматом внес все нужные изменения в cfg , отработало на 5+, все кривые строки и весь мусор почистило и аккуратненько укомплектовалось в cfg.
Спасибо огромное!!!
Тему закрываю.

Iska
24-02-2017, 02:16
Я по-прежнему считаю, что работать с xml следует средствами, для того предназначенными.

новые параметры нужно добавлять между строк <add key="UseDiff" value="false" /> и </appSettings>, а так же учесть что если данные параметры есть то их трогать не нужно. »
Я всё-таки полагаю, что «трогать» их нужно. Например, для того, чтобы задать указанные значения. Например:
Option Explicit

Dim objDictionary
Dim strSourceFile

Dim objFSO
Dim strKey
Dim objXMLDOMElement


Set objDictionary = WScript.CreateObject("Scripting.Dictionary")

With objDictionary
.Add "SkipPreSelect", "false"
.Add "RefundLockTime", "20"
.Add "UseSverkaDiff", "false"
End With

strSourceFile = "cfg.Config"

Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

If objFSO.FileExists(strSourceFile) Then
With WScript.CreateObject("Microsoft.XMLDOM")
.preserveWhiteSpace = True
.load strSourceFile

For Each strKey In objDictionary.Keys
Set objXMLDOMElement = .selectSingleNode("/configuration/appSettings/add[@key='" & strKey & "']")

If objXMLDOMElement Is Nothing Then
Set objXMLDOMElement = .createElement("add")
objXMLDOMElement.setAttribute "key", strKey
objXMLDOMElement.setAttribute "value", objDictionary.Item(strKey)
.selectSingleNode("/configuration/appSettings").appendChild objXMLDOMElement
Else
objXMLDOMElement.setAttribute "key", strKey
objXMLDOMElement.setAttribute "value", objDictionary.Item(strKey)
End If

Set objXMLDOMElement = Nothing
Next

objFSO.CopyFile strSourceFile, strSourceFile & ".bak", True

.save strSourceFile
End With
Else
WScript.Echo "Can't find source file [" & strSourceFile & "]."
WScript.Quit 1
End If

Set objFSO = Nothing

WScript.Quit 0

Если параметров нет — они будут добавлены, если есть — у них будут заданы указанные значения. Оригинальный файл будет сохранён с расширением .bak.

а можно этот скрипт заставить что бы он удалял все строки между
<add key="UseSverkaDiff" value="false" />
и
</appSettings>
и прописывал то что я укажу, т .е. не важно какие между этими строками были параметры и строки, он их затрёт и впишет нужные мне. »
Какой в этом смысл? А если там окажутся нужные узлы? В xml ведь, хоть порядок расположения и присутствует, но, фактически, не используется на практике. Тогда уж стоит удалять всё содержимое узла appSettings и задавать своё.

glukin
24-02-2017, 13:23
Iska, Подскажите, пожалуйста, чем Вы автоматизируете написание вот этого всего?

Option Explicit

Dim objDictionary
Dim strSourceFile

и так далее

Не руками же пишете все? Алгоритм, понятно, руками, а обертку? Вот эти все "WScript.CreateObject" и подобное?
ПС: только начинаю изучать скриптовые языки, перехожу с чистого С.

Iska
25-02-2017, 02:27
glukin, редактор Far Manager'а, SciTE. VBSEdit также весьма хорош (но не бесплатен). Главное, никогда не забывайте первой строкой в VBS писать «Option Explicit».

Весьма рекомендую Серый форум (http://forum.script-coding.com/) и коллекцию ссылок оттуда в: Windows Script Host: Коллекция ссылок (http://forum.script-coding.com/viewtopic.php?id=10), хоть многое на сайте Microsoft уже и убрали (скажем, всё, что было здесь (http://forum.script-coding.com/viewtopic.php?pid=10392#p10392), уже недоступно). Я думаю, что надо бы было выложить всё это куда-нибудь. Сделать какую-нибудь общую инсталляцию и выложить для общего пользования, потому как потребность у народа всё ещё есть.




© OSzone.net 2001-2012