Jump to content

Communication between AutoIt and VBScript


Recommended Posts

 I am looking for a two way communication between AutoIt and VBScript.

I need the communication for my PSPad4AutoIt3 project, to communicate between my CallTipViewer and PSPad's VBScript. The communication must be very fast, because the messages are sent/received in a loop that repeats every 10 ms.

A communication in the direction from VBScript to AutoIt I could implement via MailSlot.au3 from trancexx, the other direction, from AutoIt to VBScript not yet. Also I don't know if the MailSlot functions are fast enough, because I couldn't finish rebuilding and testing my code yet.

Now LarsJ mentioned an interesting possibility, which I would like to test.  I created this thread to discuss LarsJ's code.

17 hours ago, LarsJ said:

Data transfer between AutoIt and VBScript can be performed using ROT objects as demonstrated in this example. ROT objects also have the advantage that arrays can be transferred directly and that the internal data type of array elements and other variables is preserved during the data transfer.

Link to comment
Share on other sites

It is a framework.  Lets say au3 is the server.  All the components of the server part of UDF doesn't need to be rewrite, you can reuse them as is.  Now (I am not fluent in VBS, so bare with me), all you have to do is find a way to register the message WM_COPYDATA on the VBS side.  Once it is done, then you can exchange back and forth messages thru this channel.  It will be very fast since it is relying on Windows Messaging System.

Link to comment
Share on other sites

9 minutes ago, Nine said:

It will be very fast since it is relying on Windows Messaging System.

Oh, it sounds so good!

11 minutes ago, Nine said:

all you have to do is find a way to register the message WM_COPYDATA on the VBS side.

My VBScript skills are not small, but far from great, but I think registering the WM_COPYDATA message requires a window. Is that right? Unfortunately, there are no native windows in VBScript.

Link to comment
Share on other sites

27 minutes ago, Professor_Bernd said:

registering the WM_COPYDATA message requires a window. Is that right? Unfortunately, there are no native windows in VBScript.

Yes, it definitely requires a window.  I was under the impression that it was possible with VBS.  You could use this api to create an invisible window, but it is starting to get a tad more complex as you will also need to register a callback function to access its WinProc.  It is so simple in AutoIt.  Sorry.

Link to comment
Share on other sites

If VBS is similar to VBA, the problem with creating a window with CreateWindowEx would be the message loop to keep it alive. (All this is new to me) and I could create a window with VBA in Excel using it, but the window would stop everything else as long as it was active. Now, perhaps I could Application.OnTime to run that code in parallel and perhaps use DoEvents (doesn't exist in VBS as far as I have read after Prof's previous topic). I made a barebone window with one textbox with AutoIT, and used WM_SetText to send whatever. I didn't have a need to return anything back to Excel btw.

This would be one directional though, and you would have to read it once in a while and I remember reading that Prof. couldn't do loops due to the nature of the code?! or is that some other part?

Link to comment
Share on other sites

@Nine

Someone feel free to correct me, but I believe that an exe is needed to create a window. VBScript itself has no exe in this sense. It is possible to create windows with iexplore.exe (Internet Explorer) (Example) respectively mshta.exe (HTA) (Example). But then the problems you mentioned and others occur, so it becomes more and more complex and complicated. I think that in the end the speed of communication is not enough.

13 hours ago, Nine said:

You could use this api to create an invisible window,

As far as I know, VBScript does not have access to the Windows API.

Anyway, thank you for your advice! It adds momentum and further posts often bring more information. :)

Edited by Professor_Bernd
Link to comment
Share on other sites

@GokAy

Unfortunately, VBA and VBScript are not similar. Compared to VBScript, VBS is more "powerful". As already written, VBScript has no access to the Windows API. Thus CreateWindowEx cannot be used. There are two ways to use Windows in VBScript, I linked them in the post above. But unfortunately with a window there are the problems you both mentioned and probably the communication is too slow:

On 12/16/2020 at 2:16 PM, Professor_Bernd said:

I am looking for a two way communication between AutoIt and VBScript.  .... The communication must be very fast, because the messages are sent/received in a loop that repeats every 10 ms.

 

On 12/16/2020 at 10:04 PM, GokAy said:

I remember reading that Prof. couldn't do loops due to the nature of the code?! or is that some other part?

