Jump to content
wisepage

Question about launching batch files with AutoIt scripts

Recommended Posts

wisepage

I want to use AutoIt to perform a certain function, and was lucky enough that I found something similar to what I wanted on a message board somewhere. I have been tweaking it but can't quite make it work.

Basically, I want AutoIt to compile an exe, MyCompiledScript.exe, that does the following:
1. Wait a set amount of time for idle, then launch a batch (MyBat.bat) file I've already written (batch file then launches an exe; MyProgram.exe).
2. When idle ends, close exe from step 1.

I need the batch file because running the exe file directly from the script doesn't work in the way I want.

When I launch MyBat.bat by just double clicking it, it does what it should and launches MyProgram.exe no issues. However, when I try and launch the bat from MyCompiledScript.exe, I run into issues. The first issue I encountered, when I try to run MyCompiledScript.exe from my Desktop, it opens the command prompt to start to run the batch, then closes it, then opens cmd again, then closes it, all very quickly, ad infinitum. The batch never completes and runs the MyProgram.exe, just keeps opening and closing a cmd window until I move the mouse to take the machine out of idle. I was able to read what it said: First it just reads the code in MyBatch.bat, then finishes with "MyProgram.exe is not recognised as an internal or external command, operable program or batch file."

I did a bit of Googling and saw a thread on these boards that mentioned that batch files can misbehave with AutoIt scripts when they are in different directories, So I copied the MyCompiledScript.exe to the directory where the MyBat.bat and MyProgram.exe is. Success! Almost..... It launched MyBat.bat which in turn launched MyProgram.exe. Only issue is, I now have 4 instances of MyProgram.exe instead of just 1, which is what I want. It's almost like the script is running, doing what it should, then running through again and doing it again 3 or 4 times before it realises MyProgram.exe is actually already running. I need it to wait, maybe say 5 or 10 seconds before trying again, but I'm not quite sure how. Is this something that can be done easily?

If I have to run MyCompiledScript.exe from the same directory as the others that's fine, I'm not too worried about that half of the problem (although I am curious about it). I would like for MyProgram.exe to only open a single instance though.

I tried compiled in both 32 and 64 bit without noticeable difference. I assume I should be compiling as 64-bit give my setup is 64-bit?

This is where I’m at:

#include <Timers.au3>
While 1
   Sleep(10)
   $idleTimer = _Timer_GetIdleTime()
   If $idleTimer > 30000 And Not ProcessExists("MyProgram.exe") Then
      Run("C:\PATH\MyBat.bat")
   ElseIf $idleTimer < 10 Then
      ProcessClose("MyProgram.exe")
   EndIf
WEnd

 

Thank you very much!

Share this post


Link to post
Share on other sites
Bilgus

Pretty sure you would be better served showing us the batch file so we could run it directly from your script, You could also directly run it in a cmd window if that was a requirement

see here for how to use the command prompt

https://www.autoitscript.com/wiki/Snippets_(_CMD_)

 

#include <Timers.au3>
Local Const $sProcessName = "MyProgram.exe"

While 1

   $idleTimer = _Timer_GetIdleTime()
   If $idleTimer > 30000 And Not ProcessExists($sProcessName) Then
      Run("C:\PATH\MyBat.bat")
      ProcessWait ( $sProcessName, 30) ;Wait for the Process to start for 30 seconds
   ElseIf $idleTimer < 10 Then
      ProcessClose($sProcessName)
      Sleep(25000) ;No Point in going back yet
   Else
      Sleep(100) ;100 MilliSeconds
   EndIf
   
WEnd
Ps next time post code using the button  < > (code tags) 

 

Share this post


Link to post
Share on other sites
wisepage

Are you saying I can include the batch file contents within my script and bypass loading the batch altogether? That might be cool! 

The reason I didn't include it initially is because it has some sensitive information in it. I guess I could remove it before sharing. Basically I want to use this for GPU crypto mining on my PC. Anybody familiar with mining has probably heard of Nicehash. It has this great function where it mines only when the PC is idle. So when I'm not using my PC, it can be mining without me needing to remember to start and stop the miner all the time. However, I want to do this for different mining software (in this case, EWBF Miner on Mining Pool Hub), which doesn't have in built "mine when idle" functionality. The miner.exe requires a batch file to launch it which contains pool info, username,  password and a few other snippets. 

How would I go about including the batch info directly into my script? 

Share this post


Link to post
Share on other sites
wisepage

Sorry, can't seem to edit my post. 

I can see your suggested changes to my script:

Local Const, adding of ProcessWait, the additional Else.

I understand the ProcessWait, that's obvious what that does, but not what the other 2 additions do. What is the goal of these? Also I don't understand the significance of $s, as opposed to me using " " . Sorry, major noob here :(

Share this post


Link to post
Share on other sites
Earthshine

he assigned your process name to a constant, and just uses that in the function calls, you can still hard-code process names but then your code is not reusable if you want to use it with another process. He's teaching you good coding habits.


My resources are limited. You must ask the right questions

 

Share this post


Link to post
Share on other sites
Bilgus

This Should get you started

#include <Timers.au3>
;??https://github.com/nanopool/ewbf-miner/releases

Global Const $sProcessName = "miner.exe"

Global $sProcessPath = @ScriptDir & "\" & $sProcessName ;Note: Place Your Script in the same directory
Global $sServer = "abc.123.bitcoin.org"
Global $iPort = 1234
Global $sUser = "a136951234asDfGHIJqwertyrando"
Global $sPass = "01234istheworst.password"
Global $iLog = 0
Global $ifee = 0
Global $iTempLimit = 65

Global $iIdleMs = 30000
Global $iWaitMs = 100

Global $sCmdLine = $sProcessPath & _
        SW("server", $sServer) & SW("port", $iPort) & _
        SW("user", $sUser) & SW("pass", $sPass) & _
        SW("log", $iLog) & SW("fee", $ifee) & _
        SW("templimit", $iTempLimit) & SW("pec", "")

RunApp()

Func SW($sName, $vVal) ;Creates a switch for command options
    Return " --" & $sName & " " & $vVal
EndFunc   ;==>SW

Func $RunApp()
    While 1

        Local $iIdleTimer = _Timer_GetIdleTime()
        If $iIdleTimer > $iIdleMs And Not ProcessExists($sProcessName) Then
            Run(@ComSpec & ' /k ' & $sCmdLine) ;Keeps window open when done
            ;Run(@ComSpec & ' /c ' & $sCmdLine,"");Closes window when done
            ;Run(@ComSpec & ' /c ' & $sCmdLine,"",@SW_HIDE);Hides Window<----use this one once its working properly
            ProcessWait($sProcessName, 30) ;Wait for the Process to start for 30 seconds
        ElseIf $iIdleTimer < $iWaitMs Then
            ProcessClose($sProcessName)
            Sleep($iIdleMs) ;No Point in going back yet
        Else
            Sleep($iWaitMs)
        EndIf

    WEnd
EndFunc   ;==>$RunApp

Note that you probably don't need comspec

Run($sCmdLine, "", @SW_Hide)

Will probably work just as well

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

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.