<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; HTA & JScript: HTA as 64 bit in focus - запуск HTA как 64 bit в фокусе]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=15760&amp;type=atom" />
	<updated>2020-11-01T13:25:54Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=15760</id>
		<entry>
			<title type="html"><![CDATA[Re: HTA & JScript: HTA as 64 bit in focus - запуск HTA как 64 bit в фокусе]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=143075#p143075" />
			<content type="html"><![CDATA[<p>Дальнейшее исследование позволило устранить возможное мерцание плитки приложения на панели задач во время его запуска.<br />Обновленную версию скрипта вы можете найти на моем сайте.<br />Подробности о возникновении мерцания разобраны в теме <a href="http://forum.script-coding.com/viewtopic.php?id=15788">HTA &amp; JScript: HTA silent stop and close - тихая остановка и закрытие</a>.</p>]]></content>
			<author>
				<name><![CDATA[lifeflame]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=40203</uri>
			</author>
			<updated>2020-11-01T13:25:54Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=143075#p143075</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA & JScript: HTA as 64 bit in focus - запуск HTA как 64 bit в фокусе]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=143023#p143023" />
			<content type="html"><![CDATA[<p>Дальнейшее исследование показало, что необходимая для сохранения фокуса пауза перед вызовом &quot;w.document.Script.close();&quot; коррелирует с ожиданием &quot;document.body&quot; во время динамического построения.<br />Таким образом, можно обойтись без нее, если провести предварительное создание &quot;document.body&quot; принудительно:</p><div class="codebox"><pre><code>
for(var ws = O(&#039;Shell.Application&#039;).Windows(), i = ws.Count; i -- &gt; 0;)
    if((w = ws.Item(i)) &amp;&amp; w.id == env(&#039;is64bit&#039;))
    {
        PID = w.PID;
        w.document.Script.WSS.AppActivate(PID);     //using &quot;WScript.Shell&quot; in focus to activate
                                                       //the application window of 64 bit HTA instance;
                                                       //remember that &quot;WScript.Shell&quot; should be
                                                       //in focus in order &quot;AppActivate&quot; to work properly
        break;
    }

document.write(&#039;&lt;body&gt;&#039;);                           //obtaining body
if(w &amp;&amp; w.id == env(&#039;is64bit&#039;))
    w.document.Script.close();                      //closing previous 32 bit HTA instance while being in safe focus
moveTo(screen.availWidth / 2 - 190, screen.availHeight / 2 - 102);
</code></pre></div><p>На практике такой пример рассмотрен в <a href="http://forum.script-coding.com/viewtopic.php?id=15779">&quot;Extended Drop Target&quot;</a>.</p>]]></content>
			<author>
				<name><![CDATA[lifeflame]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=40203</uri>
			</author>
			<updated>2020-10-30T20:15:59Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=143023#p143023</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[HTA & JScript: HTA as 64 bit in focus - запуск HTA как 64 bit в фокусе]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=142920#p142920" />
			<content type="html"><![CDATA[<p>Еще одна наработка, которую я использовал в HTML приложении <a href="http://forum.script-coding.com/viewtopic.php?id=15725">&quot;Resource Extractor&quot;</a> это &quot;<strong>HTA as 64 bit in focus</strong>&quot;.</p><p><strong>Предназначение</strong> - перезапуск HTA в 64 bit без стороннего вмешательства и использования каких-либо системных путей.</p><p>Предлагаю вашему вниманию ее усовершенствованную версию с корректной простановкой фокуса при перезапуске.</p><p>Казалось бы, ничего сильно сложного с запуском HTA как 64 bit не должно быть, но все же есть некоторые трудности с универсальностью различных подходов, а также с получением фокуса для перезапущенного окна в Windows 7 и особенно в Windows XP.</p><p><strong>Скриптовый пример имеет следующие специальные возможности:</strong><br /></p><div class="fancy_spoiler_switcher"><div class="fancy_spoiler_switcher_header" data-lang-open="открыть спойлер" data-lang-close="скрыть спойлер"><strong>+</strong>&nbsp;открыть спойлер</div><div class="fancy_spoiler"><ul><li><p>не требует установки какого-либо стороннего программного обеспечения и поддерживает любую версию Windows, начиная с XP (возможно и 2000) с определенными ActiveX объектами, не запрещенными по умолчанию;</p></li><li><p>полностью написан на JScript в файле скриптового формата HTA и использует следующие ActiveX объекты: WScript.Shell, Scriptlet.TypeLib, WbemScripting.SWbemLocator, Shell.Application и Shell.Explorer.2, также известный как Microsoft Web Browser;</p></li><li><p>тестировался и адаптирован для Windows XP, Windows 7 и Windows 10;</p></li><li><p>не пишет каких-либо записей в реестр и не сохраняет каких-либо персональных данных на вашем жестком диске;</p></li><li><p>не выходит в сеть каким-либо способом;</p></li><li><p>не требует какой-либо вложенной структуры для 64-битной части скрипта (новый код может быть просто добавлен в конец);</p></li><li><p>получает все необходимые паузы и фокусы для того, чтобы приложение оставалось поверх других окон при старте;</p></li><li><p>получает собственный PID, который может быть использован вновь позже;</p></li><li><p>не требует никаких системных путей или деклараций, которые могут отсутствовать в некоторых версиях Windows (например, &quot;SysNative&quot; неизвестен для Windows XP 32 bit).</p></li></ul></div></div><p><strong>Скриптовый пример демонстрирует:</strong><br /></p><ul><li><p>как скрыть HTA во время его динамического создания;</p></li><li><p>как запустить HTA в виде 64-битного процесса без использования системных путей или деклараций;</p></li><li><p>как получить скрытую остановку скрипта в HTA;</p></li><li><p>как решить подтвержденные проблемы с немедленным вызовом &lt;moveTo&gt; или &lt;resizeTo&gt; при старте в Windows XP</p></li><li><p>и как передать и использовать переменные среды для процесса, созданного с помощью WMI.</p></li></ul><br /><p><strong>Различные способы запуска HTA как 64 bit.</strong></p><p>Самый простой и часто предлагаемый способ запуска HTA как 64 bit - создание <strong>ярлыка</strong> с жестко прописанным путем к mshta.exe, но в этом случае приложение становится несколько ограниченным и может требовать стороннего вмешательства.</p><p>Другой способ - использование декларации &quot;<strong>SysNative</strong>&quot;, но Windows XP 32 bit, например, о ней ничего не знает, и требуется дополнительная совместимость.</p><p>Однажды при исследовании <strong>WMI</strong> я обнаружил, что создаваемые им процессы - 64-битные в соответствующих операционных системах. Поменять, вероятно, можно и данное поведение (преимущества смены в этом случае спорны), но меня привлекло то, что это заложено по умолчанию, доступно в любой версии Windows, начиная с XP (возможно и 2000), и этого достаточно, чтобы отвязаться от &quot;SysNative&quot; и жестко прописанных путей.</p><p><strong>Использование &quot;AppActivate&quot; для получения фокуса при перезапуске.</strong></p><p>При скриптовом перезапуске HTML приложения с UI (которым оно обладает, в отличие от WScript и CScript-сценариев), в старых версиях Windows (особенно при уничтожении старой копии) возникают настолько нетривиальные проблемы с расстановкой фокуса новым и старым окнам, что простые вызовы &quot;focus&quot; или &quot;blur&quot; уже не помогают. На помощь приходит &quot;<strong>AppActivate</strong>&quot; от &quot;WScript.Shell&quot;, но и с ним не все так просто.</p><p>Ипользовать метод &quot;AppActivate&quot; следует осторожно в том смысле, что он ищет приложения с похожими заголовками, если обращение было по заголовку. Если же заголовок недостаточно уникален, то и вовсе может быть активировано другое приложение.</p><p>Преимущество данного метода заключается в том, что он может активировать приложения еще и по их PID (Process ID), которые уникальны для текущей среды. Эта возможность нам далее и пригодится.</p><p>Глубокое исследование показало, что &quot;AppActivate&quot; работает корректно только в случаях, если окно с его &quot;хозяином&quot; - &quot;WScript.Shell&quot; - находится в фокусе или является родителем дочерних окон. При этом, даже если окно было активировано корректно, его фокус в старых версиях Windows часто будет все равно потерян при уничтожении родителя, который его активировал.</p><p>Еще одна интересная особенность - нельзя в окне с фокусом корректно активировать другое окно, если при этом использовать &quot;WScript.Shell&quot; чужого окна не в фокусе. Таким образом, для корректной активации принцип прежний - важно наличие фокуса не у самого окна, в котором вызывается метод &quot;AppActivate&quot;, а у того окна, где объявлен его хозяин &quot;WScript.Shell&quot;.</p><p><strong>Передача переменных среды в WMI как сигнал о состоянии приложения.</strong></p><p>На данный момент существует мало примеров передачи переменных среды процессу, созданному при использовании WMI. Но это может быть полезно, как в случае с наследованием переменных при использовании &quot;WScript.Shell&quot;.</p><p>В данной работе при перезапуске скрипта отдано предпочтение анализу наличия определенной переменной среды как сигналу о состоянии приложения, тогда как перебор окон коллекции, анализ их параметров и сравнение признается более затратным по ресурсам и времени, чтобы проводить его чаще, чем один раз. Также, например, анализ параметров командной строки в качестве альтернативы требует инициализации определенного тега &quot;hta:application&quot;, для которого до анализа еще не известно, стоит ли его прятать в Taskbar или еще нет.</p><p><strong>Примечание</strong>: особенностью WMI является то, что переданные переменные являются единственными переменными, которые получит новый процесс. Таким образом, передача переменных процессу в WMI накладывает ограничения на работу процесса вплоть до того, что он даже не сможет нормально запуститься, если не получит на вход существенно важную для него переменную. На передачу переменных в WMI всегда нужно обращать внимание, так как возникающие ошибки при отсутствии необходимых переменных могут сложно определяться и быть самого разного характера. Если не уверены, что нужно для работы создаваемого в WMI процесса, то проще передать ему все доступные в среде переменные.</p><p><strong>Принудительная остановка скрипта.</strong></p><p>Чтобы избежать дополнительной вложенности и включения нового кода для 64-битной части скрипта в ветку if-else в данной работе я использовал собственную принудительную остановку скрипта.</p><p>Глубокое исследование показало, что браузер при работе пробегается вплоть до самой последней строки скрипта даже в случае, если было вызвано завершение приложения на более раннем этапе. Это приводит к возникновению нежелательных ошибок при линейном выполнении кода.<br />Опытным путем было установлено, что приостановить такую работу можно отвлекающими маневрами, одним из которых является блокировка выполнения скрипта модальным окном.</p><p>Специальная настройка такого модального окна позволяет полностью скрыть его из виду с сохранением основной функциональности.<br />Таким образом, скрипт можно приостановить, а затем принудительно завершить без пробегания всех его строк до последней.</p><br /><p><strong>Работа с исходным кодом.</strong><br /></p><ol class="decimal"><li><p>Для запуска скриптового примера скопируйте его исходный код и сохраните его в текстовом файле, сменив его расширение на &quot;hta&quot;.</p></li><li><p>Запуск скриптового примера осуществляется двойным нажатием, как и в случае с обычной программой.</p></li></ol><p>Рекомендую использовать <a href="http://akelpad.sourceforge.net/en/download.php">AkelPad</a> для просмотра сохраненного исходного кода примера <span class="bbu">с правильными отступами</span>.</p><p>Вы можете использовать скриптовый пример на свое усмотрение, но, пожалуйста, оставьте комментарий с прямой ссылкой на <a href="https://tastyscriptsforfree.wix.com/page/scripts">tastyscriptsforfree.wix.com/page/scripts</a> в этом случае.</p><br /><div class="codebox"><pre><code>&lt;script&gt;
/*
HTA as 64 bit in focus v1.0.2 (h t t p s://tastyscriptsforfree.wix.com/page/scripts)
Copyright 2017-2020 Vladimir Samarets. All rights reserved.
tastyscriptsforfree@protonmail.com

Release date: October 27, 2020.


Use this script sample entirely at your own risk.
This script sample is copyrighted freeware and I am not responsible for any damage or data loss it could unintentionally cause.
You may modify it but please leave a comment with direct link to https://tastyscriptsforfree.wix.com/page/scripts in that case.


*******
The purpose of this script sample:
the script sample is intendent for launching HTA as 64 bit in focus and without using system paths.

*******
The script sample has the following special features:

it requires no third party software installation and supports any Windows version since XP with certain ActiveX objects not restricted by default;
it is entirely written in JScript in HTA scripting file format and uses the following ActiveX objects: WScript.Shell, Scriptlet.TypeLib, WbemScripting.SWbemLocator, Shell.Application and Shell.Explorer.2 also known as Microsoft Web Browser;
it was tested and adapted for Windows XP, Windows 7 and Windows 10;
it writes no registry values and stores no personal settings on your hard disk;
it doesn&#039;t access network in any way;
it requires no nested structure for 64 bit instance scripting (new code can be simply added to the end);
it obtains all necessary pauses and focuses in order for the application to stay on top of other windows during its start;
it obtains the application PID which can be reused later;
it requires no system paths or declarations which could be absent in some versions of Windows (for example, &quot;SysNative&quot; is unknown for Windows XP 32 bit).

*******
The script sample demonstrates:

how to hide HTA while having it dynamically created;
how to launch HTA as 64 bit without using system paths or declarations;
how to obtain hidden stop for script in HTA;
how to deal with confirmed immediate &quot;moveTo&quot; or &quot;resizeTo&quot; issues at application start in Windows XP
and how to pass and use environment variables for process created by WMI.

*******
Basic documentation and articles I used:

&#039;VBScript Scripting Techniques: Environment Variables&#039; by Rob van der Woude
    (h t t p s://w w w.robvanderwoude.com/vbstech_data_environment.php);
&#039;Using Win32_ProcessStartup to change environment&#039; post by Rico Rosenlund
    (h t t p s://microsoft.public.scripting.wsh.narkive.com/hW1GURnH/using-win32-processstartup-to-change-environment);

&#039;WSH: exchanging data and objects between scripts - 2&#039; by Xameleon (March, 2011) in Russian
    (h t t p://forum.script-coding.com/viewtopic.php?id=5573);

&#039;VBScript Scripting Techniques: HTAs&#039; by Rob van der Woude
    (h t t p s://w w w.robvanderwoude.com/vbstech_hta.php);

&#039;InternetExplorer and WebBrowser objects&#039; by Ludogovskiy Aleksander in Russian
    (h t t p s://script-coding.com/WSH/WebBrowser.html);

&#039;Windows Script 5.6 Documentation&#039; (script56.chm) by Microsoft Corporation
    (h t t p s://w w w.microsoft.com/en-us/download/confirmation.aspx?id=2764);
&#039;MSDN&#039; related documentation by Microsoft Corporation
    (h t t p s://docs.microsoft.com/en-us/);

Windows XP moveTo and resizeTo issues:
&#039;&quot;Access is denied&quot; by executing .hta file with JScript on Windows XP x64&#039; discussion on stackoverflow.com (January 21, 2009)
    (h t t p s://stackoverflow.com/questions/464679/access-is-denied-by-executing-hta-file-with-jscript-on-windows-xp-x64);
&#039;Something strange with HTAs&#039; discussion on social.technet.microsoft.com (September 19, 2011)
    (h t t p s://social.technet.microsoft.com/Forums/officeocs/en-US/92bf1e76-ebd5-4462-bd52-533e69305a5c/something-strange-with-htas?forum=ITCG).

*******
Basic software I used:

AkelPad 4.9.8 by Aleksander Shengalts and Alexey Kuznetsov (as development environment)
    (h t t p://akelpad.sourceforge.net/en/download.php);
OLE/COM Object Viewer v2.10.059 (oleview.exe) by Charlie Kindel, Michael Nelson, and Michael Antonio (for documentation purposes).
*/

offscreenBuffering = true;                                                                                          //postpone the application window appearance till its UI is ready
var O = function(o){return new ActiveXObject(o);},
WSS = O(&#039;WScript.Shell&#039;),
env = WSS.Environment(&#039;Process&#039;),
head = document.documentElement.firstChild,                                                        //head
PID;                                                                                                                            //PID of 64 bit HTA instance

if(!env(&#039;is64bit&#039;))                                                                                                          //indicates whether the application is launched as 64 bit or not
{
    !function hide(e){try{moveTo(10000, 10000);}catch(e){try{hide();}catch(e){hide();}}}();                            //hiding the application window
    head.insertBefore(document.createElement(&#039;&lt;hta:application showInTaskBar=0&gt;&#039;), head.firstChild);    //hiding the application in the Taskbar

    var WMI=                                                                                                                //a small library written by me for obtaining WMI instance, its common methods and properties
    {                                                                                                                              //below is a sample of creating a process with certain window shifts and environment variables
                                                                                                                                   //and obtaining its &lt;ProcessId&gt; by using WMI
        SWL:new ActiveXObject(&#039;WbemScripting.SWbemLocator&#039;),
        PRMS:function(p)
        {
            var s = WMI.PS.SpawnInstance_();
            for(var i in p)
                s[i] = p[i];
            return s;
        },
        Create:function(c, s, d)
        {
            var CreateIn = WMI.CreateIn.SpawnInstance_();
            CreateIn.CommandLine = c;
            CreateIn.ProcessStartupInformation = s;
            CreateIn.CurrentDirectory = d;
            return WMI.PRC.ExecMethod_(&#039;Create&#039;, CreateIn).ProcessId;
        }
    };
    WMI.PRC = (WMI.WM = WMI.SWL.ConnectServer(&#039;.&#039;, &#039;root/cimv2&#039;)).Get(&#039;Win32_Process&#039;);
    WMI.PS = WMI.WM.Get(&#039;Win32_ProcessStartup&#039;);
    WMI.CreateIn = WMI.PRC.Methods_(&#039;Create&#039;).InParameters;

    var ID = O(&#039;Scriptlet.TypeLib&#039;).GUID.substr(0, 38),                                               //the unique ID obtaining
    EV = &#039;is64bit=&#039;+ID;                                                                                                 //passing the unique ID to 64 bit HTA instance as an Environment variable
    for(var items = new Enumerator(env); !items.atEnd(); items.moveNext())
        EV += &#039;?&#039; + items.item();                                                                                    //obtaining all Environment variables for current process

    PID = WMI.Create                                                                                                  //obtaining PID of 64 bit HTA instance
        (
            &#039;mshta &quot;&#039; + decodeURIComponent(location.pathname) + &#039;&quot;&#039;,                        //current path
            WMI.PRMS
            (
                {
                    X:10000, Y:10000,                                                                                  //hiding the application window before it is shown in order to resize it smoothly
                    EnvironmentVariables:
                        EV.split(&#039;?&#039;)                                                                                         //obtaining an array of all Environment variables by using this approach is universal for different
                                                                                                                                   //versions of Windows
                        /*
                        [                                                                                                          //another way to pass certain Environment variables
                            &#039;is64bit=&#039;+ID,                                                                                  //indicates that the application is launched as 64 bit
                            &#039;SystemRoot=&#039;+env(&#039;SystemRoot&#039;),                                              //for start
                            &#039;SystemDrive=&#039;+env(&#039;SystemDrive&#039;),                                            //for hyperlinks
                            &#039;TEMP=&#039;+env(&#039;TEMP&#039;),                                                                  //for &quot;mailto&quot; links
                            &#039;CommonProgramW6432=&#039;+env(&#039;CommonProgramW6432&#039;)     //for ADODB.Stream
                        ]
                        */
                }
            )
        );

    head.firstChild.insertAdjacentHTML(&#039;afterEnd&#039;, &#039;&lt;object id=&#039; + ID + &#039; PID=&#039; + PID +
        &#039; classid=clsid:8856F961-340A-11D0-A96B-00C04FD705A2&gt;&lt;param name=RegisterAsBrowser value=1&gt;&#039;);                   //registering current HTA window
                                                                                                                                                                                                          //in collection of windows
    showModalDialog(0, 0, &#039;dialogWidth:0;unadorned:1;&#039;);                                                                                                                //stopping the script and obtaining window focus
}                                                                                                                                                                                                         //for &quot;AppActivate&quot;

head.insertBefore(document.createElement(&#039;&lt;hta:application contextMenu=no selection=no scroll=no&gt;&#039;), head.firstChild);      //adding custom HTA header dynamically
resizeTo(380, 204);
document.title = &#039;HTA as 64 bit in focus&#039;;
for(var w, ws = O(&#039;Shell.Application&#039;).Windows(), i = ws.Count; i -- &gt; 0;)
    if((w = ws.Item(i)) &amp;&amp; w.id == env(&#039;is64bit&#039;))
    {
        PID = w.PID;
        w.document.Script.WSS.AppActivate(PID);                                                                                                                            //using &quot;WScript.Shell&quot; in focus to activate
                                                                                                                                                                                                          //the application window of 64 bit HTA instance;
                                                                                                                                                                                                          //remember that &quot;WScript.Shell&quot; should be
                                                                                                                                                                                                          //in focus in order &quot;AppActivate&quot; to work properly
        setTimeout
        (
            function()
            {
                w.document.Script.close();                                                                                                                                              //closing previous 32 bit HTA instance
                moveTo(screen.availWidth / 2 - 190, screen.availHeight / 2 - 102);
            }
            ,
            0                                                                                                                                                                                            //a small pause for having necessary window focus
        );                                                                                                                                                                                                //for &quot;AppActivate&quot;
        break;
    }

//your code could be added below for 64 bit HTA instance

&lt;/script&gt;</code></pre></div>]]></content>
			<author>
				<name><![CDATA[lifeflame]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=40203</uri>
			</author>
			<updated>2020-10-28T10:48:24Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=142920#p142920</id>
		</entry>
</feed>