In VBScript you can't run a loop all the time because that has undesirable effects, up to freezing the whole program. But basically you can use loops, which I do, while a CallTip is displayed in PSPad. In this loop is executed about every 10 ms, which sends and reads messages to the CallTipViewer. I do this at the moment using AutoItX, but PSPad4AutoIt is now to become completely portable. Therefore I am looking for another way to communicate.

The possibility mentioned by LarsJ (see first posting) looks promising and I will test it next. Since my knowledge of COM and ROT is quite limited, I'll try to learn the ropes first.

Thanks a lot for your post! :)

Edited by Professor_Bernd
Link to the first posting added.
Link to comment
Share on other sites

I have studied the linked pages, but unfortunately this will probably not work. I'm afraid even if I could get these complicated operations to work, communication would most likely be very slow.

But it was very interesting, especially the information about regsvr42. I can definitely use this info some other time. :)

Thanks a lot for your effort!

Link to comment
Share on other sites

Just made a proof of concept how to communicate between AutoIt and VBS.  It is based on Named Pipes.  My client (VBS) written in AutoIt only uses a COM object available, so it must be a no brainer to translate it into VBS.

Not sure it will be fast enough, but at least now you have a potential solution.

Server (AutoIt) :

#include <NamedPipes.au3>
#include <Constants.au3>
#include <WinAPIFiles.au3>

Local $hNamedPipe = _NamedPipes_CreateNamedPipe("\\.\pipe\pipename", 2, 1)
ConsoleWrite ($hNamedPipe & @CRLF)
$test = _NamedPipes_ConnectNamedPipe($hNamedPipe)
ConsoleWrite ($test & @CRLF)

Local $tBuffer = DllStructCreate("char Text[" & 100 & "]"), $iRead, $iWritten
$pBuffer = DllStructGetPtr($tBuffer)
$bSuccess = _WinAPI_ReadFile($hNamedPipe, $pBuffer, 100, $iRead)
ConsoleWrite (DllStructGetData($tBuffer, "Text") & @CRLF)
_NamedPipes_DisconnectNamedPipe ($hNamedPipe)

$test = _NamedPipes_ConnectNamedPipe($hNamedPipe)
ConsoleWrite ($test & @CRLF)
DllStructSetData($tBuffer, "Text", "Reponse" & @CRLF)
$bSuccess = _WinAPI_WriteFile($hNamedPipe, $pBuffer, 9, $iWritten)
If Not $bSuccess Then ConsoleWrite (_WinAPI_GetLastError() & @CRLF)
ConsoleWrite ($bSuccess & @CRLF)
_NamedPipes_DisconnectNamedPipe ($hNamedPipe)

Client (VBS) :

Local $oFileSys = ObjCreate("Scripting.FileSystemObject")
$oTSF = $oFileSys.OpenTextFile("\\.\pipe\pipename", 2, True, 0)
$oTSF.WriteLine("Ceci est un test")
$oTSF.Close

Sleep (50)

$oTSF = $oFileSys.OpenTextFile("\\.\pipe\pipename", 1, True, 0)
$sText = $oTSF.Readline()
$oTSF.Close()
MsgBox (0,"",$sText & @CRLF)

 

Link to comment
Share on other sites

2 hours ago, Nine said:

Just made a proof of concept how to communicate between AutoIt and VBS.  It is based on Named Pipes.  My client (VBS) written in AutoIt only uses a COM object available, so it must be a no brainer to translate it into VBS.

Not sure it will be fast enough, but at least now you have a potential solution.

Server (AutoIt) :

#include <NamedPipes.au3>
#include <Constants.au3>
#include <WinAPIFiles.au3>

Local $hNamedPipe = _NamedPipes_CreateNamedPipe("\\.\pipe\pipename", 2, 1)
ConsoleWrite ($hNamedPipe & @CRLF)
$test = _NamedPipes_ConnectNamedPipe($hNamedPipe)
ConsoleWrite ($test & @CRLF)

Local $tBuffer = DllStructCreate("char Text[" & 100 & "]"), $iRead, $iWritten
$pBuffer = DllStructGetPtr($tBuffer)
$bSuccess = _WinAPI_ReadFile($hNamedPipe, $pBuffer, 100, $iRead)
ConsoleWrite (DllStructGetData($tBuffer, "Text") & @CRLF)
_NamedPipes_DisconnectNamedPipe ($hNamedPipe)

