AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Windows Scripting Host (WSH)

Windows Scripting Host (WSH)

Ein Thema von himitsu · begonnen am 5. Nov 2023 · letzter Beitrag vom 7. Nov 2023
 
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.556 Beiträge
 
Delphi 12 Athens
 
#2

AW: Windows Scripting Host (WSH)

  Alt 5. Nov 2023, 17:16
Ach ja, alles natürlich auch für Win64.
Viele Beispiele im Internet funktionieren hier nicht, da zwar die Interfaces "gleich" sind, aber Viele eine andere GUID besitzen.

Auch muß beachtet werden, dass installierte Fremd-Sprachen in der jeweiligen Bittigkeit (oder Beides) installiert sein müssen. (zumindestens bei den In-Process-Servern)



So, und hier noch ein winziger nativer Ansatz:
https://stackoverflow.com/questions/...-from-within-c
Delphi-Quellcode:
uses
  System.SysUtils, System.Win.ComObj, System.Types, System.Variants,
  Winapi.ActiveX, h5u.ActiveScripting.Interfaces;

var
  ClassID: TGUID;
  Engine: IActiveScript;
  ASite: IActiveScriptSite;
  Parser: IActiveScriptParse;
  ErrInfo: EXCEPINFO;
  Flags: DWORD;
  OResult: OleVariant;
  Name: WideString;
  Disp: IDispatch;
  HR: HRESULT;
begin
  // https://stackoverflow.com/questions/7491868/how-to-load-call-a-vbscript-function-from-within-c

  //CoInitializeEx(nil, COINIT_MULTITHREADED);

  OleCheck(CLSIDFromProgID(PWideChar('VBScript'), ClassID));
  Engine := CreateComObject(ClassID) as IActiveScript;

  ASite := TDummyNonInteractiveScriptSite.Create; // ODER: ASite := TDummyActiveScriptSite.Create(Self.Handle)
  OleCheck(Engine.SetScriptSite(ASite));
  OleCheck(Engine.QueryInterface(IActiveScriptParse, Parser));
  OleCheck(Parser.InitNew);

  //OleCheck(Parser.AddScriptlet(nil, PWideChar('...'), nil, nil, nil, nil, 0, 0, SCRIPTTEXT_ISVISIBLE, Name, ErrInfo));
  {or}
  //OleCheck(Parser.ParseScriptText(PWideChar('...'), nil, nil, nil, 0, 0, ..., nil, ErrInfo));
  {or}
  //if Failed(Parser.ParseScriptText(PWideChar('...'), nil, nil, nil, 0, 0, ..., nil, ErrInfo)) then
  // raise Exception.CreateFmt('Error $%x: %s', [ErrInfo.scode, ErrInfo.bstrDescription]);
  {or}
  //HR := Parser.ParseScriptText(PWideChar('...'), nil, nil, nil, 0, 0, ..., nil, ErrInfo);
  //if Failed(HR) then
  // raise Exception.CreateFmt('Error $%x %s'#10'$%x: %s', [HR, SysErrorMessage(Cardinal(HR)), ErrInfo.scode, ErrInfo.bstrDescription]);

  //HR := Parser.ParseScriptText(PWideChar('WScript.Echo "abc"'), nil, nil, nil, 0, 0, SCRIPTTEXT_ISVISIBLE, @OResult, ErrInfo);
  HR := Parser.ParseScriptText(PWideChar('set fso = CreateObject("Scripting.FileSystemObject")'#10'set stream = fso.GetStandardStream(1)'#10
    + 'stream.WriteLine("This will go to standard output.")'), nil, nil, nil, 0, 0, SCRIPTTEXT_ISVISIBLE, @OResult, ErrInfo);
  if Failed(HR) then
    raise Exception.CreateFmt('Error $%x %s'#10'$%x: %s', [HR, SysErrorMessage(Cardinal(HR)), ErrInfo.scode, ErrInfo.bstrDescription]);

  HR := Parser.ParseScriptText(PWideChar('a = 123'), nil, nil, nil, 0, 0, SCRIPTTEXT_ISVISIBLE, @OResult, ErrInfo);
  if Failed(HR) then
    raise Exception.CreateFmt('Error $%x %s'#10'$%x: %s', [HR, SysErrorMessage(Cardinal(HR)), ErrInfo.scode, ErrInfo.bstrDescription]);
  //
  HR := Parser.ParseScriptText(PWideChar('a * 2 + 3'), nil, nil, nil, 0, 0, SCRIPTTEXT_ISEXPRESSION, @OResult, ErrInfo);
  if Failed(HR) then
    raise Exception.CreateFmt('Error $%x %s'#10'$%x: %s', [HR, SysErrorMessage(Cardinal(HR)), ErrInfo.scode, ErrInfo.bstrDescription]);
  Writeln('Result = ' + VarToStrDef(OResult, '(NULL)'));
  //
  HR := Parser.ParseScriptText(PWideChar('MsgBox "Hello World! The current time is " & Now'), nil, nil, nil, 0, 0, SCRIPTTEXT_ISVISIBLE, @OResult, ErrInfo);
  if Failed(HR) then
    raise Exception.CreateFmt('Error $%x %s'#10'$%x: %s', [HR, SysErrorMessage(Cardinal(HR)), ErrInfo.scode, ErrInfo.bstrDescription]);

  // Engine.GetScriptDispatch(nil, Disp);

  //CoUninitialize;
end;
Müsste jemand das Script aber nochmal testen ... kann sein, dass SetScriptSite nötig ist und man sich noch ein kleines IActiveScriptSite basteln muß.
Ja, ein IActiveScriptSite muß bereitgestellt werden, aber die Funktionen können quasi leer sein (einfach nur überall Result jeweils mit S_OK, S_FALSE usw. beglücken)
Hab dafür zwei Dummy-Interfaces in die Interface-Unit gepackt und rechts noch Knöpfe "Native-API" in die Demo-/Testanwendung.

Sollen die Scripte auch Interaktiv sein dürfen, dann muß auch IActiveScriptSiteWindow implementiert sein (und OK sagen), sonst raucht es z.B. bei einem MsgBox "peng" mit einer Exception "Erlaubnis verweigert".
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 7. Nov 2023 um 07:09 Uhr)
  Mit Zitat antworten Zitat
 

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:46 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz