Recent

Author Topic: SOLVED: About VBScript & WScript code  (Read 610 times)

SaraT

  • Jr. Member
  • **
  • Posts: 54
  • A little student
SOLVED: About VBScript & WScript code
« on: February 15, 2020, 12:47:08 am »
Hi guys :) hope you are ok

I have some little projects in VBScript code (.bat or .cmd files).
But I would like to excecute these codes using Lazarus.

Is there any plugin to do this? Or give me please a great idea.
Many thanks ;)
« Last Edit: February 15, 2020, 09:18:35 pm by SaraT »

winni

  • Hero Member
  • *****
  • Posts: 888
Re: About VBScript code
« Reply #1 on: February 15, 2020, 12:54:47 am »
Hi!

There are some different ways to do that in Lazarus.

Depends: Do you need the output or not?

Read this page - introduction with examples:

https://wiki.freepascal.org/Executing_External_Programs

Keep on hacking

Winni
« Last Edit: February 15, 2020, 01:04:29 am by winni »

SaraT

  • Jr. Member
  • **
  • Posts: 54
  • A little student
Re: About VBScript code
« Reply #2 on: February 15, 2020, 12:59:35 am »
Hi!

There are some different ways to do that in Lazarus.

Depends: Do you need the output or not?

Read this page - introduction with example:

https://wiki.freepascal.org/Executing_External_Programs

Keep on hacking

Winni

Thanks Winni ;)
Yes with the output... need it in some VBScript commands, Do you recommend something special for the output?
Give me your hacks... I will check out your link.

Best regards

winni

  • Hero Member
  • *****
  • Posts: 888
Re: About VBScript code
« Reply #3 on: February 15, 2020, 01:20:42 am »
Hi!

From the above mentioned page I modified the example to execute any type of executable and read the output.

Hint:   In the
Code: Pascal  [Select]
  1. opt: array of string;
  2.  

there is no space (#32) allowed. Split the  option in two strings.

The output of your script/program is in the string list sl.


Code: Pascal  [Select]
  1. procedure ExecuteRead(exe: string; opt: array of string; var sl: TStringlist);
  2.     const
  3.       BufSize = 2048;
  4.  
  5.     var
  6.       AProcess : TProcess;
  7.       OutputStream : TStream;
  8.       BytesRead :longint;
  9.       Buffer : array[1..BUFSIZE] of byte;
  10.       i : integer;
  11.     begin
  12.       AProcess := TProcess.Create(nil);
  13.       AProcess.Executable := exe;
  14.       for i := low(opt) to high(opt) do AProcess.Parameters.Add(opt[i]);
  15.       AProcess.Options := [poUsePipes,poStderrToOutPut, poWaitOnExit ];
  16.       AProcess.Execute;
  17.  
  18.       OutputStream := TMemoryStream.Create;
  19.  
  20.       repeat
  21.         BytesRead := AProcess.Output.Read(Buffer, BUFSIZE);
  22.         OutputStream.Write(Buffer, BytesRead)
  23.       until BytesRead = 0;
  24.  
  25.       AProcess.Free;
  26.  
  27.       sl := TStringList.Create;
  28.       with sl do
  29.       begin
  30.         OutputStream.Position := 0;
  31.         LoadFromStream(OutputStream);
  32.       end;
  33.       OutputStream.Free;
  34.     end;
  35.  


Example how to call it   :

Code: Pascal  [Select]
  1. ExecuteRead('/usr/sbin/ip', ['-4', 'a'], sl);
   

calls (linux) ip with parameters -4 and a

Winni

SaraT

  • Jr. Member
  • **
  • Posts: 54
  • A little student
Re: About VBScript code
« Reply #4 on: February 15, 2020, 01:31:59 am »
Hi!

From the above mentioned page I modified the example to execute any type of executable and read the output.

Hint:   In the
Code: Pascal  [Select]
  1. opt: array of string;
  2.  

there is no space (#32) allowed. Split the  option in two strings.

The output of your script/program is in the string list sl.


Code: Pascal  [Select]
  1. procedure ExecuteRead(exe: string; opt: array of string; var sl: TStringlist);
  2.     const
  3.       BufSize = 2048;
  4.  
  5.     var
  6.       AProcess : TProcess;
  7.       OutputStream : TStream;
  8.       BytesRead :longint;
  9.       Buffer : array[1..BUFSIZE] of byte;
  10.       i : integer;
  11.     begin
  12.       AProcess := TProcess.Create(nil);
  13.       AProcess.Executable := exe;
  14.       for i := low(opt) to high(opt) do AProcess.Parameters.Add(opt[i]);
  15.       AProcess.Options := [poUsePipes,poStderrToOutPut, poWaitOnExit ];
  16.       AProcess.Execute;
  17.  
  18.       OutputStream := TMemoryStream.Create;
  19.  
  20.       repeat
  21.         BytesRead := AProcess.Output.Read(Buffer, BUFSIZE);
  22.         OutputStream.Write(Buffer, BytesRead)
  23.       until BytesRead = 0;
  24.  
  25.       AProcess.Free;
  26.  
  27.       sl := TStringList.Create;
  28.       with sl do
  29.       begin
  30.         OutputStream.Position := 0;
  31.         LoadFromStream(OutputStream);
  32.       end;
  33.       OutputStream.Free;
  34.     end;
  35.  


Example how to call it   :

Code: Pascal  [Select]
  1. ExecuteRead('/usr/sbin/ip', ['-4', 'a'], sl);
   

calls (linux) ip with parameters -4 and a

Winni

So cool Winni :)
Just one question...

['-4', 'a']... what does this mean (-4 & a)?

This is not clear to me. I don't know how to identify the options to use.
Many thanks... you are a genius :)