$test = _NamedPipes_ConnectNamedPipe($hNamedPipe)
ConsoleWrite ($test & @CRLF)
DllStructSetData($tBuffer, "Text", "Reponse" & @CRLF)
$bSuccess = _WinAPI_WriteFile($hNamedPipe, $pBuffer, 9, $iWritten)
If Not $bSuccess Then ConsoleWrite (_WinAPI_GetLastError() & @CRLF)
ConsoleWrite ($bSuccess & @CRLF)
_NamedPipes_DisconnectNamedPipe ($hNamedPipe)

Client (VBS) :

Local $oFileSys = ObjCreate("Scripting.FileSystemObject")
$oTSF = $oFileSys.OpenTextFile("\\.\pipe\pipename", 2, True, 0)
$oTSF.WriteLine("Ceci est un test")
$oTSF.Close

Sleep (50)

$oTSF = $oFileSys.OpenTextFile("\\.\pipe\pipename", 1, True, 0)
$sText = $oTSF.Readline()
$oTSF.Close()
MsgBox (0,"",$sText & @CRLF)

 

is not it another new IPC not enlilsted in WIKI UDF LIST ;)

 

Signature beginning:
Please remember: "AutoIt"..... *  Wondering who uses AutoIt and what it can be used for ? * Forum Rules *
ADO.au3 UDF * POP3.au3 UDF * XML.au3 UDF * IE on Windows 11 * How to ask ChatGPT for AutoIt Codefor other useful stuff click the following button:

Spoiler

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind. 

My contribution (my own projects): * Debenu Quick PDF Library - UDF * Debenu PDF Viewer SDK - UDF * Acrobat Reader - ActiveX Viewer * UDF for PDFCreator v1.x.x * XZip - UDF * AppCompatFlags UDF * CrowdinAPI UDF * _WinMergeCompare2Files() * _JavaExceptionAdd() * _IsBeta() * Writing DPI Awareness App - workaround * _AutoIt_RequiredVersion() * Chilkatsoft.au3 UDF * TeamViewer.au3 UDF * JavaManagement UDF * VIES over SOAP * WinSCP UDF * GHAPI UDF - modest begining - comunication with GitHub REST APIErrorLog.au3 UDF - A logging Library * Include Dependency Tree (Tool for analyzing script relations) * Show_Macro_Values.au3 *

 

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 UDF * ADO.au3 UDF SMTP Mailer UDF * Dual Monitor resolution detection * * 2GUI on Dual Monitor System * _SciLexer.au3 UDF * SciTE - Lexer for console pane

Useful links: * Forum Rules * Forum etiquette *  Forum Information and FAQs * How to post code on the forum * AutoIt Online Documentation * AutoIt Online Beta Documentation * SciTE4AutoIt3 getting started * Convert text blocks to AutoIt code * Games made in Autoit * Programming related sites * Polish AutoIt Tutorial * DllCall Code Generator * 

Wiki: Expand your knowledge - AutoIt Wiki * Collection of User Defined Functions * How to use HelpFile * Good coding practices in AutoIt * 

OpenOffice/LibreOffice/XLS Related: WriterDemo.au3 * XLS/MDB from scratch with ADOX

IE Related:  * How to use IE.au3  UDF with  AutoIt v3.3.14.x * Why isn't Autoit able to click a Javascript Dialog? * Clicking javascript button with no ID * IE document >> save as MHT file * IETab Switcher (by LarsJ ) * HTML Entities * _IEquerySelectorAll() (by uncommon) * IE in TaskSchedulerIE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) * PDF Related:How to get reference to PDF object embeded in IE * IE on Windows 11

I encourage you to read: * Global Vars * Best Coding Practices * Please explain code used in Help file for several File functions * OOP-like approach in AutoIt * UDF-Spec Questions *  EXAMPLE: How To Catch ConsoleWrite() output to a file or to CMD *

I also encourage you to check awesome @trancexx code:  * Create COM objects from modules without any demand on user to register anything. * Another COM object registering stuffOnHungApp handlerAvoid "AutoIt Error" message box in unknown errors  * HTML editor

winhttp.au3 related : * https://www.autoitscript.com/forum/topic/206771-winhttpau3-download-problem-youre-speaking-plain-http-to-an-ssl-enabled-server-port/

"Homo sum; humani nil a me alienum puto" - Publius Terentius Afer
"Program are meant to be read by humans and only incidentally for computers and execute" - Donald Knuth, "The Art of Computer Programming"
:naughty:  :ranting:, be  :) and       \\//_.

