【问题标题】:How to load DLL file from Jscript file?如何从 Jscript 文件加载 DLL 文件?
【发布时间】:2023-06-24 02:39:01
【问题描述】:

所以我正在编写一个独立的JScript 文件,由Windows Script Host 执行(此文件不会用作网络应用程序)。

我的目标是加载一个 dll 文件。就像在 C++ 应用程序中使用 LoadLibrary function 一样。

我尝试研究这个主题,但没有找到任何有用的东西。我迷路了,我没有任何代码可以分享。我知道使用ActiveXObject 可能会救我。如果是这样,知道如何使用它吗?

更新:

如果我们都同意加载是不可能的,我会接受有效性检查。意思是,不要尝试加载,而是检查它是否已加载且功能正常。

【问题讨论】:

  • 如果你的 DLL 不是 ActiveX,我不明白你为什么认为这样的事情是可能的。
  • @manuell 我不认为这是可能的。我希望它是(以某种方式)。我会接受任何令人信服的回答,说这是不可能
  • 你用的是nodejs还是什么?
  • 只使用 plian JScript 运行使用 Windows Script HostJScript Language Reference

标签: dll jscript


【解决方案1】:

你也可以给Gilles Laurent's DynaWrap 抓住机会。

这种dll需要在regsvr32 /s DynaWrap.dll这样的目标系统上注册。

它仅限于 32 位 DLL,这可能不方便您使用,但它适用于 64 位 Windows。您无法访问按序数导出的函数,也无法直接处理 64 位或更大的值/指针。

这是一个从 JScript 调用 MessageBoxA 的示例:

var oDynaWrap = new ActiveXObject( "DynamicWrapper" )

// to call MessageBoxA(), first register the API function
oDynaWrap.Register( "USER32.DLL", "MessageBoxA", "I=HsSu", "f=s", "R=l" )

// now call the function
oDynaWrap.MessageBoxA( null, "MessageBoxA()", "A messagebox from JScript...", 3 )

这里来自 VBScript:

Option Explicit
Dim oDynaWrap
Set oDynaWrap = CreateObject( "DynamicWrapper" )

' to call MessageBoxA(), first register the API function
UserWrap.Register "USER32.DLL", "MessageBoxA", "I=HsSu", "f=s", "R=l"

' now call the function
UserWrap.MessageBoxA Null, "MessageBoxA()", "A messagebox from VBScript...", 3

要使用函数,您需要“注册”您的 DLL 的导出函数。 为此,您需要使用第一个参数调用 register 方法,其中第一个参数包含指向 DLL 完整路径的字符串对象,第二个参数用于导出要使用的函数的名称,以及以下三个以某种方式描述函数声明的参数晦涩的语法。

i=描述了函数参数的个数和数据类型。

f= 描述呼叫类型:_stdcall_cdecl。默认为_stdcall

r= 描述了返回值数据类型。

支持的数据类型有:

Code  Variant      Description

a     VT_DISPATCH  IDispatch*
b     VT_BOOL      BOOL
c     VT_I4        unsigned char
d     VT_R8        8 byte real
f     VT_R4        4 byte real
h     VT_I4        HANDLE
k     VT_UNKNOWN   IUnknown*
l     VT_I4        LONG
p     VT_PTR       pointer
r     VT_LPSTR     string by reference
s     VT_LPSTR     string
t     VT_I2        SHORT
u     VT_UINT      UINT
w     VT_LPWSTR    wide string

因此,示例中使用的Register 方法调用描述MessageBoxA 如下:

_stdcall LONG MessageBoxA( HANDLE, LPSTR, LPSTR, UINT );

有关 MessageBoxA 的说明,请查看MSDN 上的文档。

请阅读 DynaWrap 文档以获取更复杂的示例...但您可能需要 Google 翻译,因为它们是用法语编写的 ;-)

【讨论】:

    【解决方案2】:

    您可以为此目的导出特定函数。 然后,从您的 JScript 中执行 rundll32.exe 并检查该函数是否按预期运行。

    【讨论】:

      【解决方案3】:

      为了能够将 dll 用作 ActiveXObject,它需要是 registered as COM object。对此有一些限制,但如果您有此 dll 的代码,那当然是可行的。

      当您将 dll 注册为 COM 对象时,它会被分配一个名称。您使用此名称来创建对象。这个example from MSDN 使用excel,因为如果你安装了office,它已经注册了。

      var ExcelApp = new ActiveXObject("Excel.Application");
      var ExcelSheet = new ActiveXObject("Excel.Sheet");
      // Make Excel visible through the Application object.
      ExcelSheet.Application.Visible = true;
      // Place some text in the first cell of the sheet.
      ExcelSheet.ActiveSheet.Cells(1,1).Value = "This is column A, row 1";
      // Save the sheet.
      ExcelSheet.SaveAs("C:\\TEST.XLS");
      // Close Excel with the Quit method on the Application object.
      ExcelSheet.Application.Quit();
      

      除了注册dll的限制外,使用dll与使用c++或c#dll没有区别。请注意,C#(或其他 .NET dll)应该是 ComVisible 才能通过这种方式从 javascript 中使用。

      编辑:从 javascript 使用 C/C++ dll 的唯一其他方法是 swig 接口。我没用过,所以只能给你指个方向。

      SWIG 是一种软件开发工具,用于连接以 C 和 C++ 具有多种高级编程语言。 SWIG 是 与不同类型的目标语言一起使用,包括常见的 脚本语言,例如 Javascript、Perl、PHP、Python、Tcl 和 红宝石。

      【讨论】:

      • 10 倍的帮助。然而,这个答案并不能帮助我以任何方式解决我的问题。我很清楚如何使用ActiveXObject,所以这个例子并没有真正帮助我。如果你有一段加载 DLL 的 JScript 代码,请分享。