Sign in to follow this  
Followers 0
Exit

Serialize scripts ?

13 posts in this topic

; I want to synchronise 2 scripts.
; When they are started one direct after the other,
; the second should wait until the first has done it's work.
; Then the second should do the work.
; But the second never leaves the loop.
;
; How to manage this ?
;
;
#include <misc.au3>
While 1
    ; test, if an instance is already running
    If _Singleton("MyTest", 1) Then ExitLoop
    ; wait until first instance has finished
    SoundPlay(@WindowsDir & "\media\ding.wav", 1)
    Sleep(2000)
WEnd
; indicate working part running
SoundPlay(@WindowsDir & "\media\notify.wav", 1)
Sleep(5000)
; indicate working part finished
SoundPlay(@WindowsDir & "\media\Tada.wav", 1)
Exit 0

Please let run this script twice at the same time and you will hear the problem.

Thanks.


My UDFs, Abbrevs and Snippets
If you like my post, just click the like button :) 

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Seems the _Singleton function is made for a one-time use. Help was unclear on this :)

So, it only works fine the first time.

Edited by Inverted

Share this post


Link to post
Share on other sites

forumer100,

Compile this as the first script:

; indicate working part running
SplashTextOn("Script 1", "Script 1 is running")
SoundPlay(@WindowsDir & "\media\notify.wav", 1)
Sleep(5000)
; indicate working part finished
ControlSetText("Script 1", "", "Static1", "Script 1 is ending")
SoundPlay(@WindowsDir & "\media\Tada.wav", 1)

Then this as the second:

Do
    Sleep(100)
Until Not ProcessExists("Name_of_first_script.exe") ;<<<<<<<<< Change to the name of the compiled first script

; indicate working part running
SplashTextOn("Script 2", "Script 2 is running")
SoundPlay(@WindowsDir & "\media\notify.wav", 1)
Sleep(5000)
; indicate working part finished
ControlSetText("Script 2", "", "Static1", "Script 2 is ending")
SoundPlay(@WindowsDir & "\media\Tada.wav", 1)

If the second is started before the first finishes, it will wait until the first ends before running the working part.

Or do you want the same script to be launched twice?

M23


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

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

@ Melba

That's I believe what he wants, but there has to be a better solution. And also, it should be working with non-compiled scripts.

Share this post


Link to post
Share on other sites

forumer100,

If you do want the same script to run twice, try this:

If Not WinExists("This is a hidden window") Then

; Create hidden GUI
    $hGUI = GUICreate("This is a hidden window", 500, 500)
    GUISetState(@SW_HIDE)

; Run first working code
    SplashTextOn("Script 1", "Script 1 is running")
    SoundPlay(@WindowsDir & "\media\notify.wav", 1)
    Sleep(5000)
; indicate working part finished
    ControlSetText("Script 1", "", "Static1", "Script 1 is ending")
    SoundPlay(@WindowsDir & "\media\Tada.wav", 1)

    GUIDelete($hGUI)

Else

; Wait until GUI exits
    Do
        Sleep(10)
    Until Not WinExists("This is a hidden window")

; indicate working part running
    SplashTextOn("Script 2", "Script 2 is running")
    SoundPlay(@WindowsDir & "\media\notify.wav", 1)
    Sleep(5000)
; indicate working part finished
    ControlSetText("Script 2", "", "Static1", "Script 2 is ending")
    SoundPlay(@WindowsDir & "\media\Tada.wav", 1)

EndIf

It creates a hidden GUI on the first run and then waits for the GUI to be deleted before running the second time.

M23


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

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

I cannot say that I totally understand the request from the OP and I can only hope that the situation is a bit more complex than just wanting to run two known scripts one after another... otherwise you just put them into one script - one after the other.

If the need is something like script 1 starting from a server and script 2 starting as a local copy, then script 1 calls/starts script 2 after script 1 has done its thing.

If there are several scripts that could be run as that second script - then that would call for another solution.

@Melba23,

Would this work in place of a GUI?

If Not WinExists("This is a hidden window") Then

    AutoItWinSetTitle("This is a hidden window")

; Run first working code
    SplashTextOn("Script 1", "Script 1 is running")
    SoundPlay(@WindowsDir & "\media\notify.wav", 1)
    Sleep(5000)
; indicate working part finished
    ControlSetText("Script 1", "", "Static1", "Script 1 is ending")
    SoundPlay(@WindowsDir & "\media\Tada.wav", 1)

Else

; Wait until GUI exits
    Do
        Sleep(10)
    Until Not WinExists("This is a hidden window")

