Jump to content
Sign in to follow this  
skyhigh

Problem about setting a specific time to run a program

Recommended Posts

I am working at a script (thanks @Chimp for the help on my previous thread) operating on Firefox, based on two time-set loops that are doing the same operations with some differences.
Now I need to execute a local video at a determinated hour (between 12 and 4).  
My question is

What is the best way to determine a precise hour (hh:mm)? I tried

While @Hour >= 12 & @MIN >= 00 And @HOUR <= 14 & @MIN < 30

But the loop is being ignored, although in the moment I use only @Min for my tests everything works fine.

This is the essential - and working - structure of the present script:

#include <ff.au3>
_FFStart()
While @MIN >= 00 And @MIN < 30  ; 1st Firefox loop

    Firefox url loop (contains functions and if conditions)

WEnd

;Open a new tab and runs a local video;

While @MIN >= 32 And @MIN <= 59 ; 2nd Firefox loop

    Firefox url loop (contains functions and if conditions)

WEnd

Thanks in advance

Share this post


Link to post
Share on other sites

The reason the statement is not working is because your using "&" instead of "And" they have totally different functions :)

As for the code block your first loop will run from 0 to 30 min and then exit the loop,

The second loop starts at 32 to 59 minutes, with just the code posted if those loops are not inside of another larger loop I do not see how the second loop even starts because the first would exit at 30 minutes and then the code would continue bypassing the second loop entirely. 

A good way to fix that would be just one loop with If statements, also the code could run continually this way and never need to be restarted.

While 1
Sleep(10) 
If @Min >= 00 AND @Min < 30 Then
 ;Function
ElseIf @Min >= 32 AND @Min <=59
 ;Function
EndIf
WEnd

Also you can try assigning the macros to a variable so you do not have to keep reusing the macro and could even do a crude hour:min feature like this.

While 1
    Sleep(10)
    $iTime = Number(@Hour & @Min)
    If $iTime >= 1650 AND $iTime <= 1700 Then
       MsgBox(0, "", "It's between 4:50 and 5:00 !")
    EndIf
WEnd

 

Edited by ViciousXUSMC

Share this post


Link to post
Share on other sites

The reason the statement is not working is because your using "&" instead of "And" they have totally different functions :)

As for the code block your first loop will run from 0 to 30 min and then exit the loop,

The second loop starts at 32 to 59 minutes, with just the code posted if those loops are not inside of another larger loop I do not see how the second loop even starts because the first would exit at 30 minutes and then the code would continue bypassing the second loop entirely. 

A good way to fix that would be just one loop with If statements, also the code could run continually this way and never need to be restarted.

While 1
Sleep(10) 
If @Min >= 00 AND @Min < 30 Then
 ;Function
ElseIf @Min >= 32 AND @Min <=59
 ;Function
EndIf
WEnd

Also you can try assigning the macros to a variable so you do not have to keep reusing the macro and could even do a crude hour:min feature like this.

While 1
    Sleep(10)
    $iTime = Number(@Hour & @Min)
    If $iTime >= 1650 AND $iTime <= 1700 Then
       MsgBox(0, "", "It's between 4:50 and 5:00 !")
    EndIf
WEnd

Hello world!

Sorry, I had not the occasion to post due to some issues, but I worked on your idea @ViciousXUSMC

I think that the easiest way to write more loops is to write more scripts, each one activating at a certain $iTime, right?

The problem is, if I use an infine loop (While 1) I can't even close FF at the end of the loop.

So I need to stop the loop, how?

Should I write a secondary script that stops the primary script?

Share this post


Link to post
Share on other sites

The reason the statement is not working is because your using "&" instead of "And" they have totally different functions :)

As for the code block your first loop will run from 0 to 30 min and then exit the loop,

The second loop starts at 32 to 59 minutes, with just the code posted if those loops are not inside of another larger loop I do not see how the second loop even starts because the first would exit at 30 minutes and then the code would continue bypassing the second loop entirely. 

A good way to fix that would be just one loop with If statements, also the code could run continually this way and never need to be restarted.

While 1
Sleep(10) 
If @Min >= 00 AND @Min < 30 Then
 ;Function
ElseIf @Min >= 32 AND @Min <=59
 ;Function
EndIf
WEnd

Also you can try assigning the macros to a variable so you do not have to keep reusing the macro and could even do a crude hour:min feature like this.

While 1
    Sleep(10)
    $iTime = Number(@Hour & @Min)
    If $iTime >= 1650 AND $iTime <= 1700 Then
       MsgBox(0, "", "It's between 4:50 and 5:00 !")
    EndIf
WEnd

Hello world!

Sorry, I had not the occasion to post due to some issues, but I worked on your idea @ViciousXUSMC

