<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
		<link>http://forum.script-coding.com/viewtopic.php?id=7328</link>
		<atom:link href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=7328&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «WSH: обсуждаем DynamicWrapperX от YMP - 2».]]></description>
		<lastBuildDate>Mon, 14 Mar 2022 08:49:04 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=152571#p152571</link>
			<description><![CDATA[<div class="quotebox"><cite>alexii пишет:</cite><blockquote><p>Как именно регистрируете?</p></blockquote></div><p>Надо было каталог в PATH загнать - там были ссылки из одной dll-ки на другие...</p>]]></description>
			<author><![CDATA[null@example.com (yyk)]]></author>
			<pubDate>Mon, 14 Mar 2022 08:49:04 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=152571#p152571</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=149491#p149491</link>
			<description><![CDATA[<p><strong>alexii</strong> спасибо за пинок, это я то с разрядностью, то с именами напутал...<br />Работает!!!...</p>]]></description>
			<author><![CDATA[null@example.com (yyk)]]></author>
			<pubDate>Wed, 08 Sep 2021 13:24:46 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=149491#p149491</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=149480#p149480</link>
			<description><![CDATA[<div class="quotebox"><cite>yyk пишет:</cite><blockquote><p>А порядок регистрации х32 и х64 dynwrapx.dll важен?<br />А то зарегистрировал, а результат странный (хотя примеры работают)</p></blockquote></div><p>Нет, порядок не важен. А результат правильный, просто названия этих папок в Windows могут ввести в заблуждение. На самом деле в System32 находятся 64-разрядные версии программ и библиотек, а в SysWOW64 -- 32-разрядные.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Mon, 06 Sep 2021 16:15:52 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=149480#p149480</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=149476#p149476</link>
			<description><![CDATA[<p>Как именно регистрируете?</p>]]></description>
			<author><![CDATA[null@example.com (alexii)]]></author>
			<pubDate>Sun, 05 Sep 2021 13:05:12 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=149476#p149476</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=149454#p149454</link>
			<description><![CDATA[<p>И еще проблемка: не хочет регистрировать библиотеки из mingw64. Пишет &quot;Не удалось найти или загрузить DLL&quot;.</p>]]></description>
			<author><![CDATA[null@example.com (yyk)]]></author>
			<pubDate>Thu, 02 Sep 2021 09:04:58 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=149454#p149454</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=149453#p149453</link>
			<description><![CDATA[<p>А порядок регистрации х32 и х64 dynwrapx.dll важен?<br />А то зарегистрировал, а результат странный (хотя примеры работают):</p><p>Код: </p><div class="codebox"><pre><code>var DWX = new ActiveXObject(&quot;DynamicWrapperX&quot;);
WSH.Echo(&quot;Разрядность &quot; + DWX.Bitness());</code></pre></div><p>Результат:<br /></p><div class="codebox"><pre><code>F:\work\jScript\dwx2&gt;C:\Windows\SysWOW64\cscript.exe /nologo test.js
Разрядность 32

F:\work\jScript\dwx2&gt;C:\Windows\System32\cscript.exe /nologo test.js
Разрядность 64

F:\work\jScript\dwx2&gt;</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (yyk)]]></author>
			<pubDate>Thu, 02 Sep 2021 08:05:17 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=149453#p149453</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=133207#p133207</link>
			<description><![CDATA[<p><strong>Parazit</strong>, динамически регистрировать функцию в любом месте кода можно методом DWX.Register, тут всё хорошо.<br />Вопрос в том, чтобы вообще руками не регистрировать, а регистрация происходила автоматически при первом вызове. К тому же, не для всех функций регистрация заключается лишь в передачи модуля, имени, типов аргументов (&quot;i=&quot;) и возвращаемого значения (&quot;o=&quot;) из массива.<br />Для функции SetClassLongPtrW, например, регистрация различается в зависимости от разрядности хоста:<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"><div class="codebox"><pre><code>if(bitness === 64) {
  DWX.Register(&quot;user32&quot;,&quot;SetClassLongPtrW&quot;,&quot;i=hlp&quot;,&quot;r=p&quot;); // HWND,int,LONG_PTR; ULONG_PTR
} else {
  DWX.Register(&quot;user32:SetClassLongW&quot;,&quot;SetClassLongPtrW&quot;,&quot;i=hll&quot;,&quot;r=u&quot;); // HWND,int,LONG; DWORD
}</code></pre></div></div></div><p>А для функции GetModuleFileNameExW, в зависимости от версии системы, регистрация выполняется даже из разных модулей (<em>лучше переделать без try-catch, но пока так</em>):<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"><div class="codebox"><pre><code>try { // for NT5.1 or later
  DWX.Register(&quot;psapi&quot;,&quot;GetModuleFileNameExW&quot;,&quot;i=hhpu&quot;,&quot;r=u&quot;); // HANDLE,HMODULE,LPWSTR,DWORD; DWORD
} catch(e) {
  try { // for NT6.1 or later
    DWX.Register(&quot;kernel32:K32GetModuleFileNameExW&quot;,&quot;GetModuleFileNameExW&quot;,&quot;i=hhpu&quot;,&quot;r=u&quot;); // HANDLE,HMODULE,LPWSTR,DWORD; DWORD
  } catch(e) {
    host.error(new Error(&quot;Функция GetModuleFileNameExW не найдена!&quot;));
    host.exit(1);
  }
}</code></pre></div></div></div><p>Пробовал по-разному такую функциональность реализовать, но вариант каждый вызов winapi-функции оборачивать в try-catch не выход, а при реализации обёрточной функции встаёт проблема передачи аргументов (+ лишняя нагрузка на каждый вызов winapi-функции, <em>а, например, 3d рендринг и без того ограничен подобными накладными затратами, да и при обычном изменении размеров окна перерисовка затратна</em>), к тому же некрасивый код выходит:<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"><div class="codebox"><pre><code>var host = {
  &quot;activex&quot;: function(progid){ return new ActiveXObject(progid); },
  &quot;error&quot;: function(msg){ if(host.activex(&quot;WScript.Shell&quot;).Popup(msg instanceof Error &amp;&amp; msg.message || msg, 0, &quot;JScript host&quot;, 48 + 1) === 2) host.exit(1); },
  &quot;exit&quot;: function(code){ WScript.Quit(code || 0); }
};

var DWX = host.activex(&quot;DynamicWrapperX&quot;);
if(DWX.Version(7) &lt; 0x2000100010001) host.exit(1);

function define(name) {
  // захардкожу
  if(name === &quot;MessageBoxW&quot;) DWX.Register(&quot;user32&quot;, &quot;MessageBoxW&quot;, &quot;i=hppu&quot;, &quot;r=l&quot;); // HWND,LPCWSTR,LPCWSTR,UINT; int
  return true;
}

function call(name, args) {
  var retval;
  var call_internal = function() {
    // так не прокатывает
    // return DWX[name].apply(DWX, args);
    
    // а так костыль страшный
    switch(args.length) {
    case 0: return DWX[name]();
    case 1: return DWX[name](args[0]);
    case 2: return DWX[name](args[0], args[1]);
    case 3: return DWX[name](args[0], args[1], args[2]);
    case 4: return DWX[name](args[0], args[1], args[2], args[3]);
    // ...
    }
  };
  try {
    retval = call_internal();
  } catch(err) {
    if(define(name)) {
      try {
        retval = call_internal();
      } catch(err) {
        host.error(new Error(&quot;Функция &quot; + name + &quot; недоступна.&quot;));
        host.exit(1);
      }
    } else {
      host.error(new Error(&quot;Функция &quot; + name + &quot; не определена.&quot;));
      host.exit(1);
    }
  }
  return retval;
}

// Эстетически это выглядит страшнее, чем DWX.MessageBoxW(...)
call(&quot;MessageBoxW&quot;, [0, &quot;Dynamic load function is success!&quot;, &quot;JScript&quot;, 0x40]);</code></pre></div></div></div><p>До этого момента проходилось либо регистрировать большое множество ненужных функций даже для вывода helloworld, в случае использования моей библиотеки функций, либо по мере необходимости копировать из неё определения по-отдельности, но ручная работа «линковщика» удовольствия не доставляет, гораздо удобнее иметь одну внешнюю библиотеку для проектов.</p><br /><p><strong>YMP</strong>, спасибо вам большое! Работает)<br />Я тоже не вижу, только если в целях унификации механизма. Хотя ошибку &quot;модуль не найден&quot; в некоторых случаях тоже можно обработать, организовав дополнительный поиск, но т.к. эта ошибка возникает при регистрации функции, там же можно и перехват исключения организовать: в дополнительном инструменте необходимости, на мой взгляд, нет.<br />На «событийном механизме» не настаиваю, но до более красивого варианта организовывать динамическую регистрацию функций я пока не додумался. На названии не настаиваю тем более, я лишь для примера писал <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p><p>С названием OnMemberNotFound согласен. Только нашёл странность в её поведении: вернув true получаем ошибку (как и при возврате false), т.к. true преобразуется к -1 (что делает невозможным возвращать результат сравнения без конструкции a == b ? 1 : 0). Кажется лучше сделать проверку на 0: если ноль – ошибка, не ноль – повторная попытка вызова.<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"><p>Т.е. вместо<br /></p><div class="codebox"><pre><code>cmp eax,1
je short -79</code></pre></div><p>сделать<br /></p><div class="codebox"><pre><code>cmp eax,0
jne short -79</code></pre></div><p>Если править бинарник, в случае 32-разрядной версии по смещению 0xAC0 в файле произвести замену 83F8<strong>01</strong> <strong>74</strong>B1 -&gt; 83F8<strong>00</strong> <strong>75</strong>B1.<br /><span class="postimg"><img src="https://pp.userapi.com/c854124/v854124697/15ab4/rc7sY0Vl7RA.jpg" alt="https://pp.userapi.com/c854124/v854124697/15ab4/rc7sY0Vl7RA.jpg" /></span></p></div></div>]]></description>
			<author><![CDATA[null@example.com (maksim32)]]></author>
			<pubDate>Wed, 27 Mar 2019 17:45:39 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=133207#p133207</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=133204#p133204</link>
			<description><![CDATA[<p><strong>maksim32</strong><br />Я пока отказался от планов насчёт всех ошибок, т.к. не вижу реалистичных сценариев их использования, и реализовал только метод OnMemberNotFound. Он принимает ссылку на функцию, а функции передаёт имя ненайденного метода. В общем, всё как в вашем коде, только подправить OnFunction на OnMember. OnFunctionNotFound скорее подошло бы для функции, не найденной в DLL, а то, что в объекте, это уже метод или свойство. Пробная версия здесь: <a href="https://yadi.sk/d/4k-v9xsEf7f-qg">https://yadi.sk/d/4k-v9xsEf7f-qg</a></p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Wed, 27 Mar 2019 14:24:57 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=133204#p133204</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=133200#p133200</link>
			<description><![CDATA[<p>По-моему, вы не улавливаете, о чём речь. Метод activex вообще тут не при делах. Требуется возможность назначать скриптовую функцию как обработчик ошибки в случае, если идёт попытка вызвать через DWX функцию, которая не была предварительно зарегистрирована. DWX должен передать обработчику имя ненайденного метода, а обработчик соответствующую функцию должен зарегистрировать, если она есть в библиотеке. DWX соответственно либо делает повторный поиск метода и исполняет его, либо возвращает ошибку.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Wed, 27 Mar 2019 09:26:35 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=133200#p133200</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=133199#p133199</link>
			<description><![CDATA[<p>Посмотрите его первый код.<br />Он предлагает создать метод .activex, передавать ему параметры,<br />которые будут инициализировать метод .Register.<br />В библиотеке будет куча API-функций.<br />Параметром передавать необходимую API-функцию, параметры к этой функции,<br />и типы этих параметров (ещё и DLL-ку тоже надо передавать),<br />чтобы её зарегистрировать в качестве объекта (DWX).<br />Т.е., динамически регистрировать функцию в любом месте кода.</p><p>А GetLastError будет указывать на ошибку API, если таковая будет присутствовать.</p><p>Вы же говорите, что надо инициализировать какие-то пять интерфейсов.</p>]]></description>
			<author><![CDATA[null@example.com (Parazit)]]></author>
			<pubDate>Wed, 27 Mar 2019 08:39:26 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=133199#p133199</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=133197#p133197</link>
			<description><![CDATA[<p>Ничего не понял. При чём тут GetLastError?</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Wed, 27 Mar 2019 07:12:08 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=133197#p133197</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=133194#p133194</link>
			<description><![CDATA[<p>Задача была вытащить из базы данных избранную функцию.</p><p>Зачем там интерфейсы?<br />Зачем коннектиться к какому-то объекту? <br />Зачем отслеживать события?</p><p>Обычную GetLastError, и всё. <br />При ошибке вернуть -1.</p>]]></description>
			<author><![CDATA[null@example.com (Parazit)]]></author>
			<pubDate>Wed, 27 Mar 2019 04:34:24 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=133194#p133194</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=133155#p133155</link>
			<description><![CDATA[<p>Мне больше нравится второй, более простой вариант, когда функционал библиотеки доступен сам по себе. С WScript.ConnectObject работать не приходилось, думаю, эта зависимость будет лишняя. Да и в приложениях с HTML-интерфейсом (mshta) будет не легко получить к этому доступ.<br />Спасибо, что приняли во внимание моё пожелание!</p>]]></description>
			<author><![CDATA[null@example.com (maksim32)]]></author>
			<pubDate>Mon, 25 Mar 2019 17:03:10 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=133155#p133155</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=133086#p133086</link>
			<description><![CDATA[<p>Посмотрел в сторону подключения к событиям через WScript.ConnectObject, но это какая-то жесть. Нужно реализовать 5 входящих интерфейсов и вшить в DLL библиотеку типов, описывающую исходящий интерфейс. Причём непонятно, каким он, собственно, должен быть. Думаю пойти более простым путём, просто сделать метод OnError, который принимает ссылку на функцию-обработчик. А передавать ей можно объект Error, через методы которого обработчик может извлекать всю нужную информацию и инструктировать DWX о дальнейших действиях.</p>]]></description>
			<author><![CDATA[null@example.com (YMP)]]></author>
			<pubDate>Sat, 23 Mar 2019 16:56:52 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=133086#p133086</guid>
		</item>
		<item>
			<title><![CDATA[Re: WSH: обсуждаем DynamicWrapperX от YMP - 2]]></title>
			<link>http://forum.script-coding.com/viewtopic.php?pid=133033#p133033</link>
			<description><![CDATA[<p>Спасибо за ответ. Согласен, кучу событий добавлять – это плохо. Не подумал о других исключениях и что для них придётся заложить аналогичный функционал.<br />Да, в общем виде это очень удобно (<em>даже если вдруг захочется реализовать в виде подписчиков на события подобный менеджер будет реально написать, потенциал имеется</em>).</p>]]></description>
			<author><![CDATA[null@example.com (maksim32)]]></author>
			<pubDate>Thu, 21 Mar 2019 11:12:45 +0000</pubDate>
			<guid>http://forum.script-coding.com/viewtopic.php?pid=133033#p133033</guid>
		</item>
	</channel>
</rss>