I'm going to try the code.

winni

  • Hero Member
  • *****
  • Posts: 888
Re: About VBScript code
« Reply #5 on: February 15, 2020, 01:45:55 am »
Hi!

Seems you live in the Windows World.

The line
Code: Pascal  [Select]
  1. ExecuteRead('/usr/sbin/ip',['-4', 'a'],sl);
means on the command line

/usr/sbin/ip -4 a 


A WinDOS example:  list a directory with subdirectories.
You do:

DIR /S

With my ExecuteRead you would do

ExecuteRead('DIR', ['/S'], sl);

And in the StringList sl is the complete contents of the listed directory.

Got it?

Winni

SaraT

  • Jr. Member
  • **
  • Posts: 54
  • A little student
Re: About VBScript code
« Reply #6 on: February 15, 2020, 05:21:36 am »
Yes Winni, understood :)

Look... The below code is for reading the SO version in WScript
Does it work with your code? Maybe .vbs files... Some way to make it work?

I wanna know if Lazarus can excecute these kind of code.
Thanks Winni

Code: Text  [Select]
  1. Set dtmConvertedDate = CreateObject("WbemScripting.SWbemDateTime")
  2.  
  3. strComputer = "."
  4. Set objWMIService = GetObject("winmgmts:" _
  5.     & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
  6.  
  7. Set colOperatingSystems = objWMIService.ExecQuery _
  8.     ("Select * from Win32_OperatingSystem")
  9.  
  10. For Each objOperatingSystem in colOperatingSystems
  11.   Wscript.Echo "Version: " & objOperatingSystem.Version
  12. Next
« Last Edit: February 15, 2020, 06:06:23 am by SaraT »

Thaddy

  • Hero Member
  • *****
  • Posts: 9625
Re: About VBScript code
« Reply #7 on: February 15, 2020, 07:16:55 am »
That is possible but with a slightly different syntax. FreePascal supports late bound com objects (as well as early bound com objects).
You can even embed the vbscript engine if necessary.
I am more like donkey than shrek

SaraT

  • Jr. Member
  • **
  • Posts: 54
  • A little student
Re: About VBScript code
« Reply #8 on: February 15, 2020, 02:34:48 pm »
That is possible but with a slightly different syntax. FreePascal supports late bound com objects (as well as early bound com objects).
You can even embed the vbscript engine if necessary.

Thanks Thaddy, if this is possible, How can we do that?
We can try with the code in my previous post.

Thanks guys, for your time ;)
« Last Edit: February 15, 2020, 02:43:13 pm by SaraT »

Thaddy

  • Hero Member
  • *****
  • Posts: 9625
Re: About VBScript & WScript code
« Reply #9 on: February 15, 2020, 02:41:22 pm »
I wrote a KOL Delphi version about 20 years ago. http://members.chello.nl/t.koning8/kolaxscript.zip
You need to adapt it back to fcl/vcl - quite easy for experienced programmers - , unless you download the kol library and use it as--is..

This was an authorized translation from Serhiy Perevozny's Delphi code. Google him. That original code may also still be available. (Torry?)
« Last Edit: February 15, 2020, 02:56:41 pm by Thaddy »
I am more like donkey than shrek

SaraT

  • Jr. Member
  • **
  • Posts: 54
  • A little student