I think that the easiest way to write more loops is to write more scripts, each one activating at a certain $iTime, right?

The problem is, if I use an infine loop (While 1) I can't even close FF at the end of the loop.

So I need to stop the loop, how?

Should I write a secondary script that stops the primary script?

Share this post


Link to post
Share on other sites

Would be hard to help without knowing how your function works.

Sounds to me instead of needing to run between (start time) and ending at (stop time) you just need a (start time) only.

So just modify like so:

While 1
    Sleep(10)
    $iTime = Number(@Hour & @Min)
    If $iTime = 1650 Then MsgBox(0, "", "Function Started @ 4:50PM")
    If $iTimer = 1850 Then MsgBox(0, "", "Function Started @ 6:50PM")
WEnd

 

If your going to have a bunch of different start times that is a good chance to use Switch/EndSwitch instead of If/EndIf statements.

Share this post


Link to post
Share on other sites

Would be hard to help without knowing how your function works.

Sounds to me instead of needing to run between (start time) and ending at (stop time) you just need a (start time) only.

So just modify like so:

While 1
    Sleep(10)
    $iTime = Number(@Hour & @Min)
    If $iTime = 1650 Then MsgBox(0, "", "Function Started @ 4:50PM")
    If $iTimer = 1850 Then MsgBox(0, "", "Function Started @ 6:50PM")
WEnd

 

If your going to have a bunch of different start times that is a good chance to use Switch/EndSwitch instead of If/EndIf statements.

I am sorry, I should have explained myself better from the beginning. I'll try to do it now.
Here the operations I need

1)To run firefox at a certain hour (HH:MM),
2)To open a random url taken from a list, let it open then close it
3)To keep doing it until a determined hour (HH:MM)
4)To change the list where the urls are taken from
5)Repeat 2) until is time for the script to stop itself (HH:MM).
6)To execute a local video at given times (HH:MM, HH:MM, etc)

Notes (number related)
1)Thanks to the FF libraries I can easily operate in Firefox, so no problem there.
2)To open the urls randomly I wrote this code (example of the code structure)

Global $aURLS[6]
$aURLS[1] = "www.youtube.com" 
$aURLS[2] = "www.yahoo.com"
$aURLS[3] = "www.vimeo.com"
$aURLS[4] = "www.dailymotion.com"
$aURLS[5] = "www.twitch.tv"

$x = Random(1, 5, 1)

_FFTabAdd($aURLS[$x], True, True)
WinWaitActive("Tab",0,10)

Sleep(5 * 1000) 

_FFTabClose("0", "index")
Sleep(5000)

    Select
    Case $x <= 2
    MouseClick(x,y)
    Sleep(15 * 1000) 
    MouseClick(x,y)

    Case $x >= 3
    MouseWheel("down", 1)                   
    Sleep(2000)
    MouseClick(x,y) 
    Sleep(15 * 1000)
    MouseClick(x,y)

EndSelect


So, that is the essential code I need to loop. The case select is necessary to maximize the video window in different websites.
3)I don't care if the script is only one or I have to divide it. I just need it to work correctly.
4)There are two (al least) lists of urls. This is a vital part of the script
6)This is vital too, so I am taking into consideration to write 3 scripts instead of only one. It looks easier, do you agree?

 

Share this post


Link to post
Share on other sites

I'll look at this more later, but I can tell you that running separate loops like you posted in your example should behave no different than the While loop I posted so the issue that is happening must have something to do with your code.

If you really want to do this in a professional manner you should look at the IUIAutomation thread where you can click/full screen without using MouseClick() so that it will always work no matter the resolution, and I think FireFox UDF has methods to detect when a page has loaded so you can get rid of the excessive Sleep() you have for page loading.

Share this post


Link to post
Share on other sites

I found out my mistake: ""

Daaaaamn quotes!

$iTime = Number(@Hour & @Min)
For $iTime = "1640" To "1642"

This "timer" appears to be workimg well! EDIT: well, seems it does not work if I don't include a piece of code I found surfing the net.

I checked the IUIAutomation thread. It looks very useful and I thank you for pointing it out to me, but I have the impression it requires to be more skilled than the level I am presently.

You are right, it exists the _FFLoadWait function, better than Sleep, thanks for the hint

I'll continue my work on the script, thank you for you help!

