<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; WSH: Скрипт автообновления приложения]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=7214</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=7214&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «WSH: Скрипт автообновления приложения».]]></description>
		<lastBuildDate>Tue, 04 Dec 2012 07:12:16 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: WSH: Скрипт автообновления приложения]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=66553#p66553</link>
			<description><![CDATA[<p>Была аналогичная задача, правда приложение было клиентское и файл(adp) в локалке.</p><p>Ярлык для запуска проекта вёл на скрипт. Скрипт проверял версию файла на сервере(текстовик с датой в формате yyyymmddvv, vv - версия в течении дня, на всякий случай). Если число было больше чем в локальном файле с версией, то загружался с перезаписью обновлённый adp-файл(плюс локальный файл с версией обновлялся), после чего он открывался в акцесе.</p><p>Ко всему выше перечисленному была простыня по работе с файлами, протоколированию в журнал, определению доступной версии акцесса, защите от дурака, созданию дерева каталогов(при первом запуске скрипта), правке настроек безопасности макросов и т.п. В общем, переписать бы всё заново - есть места в которых я сам уже не помню зачем там именно &quot;это&quot; делается...&nbsp; С другой стороны, уже лет 5 работает с минимальными доработками, поэтому мотивации на переделку(подумываю о vb.net) мало - нужно усовершенствовать, а гениальных идей на этот счёт нет. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p><p>З.Ы. если нужно, могу выложить(хотя, наверно, краснеть придётся за код - тогда как раз осваивал vbs).</p>]]></description>
			<author><![CDATA[null@example.com (BeS Yara)]]></author>
			<pubDate>Tue, 04 Dec 2012 07:12:16 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=66553#p66553</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: Скрипт автообновления приложения]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=65915#p65915</link>
			<description><![CDATA[<p>Написал сам, скрипт под мою действующую задачу как есть.</p><div class="codebox"><pre><code>var CreateObject = function (ProgId) { return WScript.CreateObject(ProgId)};

var FSO = new ActiveXObject(&quot;Scripting.FileSystemObject&quot;);
var WSHShell = new ActiveXObject(&quot;Wscript.Shell&quot;);
var WshNetwork = new ActiveXObject(&quot;WScript.Network&quot;);

// ***** todo: путь брать из текущей папки
var strAppRootPath = WSHShell.CurrentDirectory+&#039;\\vfs&#039;;
var strUpdatePath = strAppRootPath+&quot;\\updates&quot;;
var strSourcePath = strUpdatePath+&quot;\\source&quot;;
var strBackupPath = strUpdatePath+&quot;\\backup&quot;;
var strLogPath = strAppRootPath+&quot;\\log&quot;;

var strUpdateFileName = &quot;vfs.rar&quot;;

var intCycles = 0;

var E;

var DebugMode = false;

var objVFS = 0;
var obj1 = 0;

var objVFSStatus = 0;
var obj1Status = 0;


// ***** functions begin

function Exec(strCommand, intMaxTimer, intTimerValue) {
    var    ExecObject;
    var intTimer = 0;

    if (!intTimerValue)    {
        intTimerValue = 1000;
    }

    if (!intMaxTimer) {
        intMaxTimer = 24*60*60;
    }

    try    {
        ExecObject = WSHShell.Exec(strCommand);

        while (ExecObject.status == 0) {
            
            WScript.Sleep(intTimerValue);

            intTimer++;

            if (intTimer &gt;= intMaxTimer) {
                ExecObject.Terminate();
                return -2;
            }
        }

    }
    catch (E) {
        Log(&quot;Exec() ошибка выполнения &quot;+E.code);

        ExecObject = null;

        return false;
    }

    try {
        return ExecObject.ExitCode;
    }
    finally {
        ExecObject = null;
    }
} // Exec()


function DeleteFiles(strPath) {
    try {
        with (FSO.GetFolder(strPath)) {
            var eFiles = new Enumerator(Files),
                eSubs = new Enumerator(Subfolders),
                itm;

            for (; !eFiles.atEnd(); eFiles.moveNext()) {
                itm = eFiles.item();

    //            WScript.echo(itm.Path + &quot;.....удалено&quot;);
                itm.Attributes = 0;
                itm.Delete();
            }

            for (; !eSubs.atEnd(); eSubs.moveNext()) {
                itm = eSubs.item();

                DeleteFiles(itm.Path);

    //            WScript.echo(itm.Path + &quot;.....удалено&quot;);

                if (itm.Size == 0) {
                    itm.Attributes = 0;
                    itm.Delete();
                }
            }
        }
    }
    catch (E) {
        return false;
    }

    return true;
} // DeleteFiles()


function UpdateFilesWithBackup(strSubPath) {
    var fBackup;

    if (!strSubPath) { strSubPath=&quot;&quot;; }

    Log(&quot;UpdateFilesWithBackup=&quot;+strSourcePath+strSubPath);

    try {
        with (FSO.GetFolder(strSourcePath+strSubPath)) {
            var eFiles = new Enumerator(Files),
                eSubs = new Enumerator(Subfolders),
                itm;

            for (; !eFiles.atEnd(); eFiles.moveNext()) {
                itm = eFiles.item();

                try {
                    fBackup = FSO.GetFile(strAppRootPath+&quot;\\&quot;+strSubPath+&quot;\\&quot;+itm.Name);
                }
                catch (E) {}

                // делаем бакап
                if (fBackup) {
                    Log(strBackupPath+strSubPath+&quot;\\&quot;+itm.Name+&quot; - backup&quot;);
                    fBackup.Copy(strBackupPath+strSubPath+&quot;\\&quot;+itm.Name, true);
                }

                // обновляем
                Log(strAppRootPath+&quot;\\&quot;+strSubPath+&quot;\\&quot;+itm.Name+&quot; - обновляем&quot;);
                itm.Copy(strAppRootPath+&quot;\\&quot;+strSubPath+&quot;\\&quot;+itm.Name, true);
            }

            for (; !eSubs.atEnd(); eSubs.moveNext()) {
                itm = eSubs.item();

                try {
                    Log(&quot;CreateFolder in approot = &quot;+strAppRootPath+&quot;\\&quot;+itm.Name);
                    FSO.CreateFolder(strAppRootPath+&quot;\\&quot;+strSubPath+&quot;\\&quot;+itm.Name);
                }
                catch (E) {
                    // папки не существует
                    Log(strAppRootPath+&quot;\\&quot;+strSubPath+&quot;\\&quot;+itm.Name+&quot;.....существует&quot;);
                }

                try {
                    Log(&quot;CreateFolder in backup = &quot;+strBackupPath+strSubPath+&quot;\\&quot;+itm.Name);
                    FSO.CreateFolder(strBackupPath+strSubPath+&quot;\\&quot;+itm.Name);
                }
                catch (E) {
                    // папки не существует
                    Log(strBackupPath+strSubPath+&quot;\\&quot;+itm.Name+&quot;.....существует&quot;);
                }

                if (!UpdateFilesWithBackup(strSubPath+&quot;\\&quot;+itm.Name)) {
                    return false;
                }
            }
        }
    }
    catch (E) {
        return false;
    }

    return true;
} // UpdateFilesWithBackup()


// ***** functions ends


function Update() {
    // ***** проверка файла обновления

    if (FSO.FileExists(strUpdatePath+&quot;\\&quot;+strUpdateFileName)) {
        if (Exec(WSHShell.CurrentDirectory+&quot;\\&quot;+&quot;rar.exe t \&quot;&quot;+strUpdatePath+&quot;\\&quot;+strUpdateFileName+&quot;\&quot;&quot;, 120) != 0) {
            Log(&quot;Ошибка выполнения rar test&quot;);

            // ***** todo: перезагрузить
        }
    }
    else {
        // по выходу запуститься приложение    
        return;
    }



    // ***** очистить папку от предыдущих файлов

    DeleteFiles(strSourcePath);


    // ***** распаковка в специальную папку

    if (Exec(WSHShell.CurrentDirectory+&quot;\\&quot;+&quot;rar.exe x \&quot;&quot;+strUpdatePath+&quot;\\&quot;+strUpdateFileName+&quot;\&quot; \&quot;&quot;+strSourcePath+&quot;\&quot;&quot;, 120) != 0) {
        Log(&quot;Ошибка выполнения rar extract&quot;);

        // ***** todo: перезагрузить
    }



    // ****** очистить папку backup

    if (!DeleteFiles(strBackupPath)) {
        // ***** todo: надо перезагрузиться
    }


    // ***** при обновлении файлов нужно создавать их резервную копию
    // ***** если обновление неудачно, то нужно возвращать зарезервированные файлы назад и выходить - пустить в перезагрузку

    if (!UpdateFilesWithBackup()) {
        // ***** восстанавливаем бакап: копируем папку backup в approot

        try {
            FSO.CopyFolder(strBackupPath, strAppRootPath, true);
        }
        catch(E) {
            // ***** todo: В перезагрузку
        }
    }


    // ***** todo: запуск update.js из распакованных (если такой имеется) с контролем errorlevel, если он неуспешный, то надо откатывать обновление

    // update.js не будет пока


    // ***** todo: удалить update.rar

    FSO.DeleteFile(strUpdatePath+&quot;\\&quot;+strUpdateFileName, true);

} // Update()


function Setup() {
    try {
        if (!FSO.FileExists(WSHShell.CurrentDirectory+&quot;\\1.exe&quot;)) {
            return false;
        }

        if (!FSO.FileExists(WSHShell.CurrentDirectory+&quot;\\vfs.exe&quot;)) {
            return false;
        }

        if (!FSO.FileExists(WSHShell.CurrentDirectory+&quot;\\rar.exe&quot;)) {
            return false;
        }

        if (!FSO.FolderExists(strLogPath)) {
            FSO.CreateFolder(strLogPath);
        }

        if (!FSO.FolderExists(strUpdatePath)) {
            FSO.CreateFolder(strUpdatePath);
        }

        if (!FSO.FolderExists(strSourcePath)) {
            FSO.CreateFolder(strSourcePath);
        }

        if (!FSO.FolderExists(strBackupPath)) {
            FSO.CreateFolder(strBackupPath);
        }
    }
    catch(E) {

        Log(&#039;Setup(): runtime error&#039;);

        return false;
    }

    return true;
} // Setup


function _GetLeadingZero(Value) {
    return (Value &gt; 9) ? &quot;&quot; + Value : &quot;0&quot; + Value;
} // _GetLeadingZero()


function Log(strMessage, strURL, strLine) {
        try {
            var strAlertMessage = &quot;&quot;;
            var LogFile; 
            var LogFileName = strLogPath+&quot;\\&quot;;
            var DateObject = new Date();
            var strDateTime = _GetLeadingZero(DateObject.getDate())+&quot;.&quot;+_GetLeadingZero(DateObject.getMonth()+1)+
             &quot; &quot;+_GetLeadingZero(DateObject.getHours())+&quot;:&quot;+_GetLeadingZero(DateObject.getMinutes())+&quot;:&quot;+
             _GetLeadingZero(DateObject.getSeconds());

            strLine = (strLine == undefined) ? &quot;&quot; : &quot;: &quot;+strLine;

            strAlertMessage += &quot;ОШИБКА ИСПОЛНЕНИЯ\n\n&quot;;
//            strAlertMessage += &quot;\nURL: &quot;+strURL;
//            strAlertMessage += &quot;\nСтрока&quot;+strLine;
            strAlertMessage += &quot;\n\n&quot;+strMessage;

            LogFileName += &quot;vp&quot;+_GetLeadingZero(DateObject.getMonth()+1)+&quot;&quot;+_GetLeadingZero(DateObject.getDate())+&quot;.txt&quot;;

            if (FSO.FileExists(LogFileName)) {
                LogFile = FSO.OpenTextFile(LogFileName, 8, true);
            }
            else {
                LogFile = FSO.CreateTextFile(LogFileName, false);
            }

            LogFile.WriteLine(&quot;! &quot;+strDateTime+&quot; [&quot;+WshNetwork.ComputerName+&quot;:&quot;+WshNetwork.UserName+&quot;]&quot;+
             &quot; -&quot;+
             &quot; &quot;+strURL+strLine+
             &quot; - &quot;+strMessage);

            LogFile.Close();

            if (DebugMode) {
                try {
                    WScript.Echo(strAlertMessage);
                }
                catch(e) {}
            }
    }
    catch(E) {
        if (DebugMode) {
            try {
                WScript.Echo(&quot;ошибка выполнения Log().&quot;+
                  &quot; Название ошибки: &quot;+E.name+&quot;.&quot;+
                  &quot; Сообщение ошибки: &quot;+E.message+&quot;.&quot;+
                  &quot; Описание ошибки: &quot;+E.description+&quot;.&quot;);
            }
            catch(e) {}
        }
    }

    LogFile = null;
    DateObject = null;

    return true;
}



// ***** main


/*

todo:

- как сообщать на сервер ошибки обновления?

- надо считать кол-во привентивных перезагрузок и останавливать процесс, если они повторились Х раз

- освобождение памяти объектов

// ***** иначе нужно определить, может быть компьютер находится в стадии перезагрузки/завершения сеанса и тогда ничего делать не надо
// ***** если нет - запустить приложение заново, возможно это был несанкционированный выход (runtime error).
// ***** после выхода из приложения надо завершить 1.exe

*/

Log(&quot;Запуск&quot;);

if (!Setup()) {
    Log(&quot;Ошибка окружения&quot;);
    WScript.Quit();
}


// ****** todo: цикл на перезапуски приложений
while (true) {
    intCycles++;

    Update();

    Log(&#039;vfs start&#039;);
    try    {
        objVFS = WSHShell.Exec(WSHShell.CurrentDirectory+&quot;\\vfs.exe&quot;);
    }
    catch (E) {
        Log(&#039;Ошибка запуска&#039;);
    }
    
    WScript.Sleep(5*1000);

    Log(&#039;1 start&#039;);
    try {
        obj1 = WSHShell.Exec(WSHShell.CurrentDirectory+&quot;\\1.exe&quot;);
    }
    catch (E) {
        Log(&quot;Ошибка выполнения 1.exe&quot;+E.code);
    }

    WScript.Sleep(5*1000);

    while (true) {
        // цикл ожидания выхода из приложений
        WScript.Sleep(500);

        objVFSStatus = objVFS.Status;
        obj1Status = obj1.Status;

        if (obj1Status != 0) {
            Log(&#039;obj1.ExitCode =&#039;+obj1.ExitCode);

            try {
                objVFS.Terminate();
            }
            catch(E) {}

            Log(&#039;VFS terminate&#039;);

            // ***** todo: 1 перезапустился в другой ProcessID, надо найти его и далее использовать

            break;
        }

        if (objVFSStatus != 0) {
            Log(&#039;objVFS.ExitCode=&#039;+objVFS.ExitCode);

            try {
                obj1.Terminate();
            }
            catch(E) {}

            Log(&#039;1 terminate&#039;);

            if (objVFS.ExitCode == 99) {
                Log(&#039;Завершение работы вручную&#039;);
                WScript.Quit();
            }

            break;
        }
    } //status executed apps

} // main


/*

// ***** todo: принудительный перезапуск эмулятора и 1
// но надо отслеживать, что 1 сам может перезапуститься и тогда его объектом нельзя будет
// управлять, соответственно надо выходить из 1 другим способом

    if (Exec(strAppRootPath+&quot;\\&quot;+&quot;Emulator.exe&quot;) == 100) {
        // ***** после завершения приложения по errorlevel=100, которое означает
        // надо обновиться запускается процесс обновления
        // Плюс, надо прервать выполнение 1.exe

        if (obj1 == 0)    {
            continue;
        }
        else {
            onj1.Terminate();
            WScript.Sleep(1000);

            continue;
        }
    }

*/
//}



// ***** todo: запустить приложение, запустить 1.exe

Log(&quot;Выход&quot;);</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (plr)]]></author>
			<pubDate>Wed, 21 Nov 2012 07:23:17 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=65915#p65915</guid>
		</item>
		<item>
			<title><![CDATA[WSH: Скрипт автообновления приложения]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=60312#p60312</link>
			<description><![CDATA[<p>Есть приложение (бинарное), оно периодически обновляется, новая версия в Интернет. Приложение работает без участия пользователя и пользователь не должен принимать участие в его работе и, соответственно, работе обновления.</p><p>Проверка и загрузка обновлений будет реализована в приложении, а вот процесс обновления думаю реализовать на WSH, чтобы не заниматься хитростями самообновления и т.п. в любом случае нужен второй процесс, который обновляет файл приложения, так пусть им будет скрипт.</p><p>Алгоритм примерно следующий:</p><p>1. Проверили новую версию, если она есть, то приложение его загрузило и завершает свою работу.<br />2. Старт приложения реализуется через WSH-скрипт, который после выхода проверяет наличие загруженных обновлений и начинает обновлять файл с резервированием, проверками и т.п.<br />3. Приложение перезапускается.</p><p>Вроде бы несложно, но может быть кто-нибудь уже реализовывал подобный велосипед - укажите пжлст.</p>]]></description>
			<author><![CDATA[null@example.com (plr)]]></author>
			<pubDate>Mon, 14 May 2012 11:40:30 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=60312#p60312</guid>
		</item>
	</channel>
</rss>