Re: About VBScript & WScript code
« Reply #10 on: February 15, 2020, 02:55:10 pm »
Thanks, I will check out your code, although I am not an expert in Delphi.
I will try to do someyhing. If somebody else have new idea, I will be grateful.
Best regards
« Last Edit: February 15, 2020, 02:56:48 pm by SaraT »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7927
Re: About VBScript code
« Reply #11 on: February 15, 2020, 03:03:05 pm »
Yes Winni, understood :)

Look... The below code is for reading the SO version in WScript
Does it work with your code? Maybe .vbs files... Some way to make it work?

I wanna know if Lazarus can excecute these kind of code.
Thanks Winni

Code: Text  [Select]
  1. Set dtmConvertedDate = CreateObject("WbemScripting.SWbemDateTime")
  2.  
  3. strComputer = "."
  4. Set objWMIService = GetObject("winmgmts:" _
  5.     & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
  6.  
  7. Set colOperatingSystems = objWMIService.ExecQuery _
  8.     ("Select * from Win32_OperatingSystem")
  9.  
  10. For Each objOperatingSystem in colOperatingSystems
  11.   Wscript.Echo "Version: " & objOperatingSystem.Version
  12. Next

Requires FPC trunk as of 12:00 CET today, because I did a fix, but this:

Code: Pascal  [Select]
  1. {$mode delphi}
  2.  
  3. uses windows,variants,sysutils,activex,comobj;
  4.  
  5. var
  6.   objWMIService : OLEVariant;
  7.   dtmConvertedDate : OLEVariant;
  8.  
  9.   colItems      : OLEVariant;
  10.   colItem       :  OLEVariant;
  11.   oEnum         : IEnumvariant;
  12.   iValue        : LongWord;
  13.   strComputer : Widestring;
  14.  
  15.   function GetWMIObject(const objectName: String): IDispatch;
  16.   var
  17.     chEaten: ULONG;
  18.     BindCtx: IBindCtx;
  19.     Moniker: IMoniker;
  20.   begin
  21.     OleCheck(CreateBindCtx(0, bindCtx));
  22.     OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), pulong(@chEaten), Moniker));
  23.     OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
  24.   end;
  25. begin
  26.     dtmConvertedDate := CreateOleObject('WbemScripting.SWbemDateTime');
  27.      
  28.     strComputer := '.';
  29.     objWMIService := GetWMIObject('winmgmts:{impersonationLevel=impersonate}!\\'+strComputer+'\root\cimv2');
  30.     colItems      := objWMIService.ExecQuery('Select * from Win32_OperatingSystem'); // ,'WQL',0);
  31.  
  32.     // vbscript FOR works with _NewEnum operator. We need to write that out, but maybe we can make a wrapper for this using a record and for..in support?
  33.     oEnum         := IUnknown(colItems._NewEnum) as IEnumVariant;
  34.     while oEnum.Next(1, colItem, iValue) = 0 do
  35.        writeln('Version: ',colitem.Version);
  36. end.
  37.  

prints

Version: 10.0.18362

SaraT

  • Jr. Member
  • **
  • Posts: 54
  • A little student
Re: About VBScript code
« Reply #12 on: February 15, 2020, 03:12:19 pm »
Yes Winni, understood :)

Look... The below code is for reading the SO version in WScript
Does it work with your code? Maybe .vbs files... Some way to make it work?

I wanna know if Lazarus can excecute these kind of code.
Thanks Winni

Code: Text  [Select]
  1. Set dtmConvertedDate = CreateObject("WbemScripting.SWbemDateTime")
  2.  
  3. strComputer = "."
  4. Set objWMIService = GetObject("winmgmts:" _
  5.     & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
  6.  
  7. Set colOperatingSystems = objWMIService.ExecQuery _
  8.     ("Select * from Win32_OperatingSystem")
  9.  
  10. For Each objOperatingSystem in colOperatingSystems
  11.   Wscript.Echo "Version: " & objOperatingSystem.Version
  12. Next

Requires FPC trunk as of 12:00 CET today, because I did a fix, but this:

Code: Pascal  [Select]
  1. {$mode delphi}
  2.  
  3. uses windows,variants,sysutils,activex,comobj;
  4.  
  5. var
  6.   objWMIService : OLEVariant;
  7.   dtmConvertedDate : OLEVariant;
  8.  
  9.   colItems      : OLEVariant;
  10.   colItem       :  OLEVariant;
  11.   oEnum         : IEnumvariant;
  12.   iValue        : LongWord;
  13.   strComputer : Widestring;
  14.  
  15.   function GetWMIObject(const objectName: String): IDispatch;
  16.   var
  17.     chEaten: ULONG;
  18.     BindCtx: IBindCtx;
  19.     Moniker: IMoniker;
  20.   begin
  21.     OleCheck(CreateBindCtx(0, bindCtx));
  22.     OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), pulong(@chEaten), Moniker));
  23.     OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
  24.   end;
  25. begin
  26.     dtmConvertedDate := CreateOleObject('WbemScripting.SWbemDateTime');
  27.      
  28.     strComputer := '.';
  29.     objWMIService := GetWMIObject('winmgmts:{impersonationLevel=impersonate}!\\'+strComputer+'\root\cimv2');
  30.     colItems      := objWMIService.ExecQuery('Select * from Win32_OperatingSystem'); // ,'WQL',0);
  31.  
  32.     // vbscript FOR works with _NewEnum operator. We need to write that out, but maybe we can make a wrapper for this using a record and for..in support?
  33.     oEnum         := IUnknown(colItems._NewEnum) as IEnumVariant;
  34.     while oEnum.Next(1, colItem, iValue) = 0 do
  35.        writeln('Version: ',colitem.Version);
  36. end.
  37.  