; indicate working part running
    SplashTextOn("Script 2", "Script 2 is running")
    SoundPlay(@WindowsDir & "\media\notify.wav", 1)
    Sleep(5000)
; indicate working part finished
    ControlSetText("Script 2", "", "Static1", "Script 2 is ending")
    SoundPlay(@WindowsDir & "\media\Tada.wav", 1)

EndIf
AutoItWinSetTitle

Changes the title of the AutoIt window.

Remarks

The AutoIt window is usually hidden. The purpose of changing the title is to allow other programs (or other AutoIt scripts) to interact with AutoIt.


[size="1"][font="Arial"].[u].[/u][/font][/size]

Share this post


Link to post
Share on other sites

You can't run _Singleton() in a loop. It's a one-time check because attempting to create the mutex creates an additional handle to the pre-existing one that never gets released, so the mutex continues to exist even after the first script exits. My understanding is a mutex doesn't go away untill ALL processes with handles to it explicitly release.

There was a post on the possibility of changing that in: _Singleton and a Server Class OS (Win2k3)

I haven't had time to try it.

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

herewasplato,

Would changing the title of the hidden AutoIt window have any unwanted effects on any other part of AutoIt? I do not know enough about it to say.

But thanks for the reminder of its existence - it was forgetfulness, not fear of unwanted consequences, that made me create a new hidden GUI! :-)

Like you, I am unsure quite what the OP wants - no doubt time will tell.

M23


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

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Thanks to all your suggestions. Lets try to explain my issue.

I'm visually handicapped and wrote an AU3 application to scan a letter, transform it to ASCII and then read it out by the soundcard.

The applicatiom worls perfect. :)

There is only a drawback: If I start the scan of the next page too early (reading out of current page not yet finished), then the second page is not read out.

So I want the second task to wait after scanning and transforming to ASCII, but before reading out.

By this way I can already scan/transform during reading out previous page. Saves a lot of time. :party:

If a letter has 10 pages, the script runs 10 times triggerd by a quickstart icon.

Here is the script. It's hardcoded to german locale.

; OCR Scan
;    MODI.Document needs MS Office Tools OCR and German feature switched ON.
;         SpeechSDK51.exe
;         MSReaderSetupGer.exe
;         ReaderTTSInstallGER.exe
#AutoIt3Wrapper_Icon=.\OCRScan.ico
DirCreate(@MyDocumentsDir & "\Eigene Dokumente\SCAN\OCRScan")
$TS = " " & @YEAR & "." & @MON & "." & @MDAY & " " & @HOUR & "." & @MIN & "." & @SEC
$FNP = @MyDocumentsDir & "\Eigene Dokumente\SCAN\OCRScan\OCR" & $TS & " .jpg"
$FNT = @MyDocumentsDir & "\Eigene Dokumente\SCAN\OCRScan\OCR" & $TS & " .txt"
While 1
    FileDelete($FNP)
    ShellExecuteWait(@ProgramFilesDir & "\IrfanView\i_view32.exe", "/scanhidden /convert=" & $FNP & " /dpi=(300,300)")
    If FileGetSize($FNP) > 0 Then ExitLoop
    MsgBox(0, "OCR Scan", "Bitte Scanner einschalten", 3)
WEnd
ShellExecute($FNP)
$String = _Img2Txt($FNP)
FileDelete($FNT)
FileWriteLine($FNT, $String)
ShellExecute($FNT)

;*******************************************************************************
; here should be the code to serialize. Wait until last speak out has finished. 
;*******************************************************************************

$OVoice = ObjCreate("SAPI.SpVoice")
$OVoice.rate = -2
$OVoice.voice = $OVoice.GetVoices.Item(4) ; Deutsch
$OVoice.Speak($String)
Exit 0

Func _Img2Txt($F, $S = "")
    ObjEvent("AutoIt.Error", "_CoMErrFunc")
    $O = ObjCreate("MODI.Document")
    $O.Create($F)
    $O.Ocr(7) ;en=9 DE=7 SP=10
    For $W In $O.Images(0).Layout.Words
        $S &= $W.text & " "
    Next
    Return $S
EndFunc   ;==>_Img2Txt

My UDFs, Abbrevs and Snippets
If you like my post, just click the like button :) 

Share this post


Link to post
Share on other sites

Thanks to all your suggestions. Lets try to explain my issue.

I'm visually handicapped and wrote an AU3 application to scan a letter, transform it to ASCII and then read it out by the soundcard.

The applicatiom worls perfect. :)

