Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Автоматическое редактирование файла.config (http://forum.oszone.net/showthread.php?t=323771)

Armsinglom 12-02-2017 14:28 2711135

Автоматическое редактирование файла.config
 
Добрый день.
Вообщем создал инсталятор которые распаковывает приложение в определенную папку. Приложение периодически обновляется (добавляются новые библиотеки и т.д.) в связи с чем в конфигурационный файлик добавляются новые строки. Так как приложение находится на разных объектах и имеет разные коммутационные настройки то запихнуть в инсталятор общий файлик конфигурации я не могу. Идея в том что бы при запуске инсталятора запускался как нибудь .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 2711142

Цитата:

Цитата Armsinglom
Вообщем создал инсталятор которые распаковывает приложение в определенную папку. »

Чем именно создавали?

Цитата:

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

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

Цитата:

Цитата Armsinglom
Конфигурационный файл выглядит примерно так(маленькая часть): »

Этого недостаточно. Сделайте то, что я прошу в предыдущем абзаце.

Цитата:

Цитата Armsinglom
т.е. новые параметры »

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

Цитата:

Цитата Armsinglom
Подскажите каким способом это можно реализовать? »

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

Armsinglom 12-02-2017 15:31 2711149

Вложений: 1
HTML код:

Чем именно создавали?
Smart Install Maker 5.04

HTML код:

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

HTML код:

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


HTML код:

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

Armsinglom 13-02-2017 10:33 2711356

Перефразирую немного что бы было понятнее, каким образом можно в текстовом файле добавить между строк
<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 2711446

Armsinglom,
Цитата:

Цитата Armsinglom
если данные параметры есть то их трогать не нужно.

Цитата:

Цитата Armsinglom
если на момент применения скрипта там были уже эти строчки то они просто заменились бы.

Чему верить?
Цитата:

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

Armsinglom 13-02-2017 18:31 2711486

Цитата:

Цитата megaloman
Armsinglom,
Цитата Armsinglom:
если данные параметры есть то их трогать не нужно.
Цитата Armsinglom:
если на момент применения скрипта там были уже эти строчки то они просто заменились бы.
Чему верить? »

Лучше заменять. так как информация может быть внесена ранее руками не корректно.

Цитата:

Цитата Armsinglom
В каком виде они поставляются? В виде файла? Какая структура того, что поставляется? Или эти поставляемые строки будут Вами каким-то образом вбиты в скрипт для обновления имеющегося конфига? »

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

megaloman 13-02-2017 20:47 2711527

Как вариант, написал на js, так как польстился на то, что имеется 2 варианта обозначения литерала
Код:

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 2711595

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

Armsinglom 14-02-2017 15:02 2711684

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

megaloman 14-02-2017 17:45 2711741

можно этот скрипт заставить чтобы он удалял все строки между
Код:

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 2711755

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

Iska 24-02-2017 02:16 2714367

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

Цитата:

Цитата Armsinglom
новые параметры нужно добавлять между строк <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.

Цитата:

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

Какой в этом смысл? А если там окажутся нужные узлы? В xml ведь, хоть порядок расположения и присутствует, но, фактически, не используется на практике. Тогда уж стоит удалять всё содержимое узла appSettings и задавать своё.

glukin 24-02-2017 13:23 2714404

Iska, Подскажите, пожалуйста, чем Вы автоматизируете написание вот этого всего?

Option Explicit

Dim objDictionary
Dim strSourceFile

и так далее

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

Iska 25-02-2017 02:27 2714544

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

Весьма рекомендую Серый форум и коллекцию ссылок оттуда в: Windows Script Host: Коллекция ссылок, хоть многое на сайте Microsoft уже и убрали (скажем, всё, что было здесь, уже недоступно). Я думаю, что надо бы было выложить всё это куда-нибудь. Сделать какую-нибудь общую инсталляцию и выложить для общего пользования, потому как потребность у народа всё ещё есть.


Время: 13:59.

Время: 13:59.
© OSzone.net 2001-