prints

Version: 10.0.18362

Great... Many thanks, sorry fpr the question but
Does this code work on Lazarus? I say it because of in the first line says Mode Delphi
And I am not in my PC right now to try it. Maybe in 2 hours.

Best regards :)
« Last Edit: February 15, 2020, 03:32:05 pm by SaraT »

lucamar

  • Hero Member
  • *****
  • Posts: 2383
Re: About VBScript code
« Reply #13 on: February 15, 2020, 04:19:54 pm »
Does this code work on Lazarus? I say it because of in the first line says Mode Delphi

The fact that it has a {$mode ....} line says it's a FPC/Lazarus source; AFAIK Delphi doesn't recognize that directive, which is why you'll frequently see it as a
Code: Pascal  [Select]
  1. {$ifdef fpc}{$mode delphi}{$endif}
block in dual-compilable (FPC + Delphi) projects. :)

« Last Edit: February 15, 2020, 04:22:39 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus 2.0.4/2.0.6  - FPC 3.0.4 on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

SaraT

  • Jr. Member
  • **
  • Posts: 54
  • A little student
Re: About VBScript code
« Reply #14 on: February 15, 2020, 05:13:42 pm »

Code: Pascal  [Select]
  1. {$mode delphi}
  2.  
  3. uses windows,variants,sysutils,activex,comobj;
  4.  
  5. var
  6.   objWMIService : OLEVariant;
  7.   dtmConvertedDate : OLEVariant;
  8.  
  9.   colItems      : OLEVariant;
  10.   colItem       :  OLEVariant;
  11.   oEnum         : IEnumvariant;
  12.   iValue        : LongWord;
  13.   strComputer : Widestring;
  14.  
  15.   function GetWMIObject(const objectName: String): IDispatch;
  16.   var
  17.     chEaten: ULONG;
  18.     BindCtx: IBindCtx;
  19.     Moniker: IMoniker;
  20.   begin
  21.     OleCheck(CreateBindCtx(0, bindCtx));
  22.     OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), pulong(@chEaten), Moniker));
  23.     OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));
  24.   end;
  25. begin
  26.     dtmConvertedDate := CreateOleObject('WbemScripting.SWbemDateTime');
  27.      
  28.     strComputer := '.';
  29.     objWMIService := GetWMIObject('winmgmts:{impersonationLevel=impersonate}!\\'+strComputer+'\root\cimv2');
  30.     colItems      := objWMIService.ExecQuery('Select * from Win32_OperatingSystem'); // ,'WQL',0);
  31.  
  32.     // vbscript FOR works with _NewEnum operator. We need to write that out, but maybe we can make a wrapper for this using a record and for..in support?
  33.     oEnum         := IUnknown(colItems._NewEnum) as IEnumVariant;
  34.     while oEnum.Next(1, colItem, iValue) = 0 do
  35.        writeln('Version: ',colitem.Version);
  36. end.
  37.  

prints

Version: 10.0.18362

Thanks marcov, your code works like a charm... ;)
Something else... Can you convert this simple code to Lazarus? please.
(Yes, I already know we can do this through Lazarus directly. I just want to see the convertion from .vbs.)
 
This code is to see if a file is read-only and, if it is not, marks it as read-only.
Best regards.

Code: Text  [Select]
  1. Set objFSO = CreateObject("Scripting.FileSystemObject")
  2. Set objFile = objFSO.GetFile("C:\MyFolder\TextFile.txt")
  3.  
  4. If objFile.Attributes = objFile.Attributes AND 1 Then
  5.     objFile.Attributes = objFile.Attributes XOR 1
  6. End If
« Last Edit: February 15, 2020, 05:16:09 pm by SaraT »