如何使用dwscript调用CreateOleObject函数?

5
我正在尝试在dwscript内执行此代码(这是一个使用CreateOleObject的最小示例)。
function GetFileVersion(const FileName: string): string;
var
  V : OleVariant;
begin
  V  := CreateOleObject('Scripting.FileSystemObject');
  Result := V.GetFileVersion(FileName);
end;

到目前为止,我尝试过以下方法:

{$APPTYPE CONSOLE}

{$R *.res}


uses
  SysUtils,
  ComObj,
  ActiveX,
  dwsComp,
  dwsCompiler,
  dwsExprs,
  dwsCoreExprs;


procedure Execute;
var
  LScript: TDelphiWebScript;
  LUnit: TdwsUnit;
  LProg: IdwsProgram;
  LExec: IdwsProgramExecution;
begin
  LScript := TDelphiWebScript.Create(NIL);
  LUnit := TdwsUnit.Create(NIL);
  try
    LUnit.UnitName := 'Foo';
    LUnit.Script := LScript;
    //  compile a simple script
    LProg := LScript.Compile(
      'function GetFileVersion(const FileName: string): string;'+sLineBreak+
      'var'+sLineBreak+
      '   V : Variant;'+sLineBreak+
      'begin'+sLineBreak+
      ' V  := CreateOleObject(''Scripting.FileSystemObject'');'+sLineBreak+
      ' Result := V.GetFileVersion(FileName);'+sLineBreak+
      'end;'+sLineBreak+
      ''+sLineBreak+
      'PrintLn(GetFileVersion(''Foo''));'+sLineBreak+
      ''
    );

    if LProg.Msgs.HasErrors then begin
      Writeln(LProg.Msgs.AsInfo);
      Exit;
    end;

    try
      LExec := LProg.Execute;
    except
      on E: Exception do
        WriteLn(E.Message + sLineBreak + LExec.Msgs.AsInfo );
    end;
    Writeln(LExec.Result.ToString);
  finally
    LScript.Free;
  end;
end;

begin
  try
    Execute;
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

但我遇到了以下错误信息:

语法错误:未知名称“CreateOleObject”[行:5,列:8]

问题是我如何使用dwscript执行CreateOleObject函数?

更新

根据Linas的建议,我终于解决了这个问题。

下面是一个可用的示例应用程序

uses
  SysUtils,
  ComObj,
  ActiveX,
  dwsComp,
  dwsCompiler,
  dwsExprs,
  dwsComConnector,
  dwsCoreExprs;


procedure Execute;
var
  LScript: TDelphiWebScript;
  LUnit: TdwsUnit;
  LProg: IdwsProgram;
  LExec: IdwsProgramExecution;
  LdwsComConnector : TdwsComConnector;
begin
  LScript := TDelphiWebScript.Create(NIL);
  LdwsComConnector:=TdwsComConnector.Create(nil);
  LdwsComConnector.Script:=LScript;
  LUnit := TdwsUnit.Create(NIL);
  try
    LUnit.UnitName := 'Foo';
    LUnit.Script := LScript;
    //  compile a simple script
    LProg := LScript.Compile(
      'function GetFileVersion(const FileName: string): string;'+sLineBreak+
      'var'+sLineBreak+
      '   V : OleVariant;'+sLineBreak+
      'begin'+sLineBreak+
      ' V  := CreateOleObject(''Scripting.FileSystemObject'');'+sLineBreak+
      ' Result := VarToStr(V.GetFileVersion(FileName));'+sLineBreak+
      'end;'+sLineBreak+
      ''+sLineBreak+
      'PrintLn(GetFileVersion(''C:\Bar\Foo.exe''));'+sLineBreak+
      ''
    );

    if LProg.Msgs.HasErrors then begin
      Writeln(LProg.Msgs.AsInfo);
      Exit;
    end;

    try
      LExec := LProg.Execute;
    except
      on E: Exception do
        WriteLn(E.Message + sLineBreak + LExec.Msgs.AsInfo );
    end;
    Writeln(LExec.Result.ToString);
  finally
    LScript.Free;
    LdwsComConnector.Free;
  end;
end;

begin
 try
    CoInitialize(nil);
    try
      Execute;
      Readln;
    finally
      CoUninitialize;
    end;
 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
end.

我刚刚添加了那个单元,结果却是相同的 :(. - Salvador
我猜测一下,请将以下 uses 指令添加到您的文件中:uses Windows, Classes, SysUtils, dwsComp, dwsCompiler, dwsExprs, dwsComConnector, Variants, ActiveX, ComObj, dwsXPlatform, dwsUtils; - LU RD
看看这个单元测试是如何使用CreateOleObject的:UCOMConnectorTests - LU RD
@LURD,我没有看到在测试中任何脚本调用CreateOleObject的地方。它是在Delphi代码中被调用以将项目添加到数据库中。 - Rob Kennedy
@RobKennedy,我认为你是完全正确的。 - LU RD
如果您无法直接从DWScript使用CreateOleObject,那么您可以创建自己的“包装器”函数来调用它,并将该包装器函数暴露给DWScript... 这可能是一种比较麻烦的方法,但应该可以工作?(免责声明:我只是阅读了关于DWScript的资料)。 - Marjan Venema
1个回答

2
这可以通过两种方式实现。 第一种方式:您必须将TdwsComConnector(来自单位dwsComConnector)拖放到数据模块或表单中(或手动创建),并将脚本实例分配给它。例如:
dwsComConnector1.Script := LScript;

双向:

interface

uses
  dwsFunctions, dwsSymbols, dwsExprs;

type
  TCreateOleObjectFunc = class(TInternalFunction)
    procedure Execute(info : TProgramInfo); override;
  end;

implementation

uses 
  OleAuto;

{ TCreateOleObjectFunc }

procedure TCreateOleObjectFunc.Execute(info : TProgramInfo);
begin
  Info.ResultAsVariant := CreateOleObject(Info.ValueAsString['ClassName']);
end;

initialization
  RegisterInternalFunction(TCreateOleObjectFunc, 'CreateOleObject', ['ClassName', cString], cVariant, True);

这将会在DWScript中暴露CreateOleObject函数,这样你就可以使用它了。
另外,你应该将V声明为OleVariant而不是Variant,并将代码行更改为Result := VarToStr(V.GetFileVersion(FileName));以使其正常工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接