how to rename files in a pair with a script - windows

I have 10 pdf files in a folder and im trying to find a way to rename them as pairs using a script for it to look like something like this
file131.pdf = order_receipt_1000.pdf
file304.pdf = invoice_1000.pdf
file542.pdf = order_receipt_1001.pdf
file194.pdf = invoice_1001.pdf
and so on for the next 8 ones

maybe this gives you a good starting point. The language is Autoit. (www.autoitscript.com)
Currently the script looks into the folder where it is saved for *pdf files. Then an new array with the files found is created an the second column contains the time when the file has been created. After that the last For-loop renames the files in chunks of two files each.
#include <Array.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>
Example()
Func Example()
Local $aFileList = _FileListToArray(#ScriptDir, '*.pdf', Default, True) ; change #scriptDir to the path you need
If #error = 1 Then
MsgBox($MB_SYSTEMMODAL, "", "Path was invalid.")
Exit
EndIf
If #error = 4 Then
MsgBox($MB_SYSTEMMODAL, "", "No file(s) were found.")
Exit
EndIf
_ArrayDisplay($aFileList, "Files FOUND")
Local $a[UBound($aFileList)][2]
For $i = 0 To UBound($aFileList) - 1
$a[$i][0] = $aFileList[$i]
$a[$i][1] = FileGetTime($aFileList[$i], $FT_CREATED, $FT_STRING) ; change FT_CREATED to what you need (created, modified, ...)
Next
_ArraySort($a, 0, 0, 0, 1)
_ArrayDisplay($a, "Sorted FileList")
Local $startcount = 1000, $y = 0
For $i = 1 To UBound($a) - 1 Step 2
FileMove($a[$i][0], 'order_receipt_' & $startcount + $y & '.pdf')
FileMove($a[$i + 1][0], 'invoice_' & $startcount + $y & '.pdf')
$y += 1
Next
EndFunc ;==>Example

Related

How does this loop works?

I have this code and I need to find an explanation to it especially the part
set files ="$files test$k.ppm"
what does it do?
set files = ""
set k = 100
while($k <210)
set files = "$files test$k.ppm"
# k = $k +10
end
https://explainshell.com/
set is for setting variables
This row set variable "files" into String with value as "{files} test{counter}.ppm"
files ="$files test$k.ppm"
At the beginning files is empty String...
#1st iteration (IN: files = "", k = 100)
files = "" + test100.ppm
#out files = test100.ppm
#2nd iteration (files = "" + test100.ppm; k = 110)
files = test100.ppm test110.ppm
#out files = test100.ppm test110.ppm
#Last iteration will be something like
test100ppm test110ppm {...} test200.ppm
Nothing else

Reading from check boxes doesn't work

I want to iterate through check boxes to get the caption text from each one. I have this code but it is not working. Could someone tell me whats wrong?
Is that because later in the For loop I am using $i to iterate through other things? But it doesn't even run the Send() command. Does AutoIt increment the $i variable automatically?
For $i = 1 to 64
If GUICtrlRead("$Checkbox" & $i,0) = $GUI_CHECKED Then
Local $checkboxtext = GUICtrlRead($Checkbox[$i], 1)
Local $checkboxtextsplit = StringSplit( $checkboxtext, "/")
$instanz = $checkboxtextsplit[1]
$favorite = "F" & $checkboxtextsplit[2]
$position = $checkboxtextsplit[3]
;Select actual Instance from Checkbox Name.
If $instanz = "1" Then
WinActivate($handle1)
Else
WinActivate($handle2)
EndIf
Send("{" & $favorite & "}")
;...
EndIf
Next
I was providing GUICtrlRead() its parameters the wrong way. Instead of:
If GUICtrlRead("$Checkbox" & $i, 0) = $GUI_CHECKED Then
Local $checkboxtext = GUICtrlRead($Checkbox[$i], 1)
It should be:
If GUICtrlRead($Checkbox & $i, 0) = $GUI_CHECKED Then
Local $checkboxtext = GUICtrlRead($Checkbox & $i, 1)
To retrieve a Checkbox checked/un-checked state use:
If GUICtrlRead($Checkbox & $i, 0) = $GUI_CHECKED Then ...
To read text of a Checkbox use:
$checkboxtext = GUICtrlRead($Checkbox & $i, 1)

Looping through WinList() result takes much time

I get a list of open windows and check if it contains a certain title. It is working but takes more than 10 seconds. Why does it take so long, what is wrong with my code?
Looks like WinList() doesn't list only visible windows.
$title = 0
$begintime = TimerInit()
MsgBox($MB_OK, "Timer", "Timer inicialized")
While $title = 0
$aList = WinList()
For $x = 1 To $aList[0][0]
;Check if a window with this title exists.
if $aList[$x][0] = "WindowTitle" Then
If $lastruntitle = "WindowTitle" Then
$title = 1
ExitLoop(2)
Else
SendMail4()
$lastruntitle = "WindowTitle"
$title = 1
ExitLoop(2)
EndIf
EndIf
Next
WEnd
Simple solution for your task is:
#include <Array.au3>
While 1
$aList = WinList()
_ArraySearch($aList, "WindowTitle", 0, 0, 0, 0, 1, 0)
If Not #error Then
MsgBox(0,"","Window found!")
Exit
EndIf
Sleep(100)
WEnd

Refresh a GUI using AutoIt

I am making AutoIt code and one of the items on the GUI needs to be updated every few seconds, and I can seem to get it to do it. To make it simple I have written some code that shows the problem:
$num = 0
GUICreate("Example")
$Pic1 = GUICtrlCreateLabel($num, 10, 10)
GUISetState()
While 1
sleep(1000)
$num = $num + "1"
WEnd
If the code was working then the number would change, but it does not. How do I make it refresh?
The number is updating, but your data is not. Plus, you are mixing integers with strings.
Luckily AutoIt converts them automatically. But take care, because you will have problems in other programming languages.
Here you go:
Local $num = 0
Local $hGUI = GUICreate("Example")
Local $Pic1 = GUICtrlCreateLabel($num, 10, 10)
GUISetState()
Local $hTimer = TimerInit()
While 1
;sleep(1000)
If TimerDiff($hTimer) > 1000 Then
$num += 1
GUICtrlSetData($Pic1, $num)
$hTimer = TimerInit()
EndIf
If GUIGetMsg() = -3 Then ExitLoop
WEnd
P.S.: Avoid using sleep in these situations while they will pause your script.
This is easily done with AdLibRegister passing the function name and then 1000 milliseconds (1 second).
Local $num = 0
Local $hGUI = GUICreate("Example")
Local $Pic1 = GUICtrlCreateLabel($num, 10, 10)
Local $msg
GUISetState()
AdLibRegister("addOne", 1000)
While 1
$msg = GUIGetMsg()
Switch $msg
Case $GUI_EVENT_CLOSE
Exit
EndSwitch
WEnd
Func addOne ()
$num += 1
GUICtrlSetData($Pic1, $num)
EndFunc
You need to set the new data in the GUI using GUICtrlSetData. Simply modify your loop like this:
While 1
sleep(1000)
$num += 1
GUICtrlSetData($Pic1, $num)
WEnd
Note that I removed the double-quotes so that AutoIt handles the values as integers.

Best way to wrap rsync progress in a gui?

I use rsync to synchronize files to Windows clients in a server agnostic way. What methods are available to send the progress of rsync to the parent process for display in a gui progress bar?
I imagine two or three choices exist. (1) Watch STDOUT (2) Watch rsync.exe log file, similar to unix tail (3) Watch rsync console output in memory.
Which one is best/preferred?
For this type of tasks, I use my own AutoIt script (freeware, Windows only). The script redirects the standard output into a graphical window, displaying it with the ability to scroll back, etc (very useful in long processes like XCOPYs / PKZIPs to check if any error did happen).
I use AutoIt because it's free, very easy to use, and can compile quickly into an .EXE. I think it's an excellent alternative to a complete programming language for this type of tasks. The downside is that it's for Windows only.
$sCmd = "DIR E:\*.AU3 /S" ; Test command
$nAutoTimeout = 10 ; Time in seconds to close window after finish
$nDeskPct = 60 ; % of desktop size (if percent)
; $nHeight = 480 ; height/width of the main window (if fixed)
; $nWidth = 480
$sTitRun = "Executing process. Wait...." ;
$sTitDone = "Process done" ;
$sSound = #WindowsDir & "\Media\Ding.wav" ; End Sound
$sButRun = "Cancel" ; Caption of "Exec" button
$sButDone = "Close" ; Caption of "Close" button
#include <GUIConstants.au3>
#include <Constants.au3>
#Include <GuiList.au3>
Opt("GUIOnEventMode", 1)
if $nDeskPct > 0 Then
$nHeight = #DesktopHeight * ($nDeskPct / 100)
$nWidth = #DesktopWidth * ($nDeskPct / 100)
EndIf
If $CmdLine[0] > 0 Then
$sCmd = ""
For $nCmd = 1 To $CmdLine[0]
$sCmd = $sCmd & " " & $CmdLine[$nCmd]
Next
; MsgBox (1,"",$sCmd)
EndIf
; AutoItSetOption("GUIDataSeparatorChar", Chr(13)+Chr(10))
$nForm = GUICreate($sTitRun, $nWidth, $nHeight)
GUISetOnEvent($GUI_EVENT_CLOSE, "CloseForm")
$nList = GUICtrlCreateList ("", 10, 10, $nWidth - 20, $nHeight - 50, $WS_BORDER + $WS_VSCROLL)
GUICtrlSetFont (-1, 9, 0, 0, "Courier New")
$nClose = GUICtrlCreateButton ($sButRun, $nWidth - 100, $nHeight - 40, 80, 30)
GUICtrlSetOnEvent (-1, "CloseForm")
GUISetState(#SW_SHOW) ;, $nForm)
$nPID = Run(#ComSpec & " /C " & $sCmd, ".", #SW_HIDE, $STDOUT_CHILD)
; $nPID = Run(#ComSpec & " /C _RunErrl.bat " & $sCmd, ".", #SW_HIDE, $STDOUT_CHILD) ; # Con ésto devuelve el errorlevel en _ERRL.TMP
While 1
$sLine = StdoutRead($nPID)
If #error Then ExitLoop
If StringLen ($sLine) > 0 then
$sLine = StringReplace ($sLine, Chr(13), "|")
$sLine = StringReplace ($sLine, Chr(10), "")
if StringLeft($sLine, 1)="|" Then
$sLine = " " & $sLine
endif
GUICtrlSetData ($nList, $sLine)
_GUICtrlListSelectIndex ($nList, _GUICtrlListCount ($nList) - 1)
EndIf
Wend
$sLine = " ||"
GUICtrlSetData ($nList, $sLine)
_GUICtrlListSelectIndex ($nList, _GUICtrlListCount ($nList) - 1)
GUICtrlSetData ($nClose, $sButDone)
WinSetTitle ($sTitRun, "", $sTitDone)
If $sSound <> "" Then
SoundPlay ($sSound)
EndIf
$rInfo = DllStructCreate("uint;dword") ; # LASTINPUTINFO
DllStructSetData($rInfo, 1, DllStructGetSize($rInfo));
DllCall("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr($rInfo))
$nLastInput = DllStructGetData($rInfo, 2)
$nTime = TimerInit()
While 1
If $nAutoTimeout > 0 Then
DllCall("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr($rInfo))
If DllStructGetData($rInfo, 2) <> $nLastInput Then
; Tocó una tecla
$nAutoTimeout = 0
EndIf
EndIf
If $nAutoTimeout > 0 And TimerDiff ($nTime) > $nAutoTimeOut * 1000 Then
ExitLoop
EndIf
Sleep (100)
Wend
Func CloseForm()
Exit
EndFunc
.NET has a pretty straight forward way to read and watch STDOUT.
I guess this would be the cleanest way, since it is not dependent on any external files, just the path to rsync. I would not be too surprised if there is a wrapper library out there either. If not, write and open source it :)
I've built my own simple object for this, I get a lot of reuse out of it, I can wrap it with a cmdline, web page, webservice, write output to a file, etc---
The commented items contain some rsync examples--
what I'd like to do sometime is embed rsync (and cygwin) into a resource & make a single .net executable out of it--
Here you go:
Imports System.IO
Namespace cds
Public Class proc
Public _cmdString As String
Public _workingDir As String
Public _arg As String
Public Function basic() As String
Dim sOut As String = ""
Try
'Set start information.
'Dim startinfo As New ProcessStartInfo("C:\Program Files\cwRsync\bin\rsync", "-avzrbP 192.168.42.6::cdsERP /cygdrive/s/cdsERP_rsync/gwy")
'Dim startinfo As New ProcessStartInfo("C:\Program Files\cwRsync\bin\rsync", "-avzrbP 10.1.1.6::user /cygdrive/s/cdsERP_rsync/gws/user")
'Dim startinfo As New ProcessStartInfo("C:\windows\system32\cscript", "//NoLogo c:\windows\system32\prnmngr.vbs -l")
Dim si As New ProcessStartInfo(_cmdString, _arg)
si.UseShellExecute = False
si.CreateNoWindow = True
si.RedirectStandardOutput = True
si.RedirectStandardError = True
si.WorkingDirectory = _workingDir
' Make the process and set its start information.
Dim p As New Process()
p.StartInfo = si
' Start the process.
p.Start()
' Attach to stdout and stderr.
Dim stdout As StreamReader = p.StandardOutput()
Dim stderr As StreamReader = p.StandardError()
sOut = stdout.ReadToEnd() & ControlChars.NewLine & stderr.ReadToEnd()
'Dim writer As New StreamWriter("out.txt", FileMode.CreateNew)
'writer.Write(sOut)
'writer.Close()
stdout.Close()
stderr.Close()
p.Close()
Catch ex As Exception
sOut = ex.Message
End Try
Return sOut
End Function
End Class
End Namespace
Check out DeltaCopy. It is a Windows GUI for rsync.
Check NAsBackup Its open source software that give Windows user Rsync GUI using Watch STDOUT.

Resources