mmoalem

manipulate script on the run

13 posts in this topic

OK so I was think if there is a way to run a script/exe that basically reads the commands from an external script on the run...

The reason:

 I want to be able to change commands/data in my autoit script without terminating the run... so the main executing script will run 24/7 and its function is basically to fetch commands from the editable external script and execute them... any chance there is a possibility to do this?

Share this post


Link to post
Share on other sites



Ok so lets assume a script that check websites periodically for some data. so it opens a browser with a specific URL and run a check, close the browser, open another browser with another URL and so on and so on throughout the day - assuming there are some 100 URLs to rotate through... now if i wanted to change any of these URLs or add another one to the script or change the data it should look for I will have to stop the script, modify it and run it again from the start which is not desriable in my case... much simpler for me will be to change URLs or data in an external resource... _ I assume this can be done with some kind of database but have no knowledge how do this...

Share this post


Link to post
Share on other sites
1 minute ago, mmoalem said:

I assume this can be done with some kind of database but have no knowledge how do this...

Correct so looks like you are up for a learning experience ;)

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

:) I barely started on AUtoit... let alone getting into database... will have to look for a tutrial on autoit integration with database i guess

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

One simple way to do that would be using an INI file. 

Create a custom section, like [WEBSITES], and list your urls under numbered keys. Your sample.ini file would look like this:

[WEBSITES]
total=3
url1=www.google.com
url2=www.yahoo.com
url3=www.cnn.com
url4=

Then you use IniRead in your script to read each line and do what you want. If you need to change an URL you just edit the ini file, which is a plain text file, and you don´t have to touch the script. Remember to update the "total" line if you change the number of URLs on the INI file (for this simple sample). You may work on a script to manage the INI file in the future...

$inifile = "F:\MySamples\sample.ini"
While 1
   $lines = IniRead($inifile, "WEBSITES", "total", "0") ; filename, section, key, default
   If $lines >= 1 Then
      For $i = 1 to $lines
         $url = IniRead($inifile, "WEBSITES", "url"&$i, "")
         MsgBox(-1,"sample", "URL: " & $url) ; <-- DO WHAT YOU WANT HERE
      Next
   Else ;Problem reading INI File
      MsgBox(-1,"ERROR", "Problem reading " & $inifile)
   EndIf
WEnd

Hope that helps. :)

 

 

Edited by Nomad_RJ

Share this post


Link to post
Share on other sites
45 minutes ago, mmoalem said:

will have to look for a tutrial on autoit integration with database i guess

You should look here:

https://www.autoitscript.com/wiki/User_Defined_Functions#Databases_and_web_connections

 


Signature beginning:   Wondering who uses AutoIT and what it can be used for ?
* GHAPI UDF - modest begining - comunication with GitHub REST API *
ADO.au3 UDF     POP3.au3 UDF     XML.au3 UDF    How to use IE.au3  UDF with  AutoIt v3.3.14.x  for 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 API *

My contribution to others projects or UDF based on  others projects: * _sql.au3 UDF  * POP3.au3 UDF *  RTF Printer - UDF * XML.au3 - BETA * ADO.au3 UDF SMTP Mailer UDF *

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 * Best coding practices * 

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) * 

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 *

"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: 2017-06-04

Share this post


Link to post
Share on other sites

Thanks all for your help - databse might be overkill for my needs so I think I will work out the iniread route... but are there any big disadvantages to using ini over database or spreadsheet (putting aside the differences in data management in those options)?

Share this post


Link to post
Share on other sites

That depends on the usage case and volume of data. 

If you need to handle thousands of entries, you need that data to be shared and/or edited concurrently, you need high performance and last but not least, data need to be secured/encrypted, go for a database system.

For a simple admin script like the one in the exampe you gave, I would go for the simplicity of an INI/TXT file.

Share this post


Link to post
Share on other sites

Sorry for my english, and for the global variables... :D

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

You'll be writing to the local disk, and if you have two files trying to write at the same time it won't work. If you have a file trying to write and read at the same time, it might not work. You could use a database, I just recently discovered sqlite and using it to create a download manager that downloads multiple files at once, a few exes running accessing the same db. I get database locked/busy occasionally but when queueing 75 downloads and starting 15, it's only a handful of errors initially.

I also use a neat little trick from a post I found by melba a long time ago to continue communication between the main GUI process and the background process.

Main Process.au3:

#include <GUIConstants.au3>
#include <WindowsConstants.au3>

Global $hMain = GUICreate("Main Process", 400, 100)
Global $inpInput = GUICtrlCreateInput("Call,MouseMove,0,0,0;Call,MouseMove,250,250,10;Call,Run,Notepad.exe;Notepad,This command is complete!;Call,Sleep,2000;Call,ProcessClose,Notepad.exe", 10, 10, 380, 20)
Global $btnSend = GUICtrlCreateButton("Send commands", 10, 35, 100, 20)

Run("Background Process.exe")

GUISetState(@SW_SHOW)