Anticipating Errors :  "Any program that accepts data from a user must include code to validate that data before sending it to the data store. You cannot rely on the data store, ...., or even your programming language to notify you of problems. You must check every byte entered by your users, making sure that data is the correct type for its field and that required fields are not empty."

Signature last update: 2023-04-24

Link to comment
Share on other sites

option explicit

Dim StartTime, DiffTime
Dim oFileSys, oTSF, sText

StartTime = Timer

Set oFileSys = WScript.CreateObject("Scripting.FileSystemObject")
Set oTSF = oFileSys.OpenTextFile("\\.\pipe\pipename", 2, True, 0)
oTSF.WriteLine("Ceci est un test")
oTSF.Close

WScript.Sleep(50)

oTSF = oFileSys.OpenTextFile("\\.\pipe\pipename", 1, True, 0)

' do
  sText = oTSF.Readline()
'   If sText <> "" Then Exit Do
' loop until Timer - Starttime > 4 ' runs for 4 seconds

oTSF.Close()
MsgBox(sText & vbCRLF)

Hello Nine.

I have rewritten your code in VBScript and tested it. Unfortunately the result is like in my tests with other pipe codes: An error is generated that the file would not be found.

For testing you can save my code to a .vbs file, then start your .au3 first and double click the .vbs afterwards. An error message will appear.

But don't spend too much time on this code. My feeling is that the option LarsJ mentioned is more suitable. In the last days I had no time to deal with it. In the next days I will hopefully find more time and study the code of LarsJ. Then I will definitely need more help.

Thanks a lot for your effort! 👍

Link to comment
Share on other sites

36 minutes ago, GokAy said:

Shouldn't you be "set"ting it here as well?

Yes you are right.  Setting it solve the problem, now working as expected with :

option explicit

Dim oFileSys, oTSF, sText

Set oFileSys = WScript.CreateObject("Scripting.FileSystemObject")
Set oTSF = oFileSys.OpenTextFile("\\.\pipe\pipename", 2, True, 0)
oTSF.WriteLine("Ceci est un test")
oTSF.Close

WScript.Sleep(50)

Set oTSF = oFileSys.OpenTextFile("\\.\pipe\pipename", 1, True, 0)
sText = oTSF.Readline()
oTSF.Close()
MsgBox(sText & vbCRLF)

 

Edited by Nine
Link to comment
Share on other sites

Kinky. Now, would you all post an "echo" script ?. One in AU3 and one in VBS as to show how the IPC would work in a MainLoop ?.
That way it'll be clear for someone with little knowing ( a.k.a. me ), how to go about implementing this as a 2 way IPC.
Thanks :)  

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Oh ya I forgot to mention.  Since VBS is kind of slow compare to AutoIt (it's funny to write that, as AutoIt has a bad reputation on that side), I have put a small sleep just before the last disconnect :

#include <NamedPipes.au3>
#include <Constants.au3>
#include <WinAPIFiles.au3>

Local $hNamedPipe = _NamedPipes_CreateNamedPipe("\\.\pipe\pipename", 2, 1)
ConsoleWrite ($hNamedPipe & @CRLF)
$test = _NamedPipes_ConnectNamedPipe($hNamedPipe)
ConsoleWrite ($test & @CRLF)

Local $tBuffer = DllStructCreate("char Text[" & 100 & "]"), $iRead, $iWritten
$pBuffer = DllStructGetPtr($tBuffer)
$bSuccess = _WinAPI_ReadFile($hNamedPipe, $pBuffer, 100, $iRead)
ConsoleWrite (DllStructGetData($tBuffer, "Text") & @CRLF)
_NamedPipes_DisconnectNamedPipe ($hNamedPipe)

$test = _NamedPipes_ConnectNamedPipe($hNamedPipe)
ConsoleWrite ($test & @CRLF)
DllStructSetData($tBuffer, "Text", "Reponse" & @CRLF)
$bSuccess = _WinAPI_WriteFile($hNamedPipe, $pBuffer, 9, $iWritten)
If Not $bSuccess Then ConsoleWrite (_WinAPI_GetLastError() & @CRLF)
ConsoleWrite ($bSuccess & @CRLF)
Sleep (200)
_NamedPipes_DisconnectNamedPipe ($hNamedPipe)

Since that, it works every time.

Edited by Nine
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...