Вызов API-функций из VBScript / JScript (DynamicWrapperX)

Тема в разделе "Банк полезных кодов", создана пользователем Dragokas, 27 июн 2014.

  1. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.475
    Симпатии:
    4.305
    Подробности с сайта автора

    О библиотеке DynamicWrapperX

    Автор: Юрий Попов (YMP на script-coding.com форуме).
    Условия распространения библиотеки: freeware.

    DynamicWrapperX - это компонент ActiveX, который вы можете использовать в скриптах (JScript, VBScript и т.п.) для вызова:
    • функций из библиотек DLL (в частности функций Windows API);
    • вообще любых функций, адрес которых в памяти вам известен;
    • функций, чей машинный код (в виде хекс-строки) у вас имеется.
    Компонент написан с нуля на языке ассемблера GoAsm как попытка более полной реализации идеи DynamicWrapper.

    Другие возможности:
    • обратный вызов (callback) скриптовой функции из вызванной вами внешней функции;
    • прямой доступ к памяти (чтение и запись числа по адресу);
    • выделение и освобождение памяти;
    • чтение и запись строк в произвольной кодировке;
    • получение указателя на строку, объект, массив, переменную;
    • получение объекта по указателю на него;
    • определение битности (32 или 64) процесса, в котором выполняется скрипт.
    Регистрация в системе (установка)

    Есть два способа регистрации:
    Код (Text):
      regsvr32.exe <путь-к-компоненту>\dynwrapx.dll — для всех пользователей.
      regsvr32.exe /i <путь-к-компоненту>\dynwrapx.dll — для текущего пользователя.
    Регистрация для текущего пользователя не требует прав администратора, но имеет ограничения:
    • в Windows 98 не работает;
    • в Windows Vista, 7 и 8 при включенном UAC объект будет недоступен приложениям, запущенным с правами администратора.
    В 64-битной ОС нужно регистрировать оба варианта DLL: x86 и x64, чтобы объект был доступен как 64-, так и 32-битным приложениям.

    Примечание для пользователей 1-й версии. Если в системе уже установлена 1-я версия DWX, 2-я зарегистрируется параллельно с ней. В этом случае она будет доступна в скриптах только по имени DynamicWrapperX.2. Чтобы заменить старую версию новой, нужно сначала разрегистрировать старую. В этом случае новая версия будет доступна также и под общим именем DynamicWrapperX.

    Разрегистрация компонента:
    Код (Text):
      regsvr32.exe /u <путь-к-компоненту>\dynwrapx.dll — для всех пользователей.
      regsvr32.exe /u /i <путь-к-компоненту>\dynwrapx.dll — для текущего пользователя.
    Если 2-я версия была установлена параллельно с 1-й, её разрегистрация никак не затронет регистрацию 1-й (и наоборот).
    Метод Register - регистрация API перед ее вызовом

    Этот метод регистрирует функцию из DLL в качестве метода объекта. Функция задаётся именем или ординалом. Значение аргументов "i=", "r=" и "f=" см. в примечаниях.

    Регистрация по имени
    Код (Text):
      DWX = new ActiveXObject("DynamicWrapperX");
      DWX.Register("user32.dll", "MessageBoxW", "i=hwwu", "r=l");
      res = DWX.MessageBoxW(0, "Hello, world!", "Test", 4); // Вызов.
    Регистрация по имени с заменой его на другое
    Код (Text):
      DWX.Register("user32:BadName", "GoodName", "r=n", "f=t");
      // BadName — имя функции, например, содержащее символы,
      // недопустимые в именах методов, или просто очень длинное.
    Регистрация по ординалу
    Код (Text):
      DWX.Register("user32:110", "MethodName", "i=p", "r=l");
      DWX.Register("user32:0x6E", "MethodName", "i=p", "r=l");
    Примечания
    • Если файл библиотеки имеет расширение dll, его можно не указывать. Если файл не имеет расширения, имя должно быть указано с точкой на конце: "mylib."
    • Для системных DLL путь указывать не нужно. Для сторонних зависит от того, где они находятся.
    • Функции Windows API, принимающие или возвращающие строки, часто имеют два варианта: например, MessageBoxW для строк в Юникоде и MessageBoxA для строк в ANSI-кодировке. Букву "А" на конце можно не добавлять, DWX сделает это сам, если не найдёт функцию MessageBox, но имена юникодных функций должны указываться точно, c "W" на конце.
    • Ординал можно задавать десятичным или шестнадцатеричным числом. Учтите, что ординал функции может быть разным в разных версиях библиотеки и в x86 и x64 вариантах одной и той же версии.
    • Наличие аргументов "i=", "r=" и "f=" зависит от функции. Порядок их произвольный, т.к. они опознаются по префиксам.
    • "i=" задаёт тип каждого из параметров функции (целое число, дробное, строка и т.п.). Может опускаться только, если функция не имеет параметров. Расшифровка буквенных обозначений здесь.
    • "r=" — тип возвращаемого значения. Можно не указывать, если возвращаемое значение не нужно, даже если функция что-то возвращает.
    • "f=" — флаги, влияющие на то, как будет вызываться функция. На данный момент имеет одно возможное значение "t" (соглашение вызова thiscall). Имеет смысл только для 32-битного DWX и только со 2-й версии. 64-битным и 1-й версией игнорируется.
    Метод RegisterAddr - регистрирует функцию по её адресу в памяти

    Этот метод регистрирует функцию по её адресу в памяти. Остальные параметры те же, что у метода Register.
    Код (Text):
    DWX.RegisterAddr(Address, "FuncName", "i=hwwu", "r=l");
    Метод RegisterCode - ассемблерная вставка

    Метод принимает в первом аргументе машинный код функции, представленный в виде хекс-строки. Остальные параметры те же, что у метода Register.
    Код (Javascript):
    DWX = new ActiveXObject("DynamicWrapperX");
    if (DWX.Bitness == 32) {
       // Функция, возвращающая произведение своих аргументов.
       Code = "8B442404F76C2408C3"
    } else {
       Code = "4889C8 48F7EA C3" // mov rax,rcx; imul rdx; ret
    }
    CodeAddr = DWX.RegisterCode(Code, "Multiply", "i=ll", "r=l");
    WScript.Echo(DWX.Multiply(5, 4));
    Примечания
    • Под код выделяется память, и он записывается туда уже в бинарном виде. После чего его можно вызывать по присвоенному ему во втором аргументе имени. Возвращаемое значение содержит адрес кода в памяти. Машинный код для 32 и 64 бит различен, отсюда необходимость проверки битности процесса (через проверку битности объекта DWX), чтобы определить, какой код использовать. В качестве возможного применения для такого кода можно привести обработку больших объёмов данных. Машинный код может работать в десятки или даже сотни раз быстрее скриптового.
    • Если вы хотите использовать код по его адресу, без создания метода, можно опустить все аргументы кроме первого. Но имейте в виду, что выделенная под код память всё же связана с объектом и будет освобождена в случае его уничтожения.
    • Хекс-строка может быть сплошной или содержать пробелы, табуляции и переводы строки.
    • Комментарии можно поместить прямо в хекс-строку, обрамив их скобками.
      Code = "4889C8 (mov rax,rcx) 48F7EA (imul rdx) C3 (ret)"

    • Если хекс-строка является многострочным текстом, комментарии можно обозначать точкой с запятой.
      Code = "4889C8 ; mov rax,rcx \n" +
      "48F7EA ; imul rdx \n" +
      "C3 ; ret"

      Но учтите, что в этом случае каждая строка, кроме последней, должна иметь на конце перевод строки, т.к. он используется как признак конца комментария.
    Метод RegisterCallback

    Этот метод нужен для получения указателя на скриптовую функцию, пригодного для передачи какой-либо функции API. Которая потом, используя этот указатель, могла бы данную скриптовую функцию вызывать. Пример такой API-функции — EnumWindows (см. код ниже). Она перебирает существующие окна и хэндл каждого окна передаёт callback-функции в качестве параметра. После этого она ждёт, что вернёт callback-функция. Если 1, то перебор идёт дальше, если 0 — прекращается.

    В JScript и VBScript функция является объектом, и ссылка на неё для таких целей не годится. Поэтому ссылка на скриптовую функцию сначала передаётся методу RegisterCallback, а API-функция получает возвращённый им указатель на одну из вспомогательных процедур внутри dynwrapx.dll, вызовы которой будут транслироваться в вызовы скриптовой функции, а возвращаемые значения — в обратном направлении.

    В JScript ссылка на функцию — это её имя без скобок, а в VBScript сначала нужно использовать GetRef. Кроме ссылки на функцию задаются также типы её параметров и возвращаемого значения — аналогично методу Register (но используются только маленькие буквы).

    Пример на JScript (VBScript см. ниже):
    Код (Javascript):
    DWX = new ActiveXObject("DynamicWrapperX");

    DWX.Register("user32", "EnumWindows",  "i=ph");
    DWX.Register("user32", "GetWindowTextW", "i=hpl");  // Unicode
    //DWX.Register("user32", "GetWindowText", "i=hpl"); // ANSI

    // Регистрация CbkEnumWin как функции обратного вызова
    // и получение указателя.
    pCbkFunc = DWX.RegisterCallback(CbkEnumWin, "i=hh", "r=l");

    n=0, m=0, WinList="";
    Buf = DWX.MemAlloc(256); // Буфер под заголовок окна (выходная строка).

    // Вызов EnumWindows с передачей ей указателя на callback-функцию.
    DWX.EnumWindows(pCbkFunc, 0);

    DWX.MemFree(Buf);

    WScript.Echo("Всего окон: " + m + "\nС заголовками: " + n +
      "\n\n" + WinList);


    // ............... Собственно callback-функция ....................

    function CbkEnumWin(hwnd, lparam)
    {
       var Title;
       DWX.GetWindowTextW(hwnd, Buf, 128);  // Unicode
       Title = DWX.StrGet(Buf, "w");
       //DWX.GetWindowText(hwnd, Buf, 256); // ANSI
       //Title = DWX.StrGet(Buf, "s");
       if(Title.length > 0) {
          WinList += hwnd + "\t" + Title + "\n";
          ++n;
       }
       ++m;
       return 1; // Если вернуть 0, вызовы прекратятся.
    }

    Пример на VBScript:
    Код (Visual Basic):
    Set DWX = CreateObject("DynamicWrapperX")

    DWX.Register "user32", "EnumWindows", "i=ph"
    DWX.Register "user32", "GetWindowTextW", "i=hpl" ' Unicode
    'DWX.Register "user32", "GetWindowText", "i=hpl" ' ANSI

    Set Ref = GetRef("CbkEnumWin") ' Получение ссылки на функцию.

    ' Регистрация CbkEnumWin как функции обратного вызова
    ' и получение указателя.
    pCbkFunc = DWX.RegisterCallback(Ref, "i=hh", "r=l")

    n = 0 : m = 0 : WinList = ""
    Buf = DWX.MemAlloc(256) ' Буфер под заголовок окна (выходная строка).

    ' Вызов EnumWindows с передачей ей указателя на callback-функцию.
    DWX.EnumWindows pCbkFunc, 0

    DWX.MemFree Buf

    WScript.Echo "Всего окон: " & m & vbCrLf & "С заголовками: " & n & _
    vbCrLf & vbCrLf & WinList


    ' ................ Собственно callback-функция .......................

    Function CbkEnumWin(hwnd, lparam)
        DWX.GetWindowTextW hwnd, Buf, 128 ' Unicode
        Title = DWX.StrGet(Buf, "w")
        'DWX.GetWindowText hwnd, Buf, 256 ' ANSI
        'Title = DWX.StrGet(Buf, "s")
        If Len(Title) > 0 Then
            WinList = WinList & hwnd & vbTab & Title & vbCrLf
            n = n+1
        End If
        m = m+1
        CbkEnumWin = 1 ' Если вернуть 0, вызовы прекратятся.
    End Function
    Прочие методы

    Параметры в квадратных скобках необязательны, но нельзя опускать такой параметр, если следующий за ним вы указываете.

    NumGet( Address [, Offset] [, Type] ) — чтение числа из памяти. Address — базовый адрес. Offset — смещение от него (в байтах), положительное или отрицательное; по умолчанию 0. Type — тип числа: те же буквенные обозначения, что и для метода Register (см. список здесь), но используются только маленькие буквы; по умолчанию — l. Считанное число помещается в возвращаемое методом значение.

    NumPut( Var, Address [, Offset] [, Type] ) — запись числа в память. Var — либо литеральное числовое значение, либо переменная, содержащая значение, которое нужно записать. Остальное — как в NumGet. Возвращаемое методом значение содержит адрес сразу за последним записанным байтом.

    В обоих методах выше Address может быть как числом, так и строкой, в последнем случае в качестве базового адреса используется указатель на эту строку. Это позволяет использовать строки в качестве буфера для данных, размещать там массивы, структуры и т.п. (о связанном с этим риске см. примечание к методу Space ниже).

    StrPtr( Var [, Type/Codepage] ) — возвращает указатель на строку (на оригинал). Var — строковая переменная или константа. Type/Codepage — тип/кодировка. Возможные значения: w (по умолчанию), s, z, либо явное указание кодировки — например, "cp1251". При значениях s, z либо кодировке строка предварительно конвертируется на месте. Поддерживается кодировка "cp1201", т.е. UTF-16 Big Endian.

    Если результирующая строка длиннее исходной, она будет обрезана. Поскольку исходная строка в Юникоде, где каждый символ занимает два байта, места должно быть более чем достаточно в большинстве случаев. Возможно, какой-нибудь восточно-азиатский текст может быть длиннее в ANSI-кодировке или в UTF-8, чем он есть в UTF-16, но это только мои догадки.

    StrGet( Address [, Type/Codepage] ) — чтение строки с указанного адреса. Возвращает копию строки. Address может быть как указателем в виде числа, так и строковой переменной. Type/Codepage — то же, что у StrPtr. Значения s и z нужны для чтения строки в ANSI— или OEM—кодировке по умолчанию. Строка при чтении конвертируется в Юникод.

    StrPut( String, Address [, Type/Codepage] ) — запись строки по указанному адресу. Type/Codepage — то же, что у двух методов выше. Строка при записи конвертируется в заданную кодировку. Возвращается адрес после нулевого терминатора строки. Если Address указан как 0, метод вернёт размер буфера в памяти, необходимый для записи строки в указанной кодировке, включая нулевой терминатор на конце строки.

    Space( Count [, Char] ) — создание строки (BSTR) заданной длины. Возвращает строковую переменную. Count — число символов (двухбайтных). Char — символ, которым будет заполнена строка. По умолчанию строка заполняется пробелами — так же, как это делает функция Space в VBScript. Чтобы заполнить строку двоичными нулями, задайте Char как пустую строку ("").

    NB: Метод Space был задуман для создания строк, используемых как буферы памяти — для чисел, структур, выходных строк. Но, как выяснилось на практике, такое использование строк в общем случае ненадёжно. Контроль над памятью, выделенной под строку, отдаётся скриптовому движку, и если он в процессе своей работы произведёт с ней какие-то манипуляции, помещённые в неё данные могут быть потеряны или испорчены. Поэтому я рекомендую для выделения памяти под буфер использовать метод MemAlloc (см. ниже).

    ObjPtr( Object ) — получение указателя на объект.

    ObjGet( ObjPtr ) — получение объекта по указателю на него. Если объект поддерживает интерфейс IDispatch, возвращается переменная типа VT_DISPATCH; если нет — VT_UNKNOWN. Счётчик ссылок объекта увеличивается на 1.

    ArrPtr( Array ) — получение указателя на структуру SAFEARRAY массива. Не работает для массивов в JScript, т.к. это объекты.

    VarPtr( Variable ) — в языках, где переменные передаются в методы по ссылке, как в VBScript, можно получить указатель на структуру VARIANT переменной.

    MemAlloc( Bytes [, ZeroMem] ) — выделение памяти. Если вторым аргументом указать 1, память будет обнулена. Возвращается указатель на выделенную память.

    MemFree( MemPtr ) — освобождение ранее выделенной памяти.

    Bitness() — определение битности объекта DynamicWrapperX (и, тем самым, битности процесса, его использующего). Возвращает число 32 или 64.

    Version( [Field] ) — возвращает указанное поле/поля из полного номера версии DynamicWrapperX. Задайте параметру Field значение согласно приведённой ниже таблице. Если Field опущен, это равносильно 0.

    Пример для версии 2.5.7.10.

    0 — полная версия как строка: "2.5.7.10"
    1 — старший номер версии: 2
    2 — младший номер версии: 5
    3 — номер сборки: 7
    4 — номер ревизии: 10 (0xA)
    5 — старший + младший номер версии: 0x20005
    6 — номер сборки + ревизии: 0x7000A
    7 — полный номер версии: 0x200050007000A

    Как вы можете видеть, каждое поле является 16-битным целым и занимает 2 байта.
    Типы параметров и возвращаемых значений

    Типы входных параметров и возвращаемых значений
    m — знаковое целое 64 бита — INT64, LONGLONG, ...
    q — беззнаковое целое 64 бита — UINT64, ULONGLONG, ...
    l — знаковое целое 32 бита — LONG, INT, LRESULT, BOOL, ...
    u — беззнаковое целое 32 бита — ULONG, UINT, DWORD, ...
    h — хэндл, дескриптор — HANDLE, HWND, HMODULE, HINSTANCE, HICON, ... — 32 бита (x86) или 64 бита (x64)
    p — указатель, для чисел то же, что u (x86) или q (x64), но также можно использовать для передачи объекта (IDispatch *) и строки.
    n — знаковое целое 16 бит — SHORT
    t — беззнаковое целое 16 бит — USHORT, WORD, WCHAR, OLECHAR, ...
    c — знаковое целое 8 бит — CHAR
    b — беззнаковое целое 8 бит — UCHAR, BYTE, ...
    f — дробное число одинарной точности (32 бита) — FLOAT
    d — дробное число двойной точности (64 бита) — DOUBLE
    w — строка в Юникоде — BSTR, LPWSTR, LPOLESTR, OLECHAR *, WCHAR *, ...
    s — строка в кодировке ANSI/Windows по умолчанию — LPSTR, LPCSTR, CHAR *, ...
    z — строка в кодировке OEM/DOS по умолчанию — LPSTR, LPCSTR, CHAR *, ...
    v — указатель на структуру VARIANT

    Примечания
    • Подробнее о строковых типах см. здесь.
    • Кроме хэндлов и указателей, есть и другие типы, меняющие свою битность с битностью процесса. Например, LPARAM, WPARAM, SIZE_T. Для них также лучше использовать тип h или p, чтобы код скрипта корректно работал при его выполнении как 32-, так и 64-битным интерпретатором.
    • Типам m и q (а также h и p в x64) в скриптах соответствовали бы типы VT_I8 и VT_UI8. Движками JScript и VBScript эти типы не поддерживаются, что ограничивает возможности работы с 64-битными целыми. Пока значение возвращаемого функцией числа это позволяет, DWX преобразует его к типам VT_I4 (знаковое целое 32 бита) либо VT_R8 (дробное число двойной точности). Поскольку мантисса VT_R8 имеет только 53 бита, этот тип не может отобразить все числа в диапазоне 64-битного целого. В таком случае возвращается тип VT_I8 или VT_UI8. Всё, что можно с ними сделать в скрипте, — передать как аргумент в какой-то другой метод или вывести значение числа в WScript.Echo либо MsgBox. Никакие расчёты с ними невозможны.
    • Когда большое целое возвращается как VT_R8 и вы хотите посмотреть его значение в диалоговом окне, оно может отображаться неточно из-за ограничения на число знаков после запятой в строковом представлении дробного числа. Поэтому, например, число 9223372036854775808 может отобразиться как 9,22337203685478E+18 вместо 9,223372036854775808E+18. Однако само число в переменной не округляется и остаётся точным.
    • Если значение 64-битного целого не укладывается ни в один из доступных числовых типов, можно указать его в виде строки, десятичной или шестнадцатеричной (с префиксом 0x).
    Код (Text):
      DWX.Register("lib.dll", "func", "i=m")
      DWX.func("0xFFFFFFFFFFFFFFFF")
      DWX.func("-0x7FFFFFFFFFFFFFFF")
      DWX.func("18446744073709551615")
      DWX.func("-9223372036854775807")
    Выходные параметры
    M — указатель на число (его адрес в памяти) — LONGLONG *, PLONGLONG и т.п.
    Q — то же — ULONGLONG *, PULONGLONG, ...
    L — то же — LONG *, LPLONG, ...
    H — то же — HANDLE *, PHANDLE, LPHANDLE, ...
    U — то же — ULONG *, LPDWORD, ...
    P — то же
    N — то же — SHORT *
    T — то же — USHORT *, LPWORD, WCHAR *, OLECHAR *, ...
    C — то же — CHAR *, ...
    B — то же — UCHAR *, LPBYTE, ...
    F — то же — FLOAT *, PFLOAT
    D — то же — DOUBLE *, PDOUBLE
    W — выходная строка в Юникоде
    S — выходная строка в ANSI
    Z — выходная строка в OEM

    Примечания
    • Использование выходных типов для чисел имеет смысл для скриптовых движков, которые передают переменные в метод по ссылке, как это делает VBScript. В этом случае DWX может передать функции указатель на значение переменной, которое функция может изменить. В движках, где аргументы передаются по значению, как в JScript, методу передаётся копия числа, поэтому изменить оригинал нет возможности. В этом случае решением будет выделение нужного количества памяти, например, методом MemAlloc, передача функции указателя на эту память (используя тип p) и затем, после вызова функции, считывание помещённого ею туда числа методом NumGet.
    • Некоторые движки копируют строки при передаче их в метод; в этом случае использование выходных типов для строк также теряет смысл. Решение аналогично: выделение памяти, передача указателя на неё типом p и затем считывание оттуда строки методом StrGet.
    Подробнее о строках

    Строки

    В JScript и VBScript используются строки типа BSTR. Это строка в Юникоде, т.е. код каждого символа занимает 2 байта. За последним символом расположен ограничитель - 2 нулевых байта. Кроме того, перед первым символом находится 4-байтное число, содержащее длину строки в байтах (без учёта нулевых на конце). Указатель, содержащийся в скриптовых строковых переменных, является адресом первого символа такой строки (т.е. байты, содержащие длину строки, как бы остаются за кадром).

    Передать строку можно тремя способами:
    • Входная строка: w, s, z. Для типов s и z строка копируется с конвертацией в соответствующую кодировку, и API-функция получает указатель на эту копию. После завершения работы функции память, запрошенная под копию строки, освобождается, т.е. эта копия перестаёт существовать. В случае w функции передаётся указатель на оригинал строки.
    • Выходная строка: W, S, Z. Передаётся указатель на оригинал строки, но S и Z предварительно конвертируются (на месте). После завершения функции строки S и Zконвертируются обратно в Юникод, у них измеряется длина, а у строки W только измеряется длина. Длина (в байтах) записывается перед строкой. Без этой последней операции потом в скрипте будут глюки, например, при конкатенации этой строки с другими.
    • Указатель: p. Это самый простой способ. Передаётся указатель на оригинал строки, без конвертации. После завершения функции нет ни конвертации, ни корректировки длины. Так что если функция туда что-то запишет, оно там будет в нетронутом виде. Здесь строка фактически является просто буфером в памяти для хранения любых данных.

      Может показаться, что это то же самое, что w, но это не так. Разница в том, что параметр, объявленный как p, принимает не только строковые переменные, но и числовые.

    Вернуть строку можно также по-разному:
    • p — получаем числовую переменную, содержащую указатель на строку, которую вернула функция.
    • w, s или z — получаем строковую переменную, содержащую указатель на копию этой строки. Строки s и z копируются с конвертацией в Юникод.

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

    Вызовы API, принимающие строковые аргументы, как правило, представлены в двух вариантах - например, MessageBoxA и MessageBoxW. Использование в скриптах юникодовских вариантов, с окончанием W, представляется более логичным, т.к. при этом нет дополнительных перекодировок строк туда и обратно.

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

    Использование строк как буферов памяти может работать или нет в зависимости от того, как внутри скриптового движка реализована работа со строками. Предпочтительнее выделять память методом MemAlloc, т.к. она будет под вашим полным контролем.

    Краткое описание

    Ранее у VBS / JS не было возможностей для вызова API-функций.
    Так было до тех пор, пока Юрий Попов не написал замечательную библиотеку DynamicWrapperX.

    Библиотеку нужно зарегистрировать:
    1) в системе (нужны права администратора)
    Код (Text):
    regsvr32 "<путь-к-компоненту>\dynwrapx.dll"
    2) или в контексте текущего пользователя
    Код (Text):
    regsvr32 /i "<путь-к-компоненту>\dynwrapx.dll"
    Затем можно воспользоваться всеми прелестями вызова API из .VBS / .JS.

    Пример вызова.

    API из JS:
    Код (Javascript):
    DWX = new ActiveXObject("DynamicWrapperX");
    DWX.Register("user32.dll", "MessageBoxW", "i=hwwu", "r=l");
    res = DWX.MessageBoxW(0, "Hello, world!", "Test", 4); // Вызов.
    API из VBS
    Код (Visual Basic):
    set DWX = CreateObject("DynamicWrapperX")
    DWX.Register "user32.dll", "MessageBoxW", "i=hwwu", "r=l"
    res = DWX.MessageBoxW(0, "Hello, world!", "Test", 4) ' Вызов.

    Библиотеку можно скачать:

    1) на сайте автора
    2) или под этим постом вместе с батником авторегистрации и примером сворачивания / разворачивания "Калькулятора Windows"
    Батник для регистрации DynamicWrapperX 2.0 (x32, x64) и вызова функций из 32/64-битных библиотек.

    В комплект уже включена DynamicWrapperX ver.2.0.0.1,
    а также демо-VBS, показывающий как свернуть и развернуть "Калькулятор Windows" с помощью API-функций.

    FindWindow.vbs - демо-проект (если библиотека не будет зарегистрирована, то сам вызовет regdynwrapx.bat и перезапустится)
    regdynwrapx.bat - чтобы зарегистрировать
    unregdynwrapx.bat - чтобы снять регистрацию.

    Скрипт сам запрашивает права Администратора, если понадобится.
    Если Вы хотите вызывать функции из своей 32-битной библиотеки (независимо от битности ОС), раскомментируйте участок кода FindWindow.vbs в строках №№ 16-24.

    Если появится новая версия библиотеки DynamicWrapperX, ее папки "32" и "64" нужно скопировать в папку "dynwrapx", заменив оригинал.

    _____________________________

    Об основах API здесь я вести речь не буду.
    Тот, кто ни разу ними не пользовался, с нуля вникать будет тяжело.
    Но можно будет воспользоваться чужими примерами реализаций простых задач.

    На функциях API основана работа самой ОС.
    Используя их, Вы получаете практически неограниченные возможности.

    Тема закрыта и дополняется.
    Просьба вопросы задавать в новых темах.
     

    Вложения:

    • DynWrapReg.zip
      Размер файла:
      48,1 КБ
      Просмотров:
      27
    Последнее редактирование: 28 июн 2014
    SNS-amigo, dzu и Kиpилл нравится это.

Поделиться этой страницей