While (True)
    Switch (GUIGetMsg())
        Case $GUI_EVENT_CLOSE
            GUIDelete($hMain)
            Exit 0
        Case $btnSend
            SendData(WinGetHandle("Background Process"), GUICtrlRead($inpInput))
    EndSwitch
WEnd

Func SendData(Const $hWndTo, $sData)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr")
    Local $tMsg = DllStructCreate("char message[" & StringLen($sData) + 1 & "]")
    DllStructSetData($tMsg, 1, $sData)
    DllStructSetData($tCOPYDATA, 2, StringLen($sData) + 1)
    DllStructSetData($tCOPYDATA, 3, DllStructGetPtr($tMsg))
    DllCall("user32.dll", "lparam", "SendMessage", "hwnd", $hWndTo, "int", $WM_COPYDATA, "wparam", 0, "lparam", DllStructGetPtr($tCOPYDATA))
EndFunc   ;==>SendData

Background Process.exe

#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3>

Global $hMain = GUICreate("Background Process", 0, 0, 0, 0, -1, -1, AutoItWinGetTitle())
GUISetState(@SW_SHOW, $hMain)

GUIRegisterMsg($WM_COPYDATA, WM_COPYDATA)
While (True)
    Sleep(100)
WEnd

Func Notepad($sText)
    While (Not WinExists("Untitled - Notepad"))
        Sleep(100)
    WEnd
    ControlSend("Untitled - Notepad", "", "[Class:Edit;Instance:1]", $sText)
EndFunc   ;==>Notepad

; Return the a 1d array with all of the valid arguments from message array that can be used for Call(function, array returned from this call)
Func MessageArrayToCallArgArray(Const ByRef $aArray, Const $iIndex, Const $iColumnStart = 0, $iColumnEnd = -1)
    Return StringSplit("CallArgArray|" & ArgArrayToCleanArgString($aArray, $iIndex, $iColumnStart, $iColumnEnd), "|", $STR_NOCOUNT)
EndFunc   ;==>MessageArrayToCallArgArray

; Return the a 1d array with all of the valid arguments from message array
Func MessageArrayToArgArray(Const ByRef $aArray, Const ByRef $iIndex, Const $iColumnStart = 0, $iColumnEnd = -1)
    Return StringSplit(ArgArrayToCleanArgString($aArray, $iIndex, $iColumnStart, $iColumnEnd), "|", $STR_NOCOUNT)
EndFunc   ;==>MessageArrayToArgArray

Func MessageToArray(Const $sMsg)
    Local $aRet = StringSplit($sMsg, ";", $STR_NOCOUNT + $STR_ENTIRESPLIT)
    Local $aReturn[0][10]

    For $i = 0 To UBound($aRet) - 1
        _ArrayAdd($aReturn, $aRet[$i], 0, ",")
    Next
    Return $aReturn
EndFunc   ;==>MessageToArray

Func WM_COPYDATA($hWndFrom, $iMsg, $wParam, $lParam)
    Local $tCOPYDATA = DllStructCreate("dword;dword;ptr", $lParam)
    Local $tMsg = DllStructCreate("char[" & DllStructGetData($tCOPYDATA, 2) & "]", DllStructGetData($tCOPYDATA, 3))
    Local $aData = MessageToArray(DllStructGetData($tMsg, 1))

    For $iIndex = 0 To UBound($aData, $UBOUND_ROWS) - 1
        Local $aCurrentCommand = MessageArrayToArgArray($aData, $iIndex, 0)
        Switch ($aCurrentCommand[0])
            Case "Call"
                Call($aCurrentCommand[1], MessageArrayToCallArgArray($aData, $iIndex, 2))
            Case "Notepad"
                Notepad($aCurrentCommand[1])
        EndSwitch
    Next

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COPYDATA

Use window messages to communicate. There's also a post in the example sub-forum for sharing variables between multiple processes.

I forgot to mention, I did do some tests to see what would be faster when I was starting this. At first I was going to use some json files to store all the information I needed to share, then I remembered MySql and saw that we had Sqlite in the UDFS. I believe I did a 1000 read test on a file, fetching an entire table/reading an entire json file, and the json file took a few seconds, the sqlite took .01 seconds. I believe the WM_COPYDATA method took < 0.001 seconds, can't remember exactly (this was a couple weeks ago). Either way, database/ini files you're reading/writing to the hard disk, using the copydata method everything is in RAM.

Edited by InunoTaishou

Share this post


Link to post
Share on other sites
6 hours ago, mmoalem said:

Thanks all for your help - databse might be overkill for my needs so I think I will work out the iniread route... but are there any big disadvantages to using ini over database or spreadsheet (putting aside the differences in data management in those options)?

First and most important.
"The Need is the mother of all inventions"
So, Databases exists because of a need, in the same way Client-Server Paradigm exists and in the same way OOP(Objects Oriented Programming) Languages exists so yes there is disadvantages of using writing to hard disk files over using databases.

Regards
Alien.

 

Share this post


Link to post
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