Registered: 2006-04-11
Posts: 39
Loc: Santa Fe, New Mexico
I need to create a script that will rename a group of files with the same file extension, to the current date (mmddyyyy)plus a random string to make them unique. These files are on flash memory on a digital audio recorder, and I need to automate copying these files to a network share. (450 employees with recorders)I would like to include this in a Kix script I have that copies the files exactly the way I want, but I need to rename them because once a batch of files is copied to the network, the recorder starts reusing names and when I try to copy another batch on a later day, I might end up overwriting files. I thought I might just call a DOS batch file from the Kix script because I am more familier with BATs than I am with Kix, but what I have come up with doesn't work. Code:
This batch file just renames the first file in the directory every time I run it. It generates the date and the random string like I want it to, but then it tries to use that same date and random string to rename ALL the files and of course generates errors that a file with that name already exists. I would prefer it to be in Kix, but I can use shell to get to DOS if I have to. I read Jooel's post in the UDF library forum called "Rename() - rename file or folder" but I don't get it at all. It seems very complex and I am just a newbie at this stuff. I have ordered a copy of the guide to scripting by Bob Kelly, but it has not arrived yet and I am lost... Any help would be appreciated. Thanks
#160777 - 2006-04-1210:00 PMRe: rename group of files to current date w/random string
MartMart KiX Supporter
Registered: 2002-03-27
Posts: 4673
Loc: The Netherlands
The code below shows an example on how to do this. It's not the most efficient way to do this but it should get you started on some ideas. It requires the DirPlus UDF (see link below).
!!THIS IS NOT TESTED SO BE CAREFUL!!
Code:
;Call the Driplus UDF. Call @SCRIPTDIR + "\DirPlus().udf" ; ;Enumerate all FILES on drive x: ;Change the drive to the you got in your setup. $files = dirplus("x:\","/a-d") ; ;Split the date on the / character and the join the parts with no separation characters. $date = Join(Split(@date, "/"),"") ; ;Get the filename without the drive letter so start counting at the 4th character. $filename = SubStr ($file, 4) ; ;Get the extension of the file. $ext = SubStr ($filename, Len($filename) - 4) ; ;Do the stuff inside the For each--next loop for each file found. For Each $file in $files ;Split the time at the : character and then join the parts with no separation characters. $time = Join(Split(@TIME, ":"),"") ;Copy the file and rename it during the copy process. Copy $file "y:\somefolder\" + $date + "-" + $time + $ext ;Sleep 1 second to get the $time var different for each file. Sleep 1 Next
Registered: 2006-04-11
Posts: 39
Loc: Santa Fe, New Mexico
Wow. Did you just right that? Way over my head. I might be able to use it if I stare at it for a few hours. Some of it makes sense to me, but the first line Call @SCRIPTDIR + "\DirPlus().udf" I don't get. Do I copy the DirPlus into my script or do I save it as another .kix and call it? Baffled.
#160779 - 2006-04-1210:28 PMRe: rename group of files to current date w/random string
Howard BullockHoward Bullock
KiX Supporter
Registered: 2000-09-15
Posts: 5809
Loc: Harrisburg, PA USA
In the example given, you would save the dirPlus function code in another file named "DirPlus().udf" and place it in the same directory as the script you are executing.
the line in question would then load the function into the current script.
Registered: 2006-04-11
Posts: 39
Loc: Santa Fe, New Mexico
Awesome. It works! It isn't grabbing the file extension though. The files are renamed and copied, just like you said, but no file extension at all. I am executing the script from the same directory the files are located in. Could that be the problem? Also, I changed the line Code:
$files = dirplus("x:\","/a-d") to read $files = dirplus("@SCRIPTDIR\","/a-d")
Registered: 2006-04-11
Posts: 39
Loc: Santa Fe, New Mexico
I am borrowing a script written by Dean Flaming. (Give credit where credit is due) This script generates a login window where the user enters a username, password and domain. These are stored as the variables $StringUsername, $StringPassword and $StringDomain. Near the bottom where it is trying to capture the file extension, everything looks right, but the files don't show up in the destination directory with a file extension of any kind.
Also, the part where it is trying to map to X:\ with the USE command has an error capturing variable that should open a messagebox telling the user they have entered the wrong password. It doesn't work most of the time. Worked yesterday, but doesn't work today. Haven't changed anything there...
Code:
;ADD YOUR STUFF HERE SUCH AS A PRINTER OR DRIVE MAPPING, ETC. Break On $RC = ClearError()
Function ClearError() Exit 0 EndFunction
If Not @USERID=$StringUsername MessageBox ("You must be logged onto this computer with your own Username and Password.","Access is Denied") Quit EndIf Use X: /Del Select Case InGroup ("NMDPS\D1ScheduleRead") Use X: "\\NAS2\SPDistrict1" /User:"@Domain\$StringUsername" /Password:"$StringPassword" Case InGroup ("NMDPS\D2SchudleRead") Use X: "\\NAS2\SPDistrict2" /User:"@Domain\$StringUsername" /Password:"$StringPassword" $ErrCode = @ERROR If @ERROR <> 0 MessageBox ("You have entered an incorrect password or you are logged into the computer "+ "as someone besides yourself. Please try again.","Invalid Password") Quit EndIf Case 1 MessageBox ("You do not have access to any District Folder. Please call the Helpdesk @ XXX-XXXX. "+ "Thank you.","Access is Denied") Quit EndSelect
If Not Exist ("X:\$StringUsername") MD "X:\$StringUsername" EndIf
MessageBox ("Please wait while your files are copied to the Network. This may take some time. "+ "A message box will appear to inform you when this is done.","Please Wait")
Break On $RC = ClearError()
Function ClearError() Exit 0 EndFunction
;Call the Driplus UDF. Call @SCRIPTDIR + "\DirPlus().udf" ; ;Enumerate all FILES on drive x: ;Change the drive to the you got in your setup. $files = dirplus("@SCRIPTDIR\DSS_FLDA","/a-d") ; ;Split the date on the / character and the join the parts with no separation characters. $date = Join(Split(@date, "/"),"") ; ;Get the filename without the drive letter so start counting at the 4th character. $filename = SubStr ($file, 4) ; ;Get the extension of the file. $ext = SubStr ($filename, Len($filename) - 4) ; ;Do the stuff inside the For each--next loop for each file found. For Each $file in $files ;Split the time at the : character and then join the parts with no separation characters. $time = Join(Split(@TIME, ":"),"") ;Copy the file and rename it during the copy process. Copy $file "X:\$StringUsername\" + $date + "-" + $time + $ext $ErrCode = @ERROR ;Sleep 1 second to get the $time var different for each file. Sleep 1 Next
MessageBox ("Your Files have been copied to the network.","File transfer Result") ;Del "@SCRIPTDIR\DSS_FLDA\*.WMA" Use X: /Del
;REMOVE THE FOLLOWING TEST LINE
;======================================================================= ;Exit the Script ;======================================================================= Quit
#160783 - 2006-04-1302:10 AMRe: rename group of files to current date w/random string
NTDOCNTDOC Administrator
Registered: 2000-07-28
Posts: 11634
Loc: CA
Well you don't specify some key variables in the script you posted. Here is your script cleaned up some but still not working without the other variables being supplied/defined.
#160784 - 2006-04-1309:44 AMRe: rename group of files to current date w/random string
NTDOCNTDOC Administrator
Registered: 2000-07-28
Posts: 11634
Loc: CA
Here Darrell,
Give this script a try. It will give a unique name pre-pended to each file plus the current name.
I highly recommend using YYYY-MM-DD as the sorting is much better using that method.
This code will give it the following type of output.
Original file name: computers.txt
It will place YYYY-MM-DD_HHMMSS_ for each file Then it will add a random number after the date/time The resulting file name would be something like this.
2006-04-13_003307_181_computers.txt
There are no checks in place to verify if the source or destination exist. It does not take into account any other type of possible file copy errors.
You supply the SOURCE, FILE-TYPE, DESTINATION and as long as there are no issues preventing the copy it should work fine. If you run it again you will have duplicate files with only the pre-pended name being different (the same as the DirPlus would do)
Registered: 2006-04-11
Posts: 39
Loc: Santa Fe, New Mexico
OK. After several days of tweaking I finally have the script running the way I would like. (Almost) There are a few remaining isuues that I need to work out and I was hoping someone out there has a suggestion. My book for Kix script editing by Bob Kelly came in, but our admin secretary went to pick it up and never came back. She gave notice and has been calling in sick every day since. Might need to reorder...
What I really need is to find a way to verify that my files have actually been copied to the network share before allowing the script to delete them from the USB storage device. I have to do a copy so that the new files show up with the current day's creation date. The recorders lose their time settings frequently and then the time\date resets to factory default. This messes me all up since I MUST retain these files for 90 days. No more. No less. When files created today are showing up with creation dates of 2 years ago it really causes problems. We are required by law to retain these recording for 90 days, and if my script fails to copy them, then deletes them from the recorder, then I might find myself in front of a judge explaining why I deleted them. Ouch. Not gonna happen. I put a statement after the file copy command that uses If @result. And that does sort of work. But I think this is only checking the result of the very last file copied. If the first 5 fail, and then the last one succeeds, then the script will not notify the end user in anyway, and will proceed to delete the files from the device. Bad. Don't know what to do with it. Code:
For Each $File in $Files If $File ;Split the time at the : character and then join the parts with no separation characters. $Time = Join(Split(@TIME,':'),"") ;Copy the file and rename it during the copy process. Copy $File 'X:\$StringUsername\' + $Date + '-' + $Time + '.WMA' ;Sleep 1 second to get the $Time var different for each file. Sleep 1 EndIf Next $result = @RESULT If $result = '1 file(s) copied.' $Msg = MessageBox ('Your Files have been succesfully copied to the ' + 'network.','File transfer Result') Else $Msg = MessageBox ('An Error has occurred during the file transfer process. ' + 'Your files are still on the recorder. Please Call the Helpdesk.','Error') EndIf
Here is the entirety of my script as it now reads: I know it is kind of long, but several people have asked for the entire script. Thanks in advance for any assistance. By the way, is there a way to automatically change the script so it fits in the window? I read about the "print thread" link but I don't see it here?
;=============================================================================================== ;Written in AdminScriptEditor Ver 2 ;Dean Flaming ;Sr. Systems Engineer ;MTM Technologies ;425-481-8181 (Seattle Office - Home Office) ;DFlaming@mtm.com ;http://www.mtm.com ;=========================== ;Author Variable Information ;=========================== $Author = "Dean Flaming - Sr. Systems Engineer - MTM Technologies" $Date = "Last Modified on 6/28/2005" ;====================================================================== ;This script is designed to create a login box for a user to type in ;their username, password, and domain. It then returns these three ;values as variables that the rest of the script(s) can use. ; ;To use this script, remove the "$Test = MessageBox" line around lines ;90-100 and add whatever you need (i.e. USE statement or whatever) ;after the ENDFUNCTION line. ; ;You no longer need to have KIXFORMS.DLL installed and registered unless ;you wish to run this script from inside the KIXSCRIPTS editor or directly ;against the KIX engine. ; ;To obtain the latest copy of KIXFORMS.DLL go to http://www.kixforms.com ;and select DOWNLOADS. Copies of KIXTART and KIXTART Help files can be ;found here as well. ;====================================================================== ;===============================================================================================
;KixForms Variables Global $WindowsKey,$WindowsValue,$SystemFolder,$WindowsFolder,$NewKixFormsFile,$KixFormsRegistered, $KixFormsCopied,$KixFormsKey1,$KixFormsKey2,$KixFormsVer1,$KixFormsVer2,$CurrentKixFormsFile, $KixFormsKeyName1,$KixFormsKeyName2,$KixFormsExist1,$KixFormsExist2
;Login Box Variables Global $StringUsername,$StringPassword,$StringDomain
;======================================================================= ;Check for and Install KIXFORMS if necessary for use with this script ;======================================================================= $Nul = CheckKiXFormsDLL ;Copy in KIXFORMS.DLL and Register it
$Nul = ReadInWorkingFolder ;Read in path of ScriptFolder
;======================================================================= ;Call the Login Box ;======================================================================= $Nul = LoginWindow
;ADD YOUR STUFF HERE SUCH AS A PRINTER OR DRIVE MAPPING, ETC. Break On ;Dim $SO ;$SO=SetOption('Explicit','On') ;$SO=SetOption('NoVarsInStrings','On') ;$SO=SetOption('NoMacrosInStrings','On')
Dim $Msg,$RC Dim $Files,$Date,$Filename,$Ext,$Time
If Not @USERID=$StringUsername $Msg = MessageBox ('You must be logged onto this computer with your own Username '+ 'and Password.','Access is Denied') Quit 5 ;Set ERROR LEVEL to 5 for Access Denied EndIf
Use X: /Del /Persistent Select Case InGroup ('NMDPS\D1ScheduleRead') Use X: '\\NAS2\SPDistrict1' /User:@Domain+'\'+$StringUsername /Password:$StringPassword Case InGroup ('NMDPS\D2SchudleRead') Use X: '\\NAS2\SPDistrict2' /User:@Domain+'\'+$StringUsername /Password:$StringPassword ;Not 100% certain about the /Password:$StringPassword but don't think it ;would like a + sign being used there $ErrCode = @ERROR If $ErrCode <> 0 $Msg = MessageBox ('Error.','Error') Quit 5 ;Set ERROR LEVEL to 5 for Access Denied EndIf Case 1 $Msg = MessageBox ('You do not have access to any District Folder. Please call the Helpdesk ' + '@ XXX-XXXX. Thank you.','Access is Denied') Quit 5 ;Set ERROR LEVEL to 5 for Access Denied EndSelect
If GetFileAttr('X:\'+$StringUsername) & 16 Else MD 'X:\'+$StringUsername EndIf
$Msg = MessageBox ('Please wait while your files are copied to the Network. This may take ' + 'some time. A message box will appear to inform you when this is done.','Please Wait')
;Call the Driplus UDF. Call @SCRIPTDIR + "\DirPlus.udf" ; ;Enumerate all FILES on drive x: $Files = DirPlus(@SCRIPTDIR+'\DSS_FLDA','/a-d') ; ;Split the date on the / character and the join the parts with no separation characters. $Date = Join(Split(@Date,'/'),"") ; ;Get the filename without the drive letter so start counting at the 4th character. $Filename = SubStr ($File, 4) ; ;Get the extension of the file. $Ext = SubStr ($Filename, Len($Filename) - 4) ; ;Do the stuff inside the For each--next loop for each file found. For Each $File in $Files If $File ;Split the time at the : character and then join the parts with no separation characters. $Time = Join(Split(@TIME,':'),"") ;Copy the file and rename it during the copy process. Copy $File 'X:\$StringUsername\' + $Date + '-' + $Time + '.WMA' ;Sleep 1 second to get the $Time var different for each file. Sleep 1 EndIf Next $result = @RESULT If $result = '1 file(s) copied.' $Msg = MessageBox ('Your Files have been succesfully copied to the ' + 'network.','File transfer Result') Else $Msg = MessageBox ('An Error has occurred during the file transfer process. ' + 'Your files are still on the recorder. Please Call the Helpdesk.','Error') EndIf Use X: /Del /Persistent ;Del @SCRIPTDIR+'\DSS_FLDA\*.WMA'
;======================================================================= ;Exit the Script ;======================================================================= Quit
;======================================================================= ;Subfunctions and Routines ;======================================================================= ;======================================== ;Read in path of ScriptFolder ;======================================== Function ReadInWorkingFolder If Exist("@SCRIPTDIR\kixtartmsgs.dll") $WorkingFolder = "@SCRIPTDIR" Else $WorkingFolder = $EXEPath EndIf EndFunction
;======================================== ;Check for and Install KIXFORMS if ;necessary for use with this script ;======================================== Function CheckKiXFormsDLL ;Dim $NewKixFormsFile,$KixFormsRegistered,$KixFormsCopied, $KixFormsKey1,$KixFormsKey2,$KixFormsVer1 ;Dim $KixFormsVer2,$CurrentKixFormsFile,$KixFormsKeyName1, $KixFormsKeyName2,$KixFormsExist1,$KixFormsExist2 ;======================================== ;Read in path of new KIXFORMS.DLL file ;======================================== If Exist("@SCRIPTDIR\KIXFORMS.DLL") $NewKixFormsFile = "@SCRIPTDIR\KIXFORMS.DLL" Else $NewKixFormsFile = "$EXEPath\KIXFORMS.DLL" EndIf
;======================================== ;Set Variables for KIXFORMS registration and copy ;======================================== $KixFormsRegistered = 0 $KixFormsCopied = 0
;======================================== ;Determine Operating System (Win 9x or NT ;based) AND Windows AND System folders. ;For support of script ;======================================== ;Dim $WindowsKey,$WindowsValue,$SystemFolder,$WindowsFolder If "@INWIN" = "2" $WindowsKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\" $WindowsValue = "SystemRoot" $SystemFolder = "System" Else $WindowsKey = "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\" $WindowsValue = "SystemRoot" $SystemFolder = "System32" EndIf
;======================================== ;Lookup KIXFORMS.DLL Class IDs to ;determine if it is already registered ;For support of script ;======================================== $KixFormsKey1 = "HKEY_CLASSES_ROOT\CLSID\{F89DF848-618A-46F9-8A1C-396EA442BDD3}\InprocServer32\" $KixFormsKey2 = "HKEY_CLASSES_ROOT\TypeLib\{C8DCCD39-471D-4AFD-8EA2-89604A9C6252}\1.0\0\win32\"
;======================================== ;Read in path of existing KIXFORMS.DLL file ;For support of script ;======================================== $CurrentKixFormsFile = ReadValue("$KixFormsKey1","") ;======================================== ;Get File Versions of both new and ;existing KIXFORMS.DLL files ;For support of script ;======================================== $KixFormsVer1 = GetFileVersion("$NewKixFormsFile") $KixFormsVer2 = GetFileVersion("$CurrentKixFormsFile") ;======================================== ;Check if Current KixForms File Really ;Exists and set to value if necessary ;For support of script ;======================================== If $CurrentKixFormsFile = "" $CurrentKixFormsFile = $WindowsFolder + "\System32\KixForms.DLL" EndIf
;======================================== ;Compare version numbers of new and ;existing KIXFORMS.DLL files ;For support of script ;======================================== If (($KixFormsVer1 > $KixFormsVer2) Or ($KixFormsVer2 = "")) Copy "$NewKixFormsFile" "$CurrentKixFormsFile" /H $KixFormsCopied = 1 ;Set the copy value EndIf
;======================================== ;If KIXFORMS.DLL not registered, ;register the DLL ;For support of script ;======================================== $KixFormsKeyName1 = ReadValue("$KixFormsKey1","") ;Read in Key 1 $KixFormsKeyName2 = ReadValue("$KixFormsKey2","") ;Read in Key 2 $KixFormsExist1 = UCase(SubStr("$KixFormsKeyName1", Len("$KixFormsKeyName1")-11,12)) ;Parse out KIXFORMS.DLL $KixFormsExist2 = UCase(SubStr("$KixFormsKeyName2", Len("$KixFormsKeyName2")-11,12)) ;Parse out KIXFORMS.DLL
If Not (($KixFormsExist1 = "KIXFORMS.DLL") Or ($KixFormsExist2 = "KIXFORMS.DLL")) ;Determine if the KIXFORMS keys are present Shell ''$WindowsFolder\$SystemFolder\REGSVR32.EXE /s $WindowsFolder\System32\KIXFORMS.DLL'' $KixFormsCopied = 1 EndIf
;======================================================================= ;==========*****Done Checking for or Installing KIXFORMS*****=========== ;======================================================================= EndFunction
;Execute Form $Form.Show $TextBoxUsername.SetFocus
While $Form.Visible $Nul = Execute($Form.DoEvents) Loop EndFunction
;======================================== ;Login Button Clicked Function ;======================================== Function CmdUserLogin_Click() If $TextBoxUsername.Text = "" $Nul = $Form.MsgBox("You must specify a username before clicking LOGIN.", "Invalid Username",16) $TextBoxUsername.Text = $StringUsername Exit Sub Else $StringUsername = $TextBoxUsername.Text EndIf
If $TextBoxPassword.Text = "" $Nul = $Form.MsgBox("You must specify a password before clicking LOGIN.", "Invalid Password",16) $TextBoxPassword.Text = $StringPassword Exit Sub Else $StringPassword = $TextBoxPassword.Text EndIf
If $TextBoxDomain.Text = "" $Nul= $Form.MsgBox("You must specify a domain before clicking LOGIN.", "Invalid Domain",16) $TextBoxDomain.Text = $StringDomain Exit Sub Else $StringDomain = $TextBoxDomain.Text EndIf
Registered: 2006-04-11
Posts: 39
Loc: Santa Fe, New Mexico
Sorry. I know it is very hard to read like that. I had asked in my post if there was a way to do that automatically. Do I need to edit the whole thing manually? I know I can break up textlike messages, by adding a + sign, but what about the variable statements?
Global $WindowsKey,$WindowsValue,$SystemFolder,$WindowsFolder,$NewKixFormsFile, $KixFormsRegistered,$KixFormsCopied,$KixFormsKey1,$KixFormsKey2,$KixFormsVer1, $KixFormsVer2,$CurrentKixFormsFile,$KixFormsKeyName1,$KixFormsKeyName2,$KixFormsExist1,$KixFormsExist2
_________________________
Give a man a fish and he will be back for more. Slap him with a fish and he will go away forever.
You could also create 3 GLOBAL lines: Global $WindowsKey,$WindowsValue,$SystemFolder,$WindowsFolder,$NewKixFormsFile,$KixFormsRegistered Global $KixFormsCopied,$KixFormsKey1,$KixFormsKey2,$KixFormsVer1,$KixFormsVer2 Global $CurrentKixFormsFile,$KixFormsKeyName1,$KixFormsKeyName2,$KixFormsExist1,$KixFormsExist2
_________________________
Give a man a fish and he will be back for more. Slap him with a fish and he will go away forever.
Thanks. Now hopefully, someone will read your post and take the time to respond. The board is very quiet today as I suspect it is a day off for some folks.
_________________________
Give a man a fish and he will be back for more. Slap him with a fish and he will go away forever.
Registered: 2006-04-11
Posts: 39
Loc: Santa Fe, New Mexico
I spent yesterday playing with the @error macro and i think i have it all figured out now. I had it after the NEXT statement, which only returned an error for the LAST file copied. If the first 4 failed and the last succeeded then I would lose data. I moved it up inside of the For Each-Next function and it works much better now. I need the login box because these employees work 3 rotating shifts covering 24 hours a day and so share computers. I need to make sure they are putting their files into their own folder and not just the logged on user. I was able to locate and rem out the line that places the currently logged in users name into the login window so now they have to type in their name manually. If they type in anything other than the name of the currently logged on user, the script will pop up a messagebox and quit. Thank you all for your help. This was a pretty complex script for a first time Kix user. I could not have done it without your assistance.