There is only a drawback: If I start the scan of the next page too early (reading out of current page not yet finished), then the second page is not read out.

So I want the second task to wait after scanning and transforming to ASCII, but before reading out.

By this way I can already scan/transform during reading out previous page. Saves a lot of time. :idea:

If a letter has 10 pages, the script runs 10 times triggerd by a quickstart icon.

I would try a different tack with that. Use an .ini file or a hidden GUI with a ListView control to build a que.

The first time it gets run, checked once with _Singleton() <> 0, it adds the file to the que, starts processing it, and deletes that item from the que when done. If there are no items left in the que, it exits.

Additional instances run while the first is still going detect _Singleton() = 0. All they do is add their file to the que of the existing file/GUI and exit.

When the first instance finishes the first file it was started for, it deletes the first entry from the que, and finding additional entries remaining, continues to process them in order until the que is empty.

:party:


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

... Would changing the title of the hidden AutoIt window have any unwanted effects on any other part of AutoIt? I do not know enough about it to say. ...

Sorry, I just could not test the code at the time of the post. I had hoped that you could tell by looking or testing. The answer is that is works fine.

[size="1"][font="Arial"].[u].[/u][/font][/size]

Share this post


Link to post
Share on other sites

@forumer100,

Please try this code.

If Not WinExists("first script to run") Then
    AutoItWinSetTitle("first script to run")
    Do
        Sleep(10)
    Until Not WinExists("second script to run")
    ; Run first working code
    SplashTextOn("Script 1", "Script 1 is running")
    SoundPlay(@WindowsDir & "\media\notify.wav", 1)
    Sleep(5000)
    ; indicate working part finished
    ControlSetText("Script 1", "", "Static1", "Script 1 is ending")
    SoundPlay(@WindowsDir & "\media\Tada.wav", 1)
Else
    AutoItWinSetTitle("second script to run")
    Do
        Sleep(10)
    Until Not WinExists("first script to run")
    ; indicate working part running
    SplashTextOn("Script 2", "Script 2 is running")
    SoundPlay(@WindowsDir & "\media\notify.wav", 1)
    Sleep(5000)
    ; indicate working part finished
    ControlSetText("Script 2", "", "Static1", "Script 2 is ending")
    SoundPlay(@WindowsDir & "\media\Tada.wav", 1)
EndIf

[size="1"][font="Arial"].[u].[/u][/font][/size]

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

OK, I wrote my own serialisation function. Quick and dirty, but it works. :)

Here is the code:

#include <File.au3>
#include <Array.au3>
_Serialize("MyTest", 1) ; get lock. wait, if an instance is already running
SoundPlay(@WindowsDir & "\media\notify.wav", 1); indicate working part running
Sleep(3000)
SoundPlay(@WindowsDir & "\media\Tada.wav", 1); indicate working part finished
_Serialize("MyTest", 0) ; release lock
Exit 0

Func _Serialize($sSerializeName, $iFlag = 1, $iSleep = 500) ; 0=release, 1=wait, 2=return
    Local $aRecords, $x
    Local $sFilename = @TempDir & "\~_Serialize~" & $sSerializeName
    If Not FileWriteLine($sFilename, @AutoItPID) Then Exit MsgBox(4096 + 262144, '_Serialize', "Unable to setup file" & @CRLF & $sFilename)
    While Sleep($iSleep)
        If Not _FileReadToArray($sFilename, $aRecords) Then Exit MsgBox(4096 + 262144, '_Serialize', "Unable to read file to array" & @CRLF & $sFilename)
        For $x = UBound($aRecords) - 1 To 1 Step -1
            If Not ProcessExists($aRecords[$x]) Then _ArrayDelete($aRecords, $x)
            If $aRecords[$x] = @AutoItPID And $iFlag = 0 Then _ArrayDelete($aRecords, $x)
        Next
        If Not _FileWriteFromArray($sFilename, $aRecords, 1) Then Exit MsgBox(4096 + 262144, '_Serialize', "Unable to write file from array" & @CRLF & $sFilename)
        If $iFlag > 0 And $aRecords[1] = @AutoItPID Then Return 1
        If $iFlag = 2 And Not ($aRecords[1] = @AutoItPID) Then Return 0
        If UBound($aRecords) = 1 Then Return FileDelete($sFilename)
        If $iFlag = 0 Then Return 1
    WEnd
EndFunc   ;==>_Serialize
Edited by forumer100

My UDFs, Abbrevs and Snippets
If you like my post, just click the like button :) 

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
Sign in to follow this  
Followers 0