Is the following codes right? Can I make just one with this two codes? - autoit

I'm trying to make a script to start two applications 8:00pm and stop it 8:00am, removing a dir when it stops.
I can't test it right now and I'm new with AutoIt so if someone have any suggestions to my code or know another way to do it (I tried with Task Manager calling batch files but I had some issues). I'll be very happy with your help!
My ideia is to make this script an exe and schedule with Task Manager to start on logon and when 8:00pm it start's the two applications (verifying the OS Arch). I need to make this applications stop 8:00am and I'm thinking in make a second script to do it, but if can be maked with just one script will be better.
It's for Windows machines, x64 or x86.
FIRST SCRIP:
#include <Timers.au3>
#NoTrayIcon
#persistent
loop {
If (A_Hour = 20) and (A_Min = 00) { ; is time 8:00pm?
If #OSArch = "X64" Then
RunWait (C:\ProgramData\...\FirstApp.exe)
Run (C:\ProgramData\...\SecondApp.exe)
Elseif #OSArch = "X86" Then
RunWait (C:\ProgramData\...\FirstApp_x86.exe)
Run (C:\ProgramData\...\SecondApp_x86.exe)
EndIf
}
sleep, 1000 * 60 ; sleep for 60 seconds so only loop once per minute
}
return
SECOND SCRIPT:
#include <Timers.au3>
#NoTrayIcon
#persistent
loop {
if (A_Hour = 08) and (A_Min = 00) { ; is time 8:00am?
Run (#COMSPEC & "taskkill /F /IM FirstApp.exe", #SW_HIDE)
Run (#COMSPEC & "taskkill /F /IM SecondApp.exe", #SW_HIDE)
Run (#COMSPEC & "RMDIR C:\ProgramData\MyDir\ /S /Q", #SW_HIDE)
}
sleep, 1000 * 60 ; sleep for 60 seconds so only loop once per minute
}
return

Try putting your commands inside a function.
#include <Misc.au3> ; needed for _Singleton
_Singleton(#ScriptName, 0) ; allows one one instance of running script
HotKeySet("{ESC}", _close) ; [optional to exit script]
Do
Sleep(20)
;waits for 8 AM
If #HOUR = "08" And #MIN = "00" And #SEC = "00" Then
one()
EndIf
;waits for 8 PM
If #HOUR = "20" And #MIN = "00" And #SEC = "00" Then
two()
EndIf
Until GUIGetMsg() = -3 ; $GUI_EVENT_CLOSE
Func one()
;Add the commmands you want executed at 8AM here
EndFunc ;==>one
Func two()
;Add the commmands you want executed at 8PM here
EndFunc ;==>two
Func _close()
Exit
EndFunc

Related

Compare current time to file date time last modified in Windows Batch File

I would like a command in a batch file to only execute if it has not been ran for the last 15 minutes. To achieve this I can create a "last_run" file to log the time last ran.
Where I am stuck is comparing the time last modified to the current time and taking action if the time last modified.
Here is my current code:
#echo off
set filename=last_run.txt
if not exist %filename% (
rem NOT EXISTS, CREATE FILE THEN PRINT THE LIST
echo.>"%filename%"
GOTO PrintList
) else (
rem FILE EXISTS, GET TIME LAST MODIFIED
FOR %%? IN (%filename%) DO (set filetime=%%~t?)
echo %filetime%
rem IF TIME LAST MODIFIED > 15 MINS PRINT THE LIST
if timediff??(%filetime%, current) > 15 mins {
GOTO PrintList
} else {
GOTO End
}
)
:PrintList
rem PRINT THE LIST
echo now print the list
rem WRITE TO THE FILE TO UPDATE TIME LAST MODIFIED
echo.>"%filename%"
GOTO End
:End
Another implementation using powershell from your batch-file:
#Echo Off
Set "filename=last_run.txt"
Set "minutes=15"
If Not Exist "%filename%" GoTo :PrintList
"%__APPDIR__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile If(((Get-Date)-(Get-Item ".\%filename%").LastWriteTime).Minutes -LT %minutes%){Exit 1}
If ErrorLevel 1 Exit /B
Rem Your payload below here.
:PrintList
CD.>"%filename%"
If you are happy to accept that the PC running this code will always have the appropriate entries in %PATH% and %PATHEXT%, you can change "%__APPDIR__%WindowsPowerShell\v1.0\powershell.exe" to just PowerShell.
Besides the missing time calculation, your code has a delayed expansion problem. (My solution below doesn't need delayed expansion)
cmd is incredibly crude when it comes to date/time calculation (it can be done, but...).
Better use the help of another language (like PowerShell):
#echo off
setlocal
set "filename=last_run.txt"
set "minutes=15"
if not exist "%filename%" (
break>"%filename%"
goto :PrintList
)
for /f %%a in ('"powershell Test-Path %filename% -OlderThan (Get-Date).AddMinutes(-%minutes%)"') do set "older=%%a"
if "%older%" == "True" (
echo %filename% is older than %minutes% minutes; print list
break>"%filename%"
goto :PrintList
) else (
echo %filename% is younger than %minutes% minutes; exiting
goto :eof
)
:PrintList
echo insert your payload here.
You could use total minutes with a powerhell command.
#echo off
set error=0
if not exist last_run.txt echo File not yet existed, first run will be now & set /a error+=1
for /f "delims=," %%i in ('powershell -command "(New-TimeSpan -Start (Get-Date "01/01/1970") -End (Get-Date)).TotalMinutes"') do set "now=%%i"
if "%error%" == "1" goto :run
for /f %%a in (last_run.txt) do set earlier=%%a
set /a result=%now%-%earlier%
if %result% geq 15 (
:run
echo RUN COMMANDS HERE
echo %now%>tmp.tmp
)
The concept is simple. We get the epoch time in minutes. Store the value in a file. Then compare the current minutes with the minutes in the file. if %now% is equal to or more than 15 from %earlier% the command will run. Additionally, if the file does not yet exist, it will create it and run the command first time. From there it will only run if the seconds in the file is 15 or less than current minutes.

Why Function "if ProcessExist" Don't Work in Others Computers

I'm trying to execute an IF ProcessExist.
in my win 10 64bit computer it works, but when i execute in other PC with win 7 or even with win 10. It do not execute.
#AutoIt3Wrapper_UseX64=N
If ProcessExists ("program.exe") Then
MsgBox ("", "Hold", "Test", 10)
Exit
Else
#RequireAdmin
Run(#ComSpec & " /c " & "C:\folder\file.bat", "", #SW_HIDE)
EndIf
Keep getting as if program.exe exist, but it's not.
#RequireAdmin must be on the very top of your script.
I assume it's not working when you compile the executable. It's probably called program.exe and it's finding its own process.
As for the Singleton see this:
_Singleton ( $sOccurrenceName [, $iFlag = 0] )
Enforce a design paradigm where only one instance of the script may be running
Example
#include <Misc.au3>
#include <MsgBoxConstants.au3>
If _Singleton("test", 1) = 0 Then
MsgBox($MB_SYSTEMMODAL, "Warning", "An occurrence of test is already running")
Exit
EndIf
MsgBox($MB_SYSTEMMODAL, "OK", "the first occurrence of test is running")

Running Autoit from command line and see errors/results

I am trying to run some autoit.au3 script from command line and see results there. I have put some ConsoleWrite inside script and also Exit(1) but after I run script nothing is shown in console. It just stop script on Exit and ConsoleWrite is not displayed.
I have use command:
"C:...(path to my AutoIt3.exe)" /ErrorStdOut "path_to_my_script.au3"'
Also I have tried to run script.exe with this same command but with similar (no) result. I would like to see output in console and/or custom error messages when script fail (I don't know if that is possible).
AutoIt3.exe is a GUI program. So the STD streams of a GUI program are not printed at a console by default.
The /ErrorStdOut argument redirects errors messages to Console instead of a Msgbox.
This argument does not enable print at the Console.
Command Prompt:
To print at a Command Prompt, you could pipe to more, i.e.
"C:...(path to my AutoIt3.exe)" /ErrorStdOut "path_to_my_script.au3" 2>&1|more
more reads from the Stdin stream and prints to Console.
I intentionly added 2>&1 so the Stderr stream is merged with
Stdout so you get the merged streams printed.
If you do not want the errors, then you can redirect the Stderr stream to nul i.e.
replace 2>&1 with 2>nul.
If you used a for loop at a Command Prompt, it would be i.e.
for /f "delims=" %A in ('"C:...(path to my AutoIt3.exe)" /ErrorStdOut test1.au3') do echo %A
If you use the for loop in batch-file, use %%A instead of %A. To also capture the Stderr, insert 2^>&1 into the for command or to ignore, insert 2^>nulinto the for command i.e.
for /f "delims=" %A in ('2^>nul "C:...(path to my AutoIt3.exe)" /ErrorStdOut test1.au3') do echo %A
The previous methods will not get the Exitcode.
AutoIt code:
An AutoIt script can get the Stdout and the Exitcode.
#pragma compile(Out, 'consoleau3.exe')
#pragma compile(Console, True)
$sAutoit = 'C:...(path to my AutoIt3.exe)'
$iPid = Run('"' & $sAutoit & '" /ErrorStdout ' & $CMDLINERAW, '', #SW_SHOW, 2) ; 2 = Get Stdout stream.
If #error Then Exit
; Open process handle.
$hPid = _ProcessOpenHandle($iPid)
; Get Stdout stream and then print to Console.
$sStdout = ''
Do
Sleep(10)
If $sStdout Then ConsoleWrite($sStdout & #CRLF)
$sStdout = StdoutRead($iPid)
Until #error
; Require process to be closed before calling _ProcessGetExitCode()
ProcessWaitClose($iPid)
; Get exitcode of process.
$iExitcode = _ProcessGetExitCode($hPid)
; Close process handle.
_ProcessCloseHandle($hPid)
Exit $iExitcode
Func _ProcessOpenHandle($iPID)
; Get the process handle of the process to query\n Return: Success Handle as array. Failure 0
Local Const $PROCESS_QUERY_INFORMATION = 0x400
Local $hPID = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', $PROCESS_QUERY_INFORMATION, 'int', 0, 'int', $iPID)
If #error Then Return SetError(#error, #extended, 0)
Return $hPID[0]
EndFunc
Func _ProcessGetExitcode($hPID)
; Get exitcode of the closed process\n Return: Success Exitcode as integer. Failure 0
Local $vPlaceholder
$hPID = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $hPID, 'int*', $vPlaceholder)
If #error Then Return SetError(#error, #extended, 0)
Return $hPID[2]
EndFunc
Func _ProcessCloseHandle($hPID)
; Close the handle of a process\n Return: Success 1. Failure 0
DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $hPID)
If #error Then Return SetError(#error, #extended, 0)
Return 1
EndFunc
Correct the path to AutoIt.exe in the code.
Compile to AutoIt code to executable. It will be a Console program
and will be named consoleau3.exe as to the #pragma compile directives.
Usage:
consoleau3 "path_to_my_script.au3"
Script arguments can be added i.e.
consoleau3 "path_to_my_script.au3" arg1 arg2 arg3 ...

Click on the outlook calendar by searching the calendar Image (_ImageSearch)

I am using Imagesearch.au3 to search the calendar image on outlook . Below is the code .
Created a new folder --> ImageSearch.au3 , ImageSearchDLL.dll , and the screenshot of the calendar is placed
#include <ImageSearch.au3>
$x=0
$y=0
start()
while 1
sleep(1000)
WEnd
Func Start()
while 1
$result = _ImageSearch("cal.png",1,$x,$y,0)
if $result=1 Then
ConsoleWrite("Sucesfull")
MouseMove($x,$y,10)
Else
ConsoleWrite("Img not found")
EndIf
WEnd
EndFunc
Problem : Throws an error message
"C:\Users...\Desktop\AutoIT\New folder\img\ImageSearch.au3" (44) : ==> Subscript used on non-accessible variable.:
if $result[0]="0" then return 0
if $result^ ERROR
The dll will not load while running as a script. I'm not sure why but it seems others have the same problem. I was able to compile the script as a 64 bit application and then the application loaded the DLL. After changing the tolerance, I was able to find the image.
Also, I would rewrite your code. You have two infinite while loops for no reason. I added a sleep to the remain while loop. I would increase the tolerance.
#include <ImageSearch.au3>
start()
Func Start()
while 1
$x=0
$y=0
$result = _ImageSearch("cal.png",1,$x,$y,20)
if $result=1 Then
MsgBox(0,"Found Image","moving mouse")
MouseMove($x,$y,10)
Else
MsgBox(0,"Img not found","not found")
EndIf
sleep(10000)
WEnd
EndFunc
I tested with the 64bit imagesearch located at http://www.autoitscript.com/forum/topic/148005-imagesearch-usage-explanation/page-2

No Output in NPPExec with Pascal

I want to write and build and execute a Pascal Program in Notepad ++. If i execute the program in cmd the output is normal, but in the console in nppexec the output is empty
My Code:
Program Edgar;
Uses Crt;
Var cnt, tip, pot : INTEGER;
Begin
TextColor(Red);
WriteLn('Hallo');
tip := -1;
cnt := 0;
Randomize;
pot := Random(2501)*10;
WriteLn(pot);
WHILE (tip <> pot) do
Begin
WriteLn('Tip: ');
ReadLn(tip);
if (tip < pot) then begin
WriteLn('Too low');
cnt := cnt + 1
end;
if (tip > pot) then begin
WriteLn('Too High');
cnt := cnt + 1
end;
end;
cnt:= cnt + 1;
WriteLn('IA IA');
WriteLn('Tries: ',cnt );
End.
Build Commands:
cd $(CURRENT_DIRECTORY)
fpc $(NAME_PART).pas
$(NAME_PART).exe
Output(Nppexec):
Free Pascal Compiler version 2.6.2 [2013/02/12]
for i386 Copyright (c) 1993-2012 by Florian Klaempfl
and others Target OS: Win32 for i386
Compiling ue23.pas
Linking ue23.exe 27 lines compiled, 0.1 sec , 33536 bytes code, 1900 bytes data
<<< Process finished.
(Exit code 0)
ue23.exe Process started >>>
If you enable unit CRT, the application will write to the console directly (using *console winapi functions) instead of using stdout.
Probably the console screen of npp is not a real console screen, but a capture of stdout (-piped) only.
Except not using crt (and thus not using cursor movement and coloring) there is not much that can be done, this is probably a NPP limitation.
After that, you need to press "Enter" while your cursor blinking in output side.
And you will get the output with these lines at the end.
<<< Process finished. (Exit code 0)
================ READY ================
There is no limitation, you can run commands from that output side of notepad++.

Resources