Edited by skyhigh

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  

  • Similar Content

    • By Beege
      Years ago I tried to put some functionality together to do some of this here. I started off in the right direction but it ended up getting out of control. Any new thing I learned along the way (as I was creating it), I kept trying to add in and it all became a mess. One of my primary goals with that was to make sure the code could always be pre-compiled and still run. That part did work and I was able create a couple of good projects with it, but still a lot of parts I wouldn't consider correct now and certainly not manageable. 
      Here is a redo of what I was going for there only this time I'm not going to be generating any of the assembly code. That's all going to be done using the built in macro engine already within fasm.dll and the macros written by Tomasz Grysztar (creator of fasm) so this time I don't have to worry about any of the code that gets generated. Im not going to touch the source at all. In fact there is not even going to be _fasmadd or global variables tracking anything. None of that is needed with the added basic and extended headers that you can read more about in the fasm documentation. You can use almost all of whats in the documentation section for basic/extended headers but ignore the parts about import,exports,resources,text encoding. doesn't really apply here.
      Here are examples I came up with that covers a lot of core functionality to write assembly code in a manner that you already know how. If/while using multiple conditional logic statements,  multiple functions, local variables, global variables, structures, COM interfaces, strings as parameters, nesting function calls. These are all things you dont even have to think about when your doing it in autoit and I'm hoping this helps bring some of that same comfort to fasm. 
      These 3 simple callback functions will be used through out the examples  
      Global $gConsoleWriteCB = DllCallbackRegister('_ConsoleWriteCB', 'dword', 'str;dword'), $gpConsoleWriteCB = DllCallbackGetPtr($gConsoleWriteCB) Global $gDisplayStructCB = DllCallbackRegister('_DisplayStructCB', 'dword', 'ptr;str'), $gpDisplayStructCB = DllCallbackGetPtr($gDisplayStructCB) Global $gSleepCB = DllCallbackRegister('_SleepCB', 'dword', 'dword'), $gpSleepCB = DllCallbackGetPtr($gSleepCB) Func _ConsoleWriteCB($sMsg, $iVal) ConsoleWrite($sMsg & $iVal & @CRLF) EndFunc ;==>_ConsoleWriteCB Func _DisplayStructCB($pStruct, $sStr) _WinAPI_DisplayStruct(DllStructCreate($sStr, $pStruct), $sStr, 'def=' & $sStr) EndFunc ;==>_DisplayStructCB Func _SleepCB($iSleep) Sleep($iSleep) EndFunc ;==>_SleepCB  
      proc/endp - like func and endfunc with some extra options. "uses" statement will preserve the registers specified. stdcall is the default call type if not specified. DWORD is the default parameter size if not specified. ret value is also handled for you. You don't have to worry about adjusting a number every time you throw on an extra parameter. In fact you don't ever have to specify/touch ebp/esp at all with these macros. See Basic headers -> procedures for full description.
      force - just a macro I added for creating a anonymous label for the first/primary function to ensure the code gets generated. The problem we are getting around is this: in our example, _main is never actually called anywhere within fasm code and fasm engine detects that and thinks the code is doing nothing. Because of that it wants to skip generating that code and all code that was called by it leaving you with nothing. This is actually a great feature but we obviously want to make an exception for our main/initial/primary function that starts it all off so thats all this does.
      Func _Ex_Proc() $g_sFasm = '' _('force _main') _('proc _main uses ebx, parm1, parm2') ; _('proc _main stdcall uses ebx, parm1:DWORD, parm2:DWORD'); full statement _(' mov ebx, [parm1]') _(' add ebx, [parm2]') _(' mov eax, ebx') _(' ret') _('endp') Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) Local $iAdd = DllCallAddress('dword', DllStructGetPtr($tBinary), 'dword', 5, 'dword', 5) ConsoleWrite('Parm1+Parm2=' & $iAdd[0] & @CRLF) EndFunc ;==>_Ex_Proc  
          Here Im showing you calling _ConsoleWriteCB autoit function we set up as a callback. Its how you would call any function in autoit from fasm.
          Strings - Notice Im creating and passing "edx = " string to the function on the fly. So helpful!
          invoke - same as a stdcall with brackets []. Use this for when calling autoit functions
       
      Func _Ex_Callback() $g_sFasm = '' _('force _main') _('proc _main, pConsoleWriteCB, parm1, parm2') _(' mov edx, [parm1]') _(' add edx, [parm2]') _(' invoke pConsoleWriteCB, "edx = ", edx') ; ;~ _(' stdcall [pConsoleWriteCB], "edx = ", edx') ; same as invoke _(' ret') _('endp') Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) DllCallAddress('ptr', DllStructGetPtr($tBinary), 'ptr', $gpConsoleWriteCB, 'dword', 5, 'dword', 5) EndFunc ;==>_Ex_Callback  
      Showing .while/.endw, .if/.elseif/.else/.endif usage. .repeat .until are also macros you can use. See Extended Headers -> Structuring the source. Ignore .code, .data, .end - Those are gonna be more for a full exe.
      invokepcd/invokepd - these are macros I added that are the same as invoke, just preserve (push/pop) ECX or both ECX and EDX during the call. Below is also a good example of what can happen when you don't preserve registers that are caller saved (us calling the function) vs callie saved (us creating the function). EAX,ECX,EDX are all caller saved so when we call another function like the autoit callback _ConsoleWriteCB, those registers could have very different values then what was in them before the call. This function below should do at least two loops, but it doesn't (at least on my pc) without preserving ECX because ECX is no longer zero when the function returns.
      Keep the same thought in mind for registers EBX,ESI,EDI when you are creating assembly functions (callie saved). If your functions uses those registers, You need to preserve and restore them before your code returns back to autoit or else you could cause a similar effect to autoit. "trashing" registers is a term I've seen used alot when referring to these kind of mistakes
      Func _Ex_IfElseWhile() $g_sFasm = '' _('force _main') _('proc _main uses ebx, pConsoleWriteCB') _(' xor edx, edx') ; edx=0 _(' mov eax, 99') ; _(' mov ebx, 10') _(' xor ecx, ecx') ; ecx=0 _(' .while ecx = 0') _(' .if eax<=100 & ( ecx | edx )') ; not true on first loop _(' inc ebx') _(' invokepcd pConsoleWriteCB, "Something True - ebx=", ebx') _(' ret') _(' .elseif eax < 99') ; Just showing you the elseif statement _(' inc ebx') _(' .else') ;~ _(' invokepcd pConsoleWriteCB, "Nothing True - ebx=", ebx') ; comment this and uncomment the line below _(' invoke pConsoleWriteCB, "Nothing True - ebx=", ebx') _(' inc edx') ; this will make next loop true _(' .endif') _(' .endw') _(' ret') _('endp') Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) DllCallAddress('dword', DllStructGetPtr($tBinary), 'ptr', $gpConsoleWriteCB) EndFunc ;==>_Ex_IfElseWhile  
          Sub Functions : You already understand this. Not really "sub", its just another function you call. And those functions call other functions and so on.
          fix : syntax sugar - Look how easy it was to replace invoke statement with our actual autoit function name
          ptr : more sugar - same thing as using brackets [parm1]
          Nesting : In subfunc1 we pass the results of two function calls to the same function we are calling
      Func _Ex_SubProc() $g_sFasm = '' ;replace all '_ConsoleWriteCB' statments with 'invoke pConsoleWriteCB' before* assembly _('_ConsoleWriteCB fix invoke pConsoleWriteCB') _('force _main') _('proc _main uses ebx, pConsoleWriteCB, parm1, parm2') _(' mov ebx, [parm1]') _(' add ebx, [parm2]') _(' _ConsoleWriteCB, "ebx start = ", ebx') _(' stdcall _subfunc1, [pConsoleWriteCB], [parm1], [parm2]') _(' _ConsoleWriteCB, "ebx end = ", ebx') _(' ret') _('endp') ; _('proc _subfunc1 uses ebx, pConsoleWriteCB, parm1, parm2') _(' mov ebx, [parm1]') _(' _ConsoleWriteCB, " subfunc1 ebx start = ", ebx') _(' stdcall _SubfuncAdd, <stdcall _SubfuncAdd, [parm1], [parm2]>, <stdcall _SubfuncAdd, ptr parm1, ptr parm2>') ; Nesting functions _(' _ConsoleWriteCB, " _SubfuncAdd nested <5+5><5+5> = ", eax') _(' _ConsoleWriteCB, " subfunc1 ebx end = ", ebx') _(' ret') _('endp') ; _('proc _SubfuncAdd uses ebx, parm1, parm2') _(' mov ebx, [parm1]') _(' add ebx, [parm2]') _(' mov eax, ebx') _(' ret') _('endp') Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) DllCallAddress('dword', DllStructGetPtr($tBinary), 'ptr', $gpConsoleWriteCB, 'dword', 5, 'dword', 5) EndFunc ;==>_Ex_SubProc  
      This demonstrates the struct macro. See basic headers -> Structures for more info
      _FasmAu3StructDef will create an equivalent formated structure definition. All elements already have a sizeof.#name created internally. So in this example sizeof.AUTSTRUCT.x would equal 8. sizeof.AUTSTRUCT.z would equal 16 (2*8). I have added an additional one sot.#name (sizeoftype) for any array that gets created. Below is the source of what gets generate from 'dword x;dword y;short z[8]'. Also dont get confused that in fasm data definitions,  d is for data as in db (data byte) or dw (data word). Not double like it is in autoit's dword (double word). See intro -> assembly syntax -> data definitions
         
      struct AUTSTRUCT x dd ? y dd ? z dw 8 dup ? ends define sot.AUTSTRUCT.z 2 Func _Ex_AutDllStruct() $g_sFasm = '' Local Const $sTag = 'dword x;dword y;short z[8]' _(_FasmAu3StructDef('AUTSTRUCT', $sTag)) _('force _main') _('proc _main uses ebx, pDisplayStructCB, pAutStruct') _(' mov ebx, [pAutStruct]') ; place address of autoit structure in ebx _(' mov [ebx+AUTSTRUCT.x], 1234') _(' mov [ebx+AUTSTRUCT.y], 4321') _(' xor edx, edx') _(' mov ecx, 5') ; setup ecx for loop instruction _(' Next_Z_Index:') ; set elements 1-6 (0-5 here in fasm) _(' mov [ebx+AUTSTRUCT.z+(sot.AUTSTRUCT.z*ecx)], cx') ; cx _(' loop Next_Z_Index') _(' invoke pDisplayStructCB, [pAutStruct], "' & $sTag & '"') _(' mov [ebx+AUTSTRUCT.z+(sot.AUTSTRUCT.z*6)], 666') _(' mov [ebx+AUTSTRUCT.z+(sot.AUTSTRUCT.z*7)], 777') _(' ret') _('endp') Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) Local $tAutStruct = DllStructCreate($sTag) DllCallAddress('ptr', DllStructGetPtr($tBinary), 'ptr', $gpDisplayStructCB, 'struct*', $tAutStruct) _WinAPI_DisplayStruct($tAutStruct, $sTag) EndFunc ;==>_Ex_AutDllStruct  
      Here shows the locals/endl macros for creating local variables. See basic headers -> procedures. We create a local string and the same dll structure as above. Notice that you can initialize all the values of the structure on creation. There is a catch to this though that I will show you in next example.
      addr macro - This will preform the LEA instruction in EDX and then push the address on to the stack. This is awesome, just remember its using EDX to perform that and does not preserve it. You'll pretty much want to use that for any local variables you are passing around.
      Edit: I shouldn't say things like that so causally.  Use the addr macro as much as you want but remember that it is adding a couple of extra instuctions each time you use it so if your calling invoke within a loop and ultimate performance is one of your goals, you should probably perform the LEA instructions before the loop and save the pointer to a separate variable that your would then use in the loop. 
      Func _Ex_LocalVarsStruct() $g_sFasm = '' Local Const $sTag = 'dword x;dword y;short z[8]' _(_FasmAu3StructDef('POINT', $sTag)) _('force _main') _('proc _main, pDisplayStructCB') _(' locals') _(' sTAG db "' & $sTag & '", 0') ; define local string. the ', 0' at the end is to terminate the string. _(' tPoint POINT 1,2,<0,1,2,3,4,5,6,7>') ; initalize values in struct _(' endl') _(' invoke pDisplayStructCB, addr tPoint, addr sTAG') _(' mov [tPoint+POINT.x], 4321') _(' mov [tPoint+POINT.z+sot.POINT.z*2], 678') _(' invoke pDisplayStructCB, addr tPoint, addr sTAG') _(' ret') _('endp') Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) Local $ret = DllCallAddress('ptr', DllStructGetPtr($tBinary), 'ptr', $gpDisplayStructCB) EndFunc ;==>_Ex_LocalVarsStruct  
      Back to the catch. Alignment is the problem here but only with the initializes. I'm handling all the alignment ok so you don't have to worry about that for creating structures that need alignment, only if you are using the one liner initialize in locals. The problem comes from extra padding being defined to handle the alignment, but fasm doesn't really know its just padding so without adding extra comma's to the initiator statement, your data ends up in the padding or simply fails. The _FasmFixInit will throw in the extra commas needed to skip the padding.
      Func _Ex_LocalVarStructEx() $g_sFasm = '' $sTag = 'byte x;short y;char sNote[13];long odd[5];word w;dword p;char ext[3];word finish' _(_FasmAu3StructDef('POINT', $sTag)) _('force _main') _('proc _main, pDisplayStructCB') _(' locals') _(' tPoint POINT ' & _FasmFixInit('1,222,<"AutoItFASM",0>,<41,43,43,44,45>,6,7,"au3",12345', $sTag)) _(' endl') _(' invoke pDisplayStructCB, addr tPoint, "' & $sTag & '"') _(' ret') _('endp') Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) DllCallAddress('dword', DllStructGetPtr($tBinary), 'ptr', $gpDisplayStructCB) EndFunc ;==>_Ex_LocalVarStructEx  
      I love this one and it is really not even that hard to explain. We got multiple functions and want to be able to call them individually. Here I simply use the primary function to tell me where all the functions are. I load all the offsets (byte distance from start of code) of each each function in to a dllstruct, then once its passed back to autoit, adjust all the offsets by where they are actually located in memory (pointer to dll). From there you can call each individual function as shown previously. full code is in the zip. 
      String functions came from link below. I ended up modifying strcmp to get a value I understand. CRC32 func is all mine. Made it so easy being able to call _strlen and then use while statements like I normally would    https://www.strchr.com/strcmp_and_strlen_using_sse_4.2
      Func _Ex_SSE4_Library() $g_sFasm = '' _('force _main') _('proc _main stdcall, pAdd') _(' mov eax, [pAdd]') _(' mov dword[eax], _crc32') _(' mov dword[eax+4], _strlen') _(' mov dword[eax+8], _strcmp') _(' mov dword[eax+12], _strstr') _(' ret') _('endp') _('proc _crc32 uses ebx ecx esi, pStr') ; _('endp') _('proc _strlen uses ecx edx, pStr') ; _('endp') _('proc _strcmp uses ebx ecx edx, pStr1, pStr2') ; ecx = string1, edx = string2' ; _('endp') _('proc _strstr uses ecx edx edi esi, sStrToSearch, sStrToFind') ; _('endp') Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) Local $pBinary = DllStructGetPtr($tBinary) Local $sFunction_Offsets = 'dword crc32;dword strlen;dword strcmp;dword strstr' $tSSE42 = DllStructCreate($sFunction_Offsets) $ret = DllCallAddress('ptr', $pBinary, 'struct*', $tSSE42) _WinAPI_DisplayStruct($tSSE42, $sFunction_Offsets, 'Function Offsets') ;Correct all addresses $tSSE42.crc32 += $pBinary $tSSE42.strlen += $pBinary $tSSE42.strcmp += $pBinary $tSSE42.strstr += $pBinary $sTestStr = 'This is a test string!' ConsoleWrite('$sTestStr = ' & $sTestStr & @CRLF) $iCRC = DllCallAddress('int', $tSSE42.crc32, 'str', $sTestStr) ConsoleWrite('CRC32 = ' & Hex($iCRC[0]) & @CRLF) $aLen = DllCallAddress('int', $tSSE42.strlen, 'str', $sTestStr) ConsoleWrite('string len = ' & $aLen[0] & ' :1:' & @CRLF) $aFind = DllCallAddress('int', $tSSE42.strcmp, 'str', $sTestStr, 'str', 'This iXs a test') ConsoleWrite('+strcmp = ' & $aFind[0] & @CRLF) $aStr = DllCallAddress('int', $tSSE42.strstr, 'str', 'This is a test string!', 'str', 'test') ConsoleWrite('Strstr = ' & $aStr[0] & @CRLF) EndFunc ;==>_Ex_SSE4_Library  
      I'm extremely happy I got a com interface example working. I AM. That being said.. I'm pretty fucking annoyed I cant find the original pointer when using using built in ObjCreateInterface I've tired more than just whats commented out. It anyone has any input (I know someone here does!) that would be great. Using the __ptr__ from _autoitobject works below. Example will delete the tab a couple times.
      Edit: Got that part figured out. Thanks again trancexx!
      Func _Ex_ComObjInterface() $g_sFasm = '' ;~ _AutoItObject_StartUp() ;~ Local Const $sTagITaskbarList = "QueryInterface long(ptr;ptr;ptr);AddRef ulong();Release ulong(); HrInit hresult(); AddTab hresult(hwnd); DeleteTab hresult(hwnd); ActivateTab hresult(hwnd); SetActiveAlt hresult(hwnd);" ;~ Local $oList = _AutoItObject_ObjCreate($sCLSID_TaskbarList, $sIID_ITaskbarList, $sTagITaskbarList) Local Const $sCLSID_TaskbarList = "{56FDF344-FD6D-11D0-958A-006097C9A090}", $sIID_ITaskbarList = "{56FDF342-FD6D-11D0-958A-006097C9A090}" Local Const $sTagITaskbarList = "HrInit hresult(); AddTab hresult(hwnd); DeleteTab hresult(hwnd); ActivateTab hresult(hwnd); SetActiveAlt hresult(hwnd);" Local $oList = ObjCreateInterface($sCLSID_TaskbarList, $sIID_ITaskbarList, $sTagITaskbarList) _('interface ITaskBarList,QueryInterface,AddRef,Release,HrInit,AddTab,DeleteTab,ActivateTab,SetActiveAlt') ; _('force _main') _('proc _main uses ebx, pSleepCB, oList, pGUIHwnd') _(' comcall [oList],ITaskBarList,HrInit') _(' xor ebx, ebx') _(' .repeat') _(' invoke pSleepCB, 500') ; wait _(' comcall [oList],ITaskBarList,DeleteTab,[pGUIHwnd]') ; delete _(' invoke pSleepCB, 500') ; wait _(' comcall [oList],ITaskBarList,AddTab,[pGUIHwnd]') ; add back _(' comcall [oList],ITaskBarList,ActivateTab,[pGUIHwnd]') ; actvate _(' inc ebx') _(' .until ebx=4') _(' ret') _('endp') Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) Local $GUI = GUICreate("_Ex_ComObjInterface ------ DeleteTab") GUISetState() ;~ DllCallAddress('ptr', DllStructGetPtr($tBinary), 'ptr', $gpSleepCB, 'ptr', $oList.__ptr__, 'dword', Number($GUI)) DllCallAddress('ptr', DllStructGetPtr($tBinary), 'ptr', $gpSleepCB, 'ptr', $oList(), 'dword', Number($GUI)) EndFunc ;==>_Ex_ComObjInterface  
      Lastly here is an example of how to use a global variable. Without using the org statement, this value is just an offset like the functions in the library example. In order for your code to know that location, it needs to know where the real starting address is so we have to pass that to our functions. Once you have it, if you write your code proper and preserve registers correctly, you can just leave in EBX. From what I understand, if all functions are following stdcall rules, that register shouldn't change in less you change it. Something cool and important to remember is these variables will hold whatever values left in them till you wipe the memory (dll structure) holding your code. keep that in mind if you made your dll structure with a static keyword. If thats the case treat them like static variables
      Func _Ex_GlobalVars() $g_sFasm = '' _('_ConsoleWriteCB fix invoke pConsoleWriteCB') ; _('force _main') _('proc _main uses ebx, pMem, pConsoleWriteCB, parm1') _(' mov ebx, [pMem]') ; This is where are code starts in memory. _(' mov [ebx + g_Var1], 111') _(' add [ebx + g_Var1], 222') _(' _ConsoleWriteCB, "g_Var1 = ", [ebx + g_Var1]') _(' stdcall subfunc1, [pMem], [pConsoleWriteCB], [parm1]') _(' mov eax, g_Var1') _(' ret') _('endp') ; _('proc subfunc1 uses ebx, pMem, pConsoleWriteCB, parm1') _(' mov ebx, [pMem]') _(' mov [ebx + g_Var1], 333') _(' _ConsoleWriteCB, "g_Var1 from subfunc1= ", [ebx + g_Var1]') _(' stdcall subfunc2, [pConsoleWriteCB], [parm1]') ; no memory ptr passed. ebx should be callie saved _(' _ConsoleWriteCB, "g_Var1 from subfunc1= ", [ebx + g_Var1]') _(' stdcall subfunc2, [pConsoleWriteCB], [parm1]') _(' ret') _('endp') ; _('proc subfunc2, pConsoleWriteCB, parm1') _(' add [ebx + g_Var1], 321') _(' _ConsoleWriteCB, "g_Var1 from subfunc2= ", [ebx + g_Var1]') _(' ret') _('endp') ; _('g_Var1 dd ?') ; <--------- Global Var Local $tBinary = _FasmAssemble($g_sFasm) If @error Then Exit (ConsoleWrite($tBinary & @CRLF)) Local $iOffset = DllCallAddress('dword', DllStructGetPtr($tBinary), 'struct*', $tBinary, 'ptr', $gpConsoleWriteCB, 'dword', 55)[0] ConsoleWrite('$iOffset = ' & $iOffset & @CRLF) Local $tGVar = DllStructCreate('dword g_Var1', DllStructGetPtr($tBinary) + $iOffset) ConsoleWrite('Directly access g_Var1 -> ' & $tGVar.g_Var1 & @CRLF) ; direct access EndFunc ;==>_Ex_GlobalVars  
      FasmEx.zip
    • By Skeletor
      Hi All,
      I want to make my progress bar progress with the amount of File lines read. 
      How would I do this correctly. So far the code below can sometimes run in the middle of the progress bar and state completed.. and other times it can run into the 200%. 
       
      ;======================================================================== ProgressOn("TITLE", "ACTION") ;======================================================================== For $count = 1 To _FileCountLines($FileRead) Step 1 $string = FileReadLine($FileRead, $count) $value1 = $input[1] $value2 = $input[2] $value3 = $input[3] $value4 = $input[4] $TM = FileWrite("C:\temp\test.txt", $value1 & " " & $value2 & " " & $value3 & " " & $value4 & @CRLF) ProgressSet($count, $count & "%") Next ;======================================================================== ; PROGRESS BAR OFF ;======================================================================== ProgressSet(_FileCountLines($FileRead), "Completed!") Sleep(750) ProgressOff() ;========================================================================  
    • By TheGreatMomo
      Here is the script for the variable I want to find:
      Local $oSunHrsTD = _IETagNameGetCollection($oFrameobj, "span").item(138)
      The Item(138) for the span elemets is a dynamic number based on the index of all span objects on the webpage I am trying to send inputs to. 
      Based on the span.item(#) the corresponding InnerText for that element is the value that I want to get. Which I use the following script:
      Local $oSunHrs = $oSunHrsTD.InnerText
      Global $otime = _IECreate ("https://somewebsite.banana") _IELoadWait($otime) Local $oFrameobj = _IEFrameGetObjByName($otime, "gsft_main") Local $oLinks = _IETagNameGetCollection($oFrameobj, "a") For $oLink In $oLinks If $oLink.ClassName = "linked formlink" Then _IEAction($oLink, "click") ExitLoop EndIf Next _IEloadWait($oFrameobj) Local $oMonHrsTD = _IETagNameGetCollection($oFrameobj, "span").item(139) Local $oMonHrs = $oMonHrsTD.InnerText _IELoadWait($oFrameobj) Local $oFrameobj = _IEFrameGetObjByName($otime, "gsft_main") Local $oMonHrs = _IETagNameGetCollection($oFrameobj, "SPAN") For $oMonHr In $oMonHrs If $oMonHr.ClassName = "aggregate_value" Then If $oMonHr.innertext >= "8" Then Local $oMonAdjHr = (8 - $oMonHR.Innertext) ConsoleWrite( $oMonHrs &@CRLF ) MsgBox (0, "Adjusted Value", $oMonAdjHr) ExitLoop EndIf EndIf Next  
      Where I get confused is how I find Item(#) if all I have is the InnerText. Since the InnerText is static and the Item# is dynamic:
      $oSunHrsTD = _IETagNameGetCollection($oFrameobj, "span").item( "x").InnerText = ("sometext")
      How can i get the X value??
       
    • By Vikramjeet
      $oExcel = ObjCreate("Excel.Application") $oExcel.Visible = 0 #include <MsgBoxConstants.au3> #Include <File.au3> Global $arlines WinActivate("MyApplication") ;Activate My Application Local $hWnd = WinWaitActive("MyApplication", "", 5) ;Wait for My Application for 5 seconds $oExcel.Application.WorkBooks.Open("C:\Users\Charlie\Desktop\Data.xlsx") ;Open Excel file 'Data.xlsx' local $iCell = $oExcel.Application.Cells(31,1).Value ;Read the value from cell A31 $file = @ScriptDir & "\Capture.log" If $hWnd Then For $a = 1 to $iCell ;STEP 1 Send("G*L") Send($oExcel.Application.Cells($a,1).Value) Send("/XUSR") Sleep(1000) Send("{ENTER}") Sleep(2000) ;===> Once the script has sent the above formats to 'MyApplication, A log file (Capture.log) is generated. What do I add as a link so the script moves to ;the following steps _FileReadToArray ($file, $arlines) For $i = $arlines [0] To 1 Step - 1 ; Script starts reading the log file from bottom up If $arlines [$i] = "‡NOT VALID" Then ;===> If I find the word '‡NOT VALID', then I want the script to go to STEP 1 in loop Else ;====> Else I want the script to do the following steps Send("MB") ; Continue sending formats to 'MyApplication' Send("{ENTER}") Sleep(2000) $iNum = StringRegExp(FileRead($file), "(?sm).*^\h*(\d{1,3})", 1)[0] ; Read number at a certain location in Capture.log file ConsoleWrite($iNum & @CRLF) EndIf ;====> Use the captured $iNum in the loop below. What do I add to proceed to the following steps For $i = 1 To $iNum Send("SET"& $i &"/USR") Sleep(500) Send("{ENTER}") Sleep(1000) ;====> Go back to STEP 1 $oExcel.Application.Quit I am a beginner and need help with If, then, else jump to specific loop in the script. Can I please get help with my script where I have multiple loops. I need to link the steps and also break the sequence and jump to specific loop if a certain condition is found in one loop. 
    • By Skeletor
      Hi Guys,
      Is it possible to get a variable on your For..Next loop? 
       
      Local $Lines1 = _FileCountLines(C:\temp\test.txt) Local $linesToCount2 = $Lines1 + 2 $var = Number($linesToCount2) For $count = 1 To _FileCountLines($FileRead2) Step 1 For $i = $var To $count Next ;Code does stuff here Next Somehow my code doesn't work even though I thought I could convert the variable to a Integer / Number.
      This code I posted above does not move to the next value.
      But the code below does... why is that?
      For $count = 1 To _FileCountLines($FileRead2) Step 1 For $i = 2 To $count Next ;Code does stuff here Next  
      Why is the For loop resetting itself?
      Is it because the program does not cache the variable and needs to keep on acquiring this variable each time?
      If so , how would you make this variable static?

       
×
×
  • Create New...