Here is my code
Set objFSO = CreateObject("Scripting.FileSystemObject")
a = "#echo off && " & _
"pushd ""\\xxxxx.local\cfs\Development\Docs\Baseline"" &&" & _
"cls &&" & _
"dir /b /a-d &&" & _
"popd"
Set objShell = CreateObject("WScript.Shell").Exec("%comspec% /c " & a)
execStdOut = objShell.StdOut.ReadAll()
msgbox execStdOut
Basically I am trying to run Dir command on a network drive. It works fine, but the only issue is that the output contains a garbage character in the beginning. Not sure why?
Output
If I run the same steps in a batch file, the output is correct
The answer to your question is that cls is being captured by the StdOut stream and interpreted as an extended character. Get rid of it. You don't need it.
Just so I feel like I've done something, here's the script rewritten as a batch + JScript hybrid. Save it with a .bat extension if you want to mess with it.
#if (#CodeSection == #Batch) #then
#echo off
setlocal
if "%~1"=="shell" (
pushd "\\xxxxx.local\cfs\Development\Docs\Baseline"
dir /b /a-d
popd
goto :EOF
)
cscript /nologo /e:JScript "%~f0"
goto :EOF
#end // end batch / begin JScript
var oSH = WSH.CreateObject('Wscript.Shell'),
proc = oSH.Exec("cmd /c " + WSH.ScriptFullName + " shell");
oSH.popup(proc.StdOut.ReadAll());
As an added bonus, here's the same thing with a lovely "ding" noise added.
#if (#CodeSection == #Batch) #then
#echo off
setlocal
if "%~1"=="shell" (
pushd "\\xxxxx.local\cfs\Development\Docs\Baseline"
dir /b /a-d
popd
goto :EOF
)
cscript /nologo /e:JScript "%~f0"
goto :EOF
#end // end batch / begin JScript
var oSH = WSH.CreateObject('Wscript.Shell'),
noise = WSH.CreateObject('WMPlayer.OCX.7'),
proc = oSH.Exec("cmd /c " + WSH.ScriptFullName + " shell");
with (noise) {
URL = oSH.Environment('Process')('SYSTEMROOT') + '\\Media\\Windows Exclamation.wav';
Controls.play();
}
oSH.popup(proc.StdOut.ReadAll());
The ♀ character is ASCII control character Line Feed 0x0A, a residuum of CLI cls command. Just omit the "cls &&" & _ line in your code as follows:
a = "#echo off && " & _
"pushd ""\\xxxxx.local\cfs\Development\Docs\Baseline"" &&" & _
"dir /b /a-d &&" & _
"popd"
Related
Below mentioned batch file displays InstallDate (Converted):
#echo off
for /f "delims=" %%A in ('WMIC OS GET InstallDate /format:value') do (
#for /f "tokens=2 delims==" %%B in ("%%A") do (
Call :ConvertDate %%B
)>"%temp%\%~n0.txt"
)
for /f "delims=" %%D in ('Type "%temp%\%~n0.txt"') do ( set InstallDate=%%D )
echo Install Date: %InstallDate%
pause
::**********************************************************************
Rem Function for Converting WMI Dates to a Standard Date-Time Format
:ConvertDate <Date>
(
echo WScript.echo WMIDateStringToDate("%~1"^)
echo Function WMIDateStringToDate(Mydate^)
echo WMIDateStringToDate = CDate(Mid(Mydate, 5, 2^) ^& "/" ^& _
echo Mid(Mydate, 7, 2^) ^& "/" ^& Left(Mydate, 4^) _
echo ^& " " ^& Mid (Mydate, 9, 2^) ^& ":" ^& _
echo Mid(Mydate, 11, 2^) ^& ":" ^& Mid(Mydate,13, 2^)^)
echo End Function
)>"%temp%\%~n0.vbs"
cscript /nologo "%temp%\%~n0.vbs" "%~1"
Del "%temp%\%~n0.vbs"
exit /b
Output:
Install Date: 24/05/2020 12:54:28
Now, For this I am trying to create and combine Desire Output like:
Install Date: 24/05/2020 12:54:28 (114 Days Ago)
I have tried several things but failed. is there any way to do this in batch?
Thanks.
As you're already using wsh for your date conversion, you may as well use it to retrieve the wmi information too.
Here's a single hybrid batch-file which should do that for you, without the need to write a vbs file, run it, then delete it:
<!-- :
#"%__APPDIR__%cscript.exe" //NoLogo "%~f0?.wsf"
#Pause & GoTo :EOF
-->
<Job><Script Language="VBScript">
On Error Resume Next
Set objWMIService = GetObject("winmgmts://./root/cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem in colItems
dtmInstalled = ParseDat(objItem.InstallDate)
numInstalled = DateDiff("n",dtmInstalled,ParseDat(objItem.LocalDateTime))
numInstDays = (numInstalled \ 60) \ 24
strMessage = "Install Date: " & dtmInstalled
If numInstDays = 0 Then
strMessage = strMessage & " (Today)"
ElseIf numInstDays > 1 Then
strMessage = strMessage & " (" & numInstDays & " Days Ago)"
Else
strMessage = strMessage & " (" & numInstDays & " Day Ago)"
End If
Next
WScript.Echo strMessage
WScript.Quit
Function ParseDat(ByVal strDate)
strYear = Left(strDate,4)
strMonth = Mid(strDate,5,2)
strDay = Mid(strDate,7,2)
strDat = strDay & "/" & strMonth & "/" & strYear
strHour = Mid(strDate,9,2) - strTimeShift
strMins = Mid(strDate,11,2)
strSecs = Mid(strDate,13,2)
strTime = strHour & ":" & strMins & ":" & strSecs
ParseDat = strDat & " " & strTime
End Function
</Script></Job>
As you've made no attempt at calculating the number of days yourself, I will not be explaining any of the above, modifying it, or adjusting it should you decide to modify your question post submission.
I want to pass variables from VBScript to batch but it wouldn't work.
My VBScript:
Dim shell
Set shell = CreateObject("WScript.Shell")
strnaam = InputBox ("naam")
and my batch:
#echo off
cls
echo %strnaam%
pause
I want the variable strnaam from my VBScript to my batch.
The most obvious way would be to run the vbscript as a For /F command and save its returned output as a variable:
#Echo Off
:NaamBox
Set "naam="
(Echo WScript.Echo InputBox("Naam:"^))>"%TEMP%\naam.vbs"
For /F Delims^=^ EOL^= %%A In ('CScript //NoLogo "%TEMP%\naam.vbs"')Do Set "naam=%%A"
If Not Defined naam GoTo NaamBox
Del "%TEMP%\naam.vbs"
Echo Uw naam is %naam%
Pause
If you don't like the idea of writing, running, then deleting the file, you could also embed your VBScript within the batch file:
<!-- :
#Echo Off
Echo Typ gelieve uw naam in de popup doos en OK te selecteren
For /F Delims^=^ EOL^= %%A In ('CScript //NoLogo "%~f0?.wsf"')Do Set "naam=%%A"
If Defined naam Echo Uw naam is %naam%&Pause
Exit /B
-->
<Job><Script Language="VBScript">
WScript.Echo InputBox("Naam:")
</Script></Job>
You can pass the variables only via environment variables:
The create_variable.vbs file:
Dim WshShell, WshEnv
Set WshShell = CreateObject("WScript.Shell")
Set WshEnv = WshShell.Environment("USER") ' can be either SYSTEM, USER, VOLATILE OR PROCESS
' current value
WScript.Echo "Process: NAAM=" & WshEnv.Item("NAAM")
WshEnv("NAAM") = "This text will appear in batch"
WScript.Echo "Process: NAAM=" & WshEnv.Item("NAAM")
Set WshEnv = Nothing
Set WshShell = Nothing
Then the batch file show_vbs_variable.bat (you have to open a new cmd.exe to have the new variable there! If you need more infor here is a topic on SO that covers it.:
#echo off
cls
echo %naam%
pause
vbs script for clearing up the variable clearing_variable.vbs:
Dim WshShell, WshEnv
Set WshShell = CreateObject("WScript.Shell")
Set WshEnv = WshShell.Environment("USER") ' can be either SYSTEM, USER, VOLATILE OR PROCESS
' current value
WScript.Echo "Process: NAAM=" & WshEnv.Item("NAAM")
'Deleting the env variable
WshEnv.Remove("NAAM")
WScript.Echo "Process: NAAM=" & WshEnv.Item("NAAM")
Set WshEnv = Nothing
Set WshShell = Nothing
I have a batch that create shortcut based on the order of files, the problem is that when it comes to numbers he presents the following problem when passing the number 100.
01.mp4
02.mp4
03.rmvb
04.mp4
05.rmvb
06.rmvb
07.rmvb
08.rmvb
09.rmvb
10.rmvb
100.mp4
101.mp4
102.mp4
103.mp4
104.mp4
105.mp4
106.mp4
107.mp4
108.mp4
109.mp4
11.rmvb
I searched here and found various methods however the script I use works with folders and files that sometimes use accents, & and/or !
Example: C:\Séries & Movies\Remix!.mkv (Brazil and use E place of and).
I wonder if there is any way to check the content and organize it can be properly before you save it in .ini or after saving the same in .ini.
Observations:
The folder path is loaded the first time the Set command.
After entering the path he saved in an .ini file and always loaded.
The Script list only files within the directory does not list subfolders and files and folders within it.
The script needs other files to work the download link is below:
https://www.mediafire.com/?zcoybkfo8k4nm1t
My Full Code:
#Echo off
Title Create shortcuts in alphabetical order
mode con:lines=3 cols=25
Color 1f
CD /D "%~dp0"
If Exist "Files\command.ini" For /f "usebackq delims=" %%x in ("Files\command.ini") do (set "%%x")
If Exist "Files\Config.ini" For /f "usebackq delims=" %%x in ("Files\Config.ini") do (set "%%x")
If Exist "Files\Files.ini" Goto shortcuts
If Exist "Files\command.ini" Goto shortcuts
If Exist "Files\Config.ini" Goto shortcuts
for %%F in (""%1"") do Set "location-of-files=%%~F"
for %%F in ("%location-of-files%") do IF "%%~F" NEQ """" Set "location-of-files=%location-of-files:"=%" & Set Number=1 & Goto LocationofFiles2
:LocationofFiles
mode con:lines=18 cols=78
Set "location-of-files=r1u4unoiwqa6">nul 2>&1
cls
echo Location of Files
Set /p location-of-files="¯ Location of Files: "
Set "location-of-files=%location-of-files:"=%"
Set Number=1
IF "%location-of-files%"=="r1u4unoiwqa6" Goto LocationofFiles
:LocationofFiles2
mode con:lines=18 cols=78
Set "Menu=">nul 2>&1
cls
for %%F in ("%location-of-files%") do Echo %%~F
echo 1(Yes) 2(No)
Set/p Menu="¯ Menu: "
IF "%Menu%"=="1" Goto Iniciar
IF "%Menu%"=="2" Goto LocationofFiles
Goto LocationofFiles2
:Iniciar
if not exist "%location-of-files%" Cls & Start /Wait Files\Error.vbs & Goto LocationofFiles
:Name-AnimeSerie1
Set "Serie_Anime=">nul 2>&1
cls
echo Name Serie
Set /p Serie_Anime="¯ Name: "
IF "%Serie_Anime%"=="" Goto Name-AnimeSerie1
:Name-AnimeSerie2
Set "Menu=">nul 2>&1
cls
for %%F in ("%Serie_Anime%") do Echo %%~F
echo 1(Yes) 2(No)
Set/p Menu="¯ Menu: "
IF "%Menu%"=="1" Goto shortcuts
IF "%Menu%"=="2" Goto Name-AnimeSerie1
Goto Name-AnimeSerie2
:shortcuts
If Exist "Files\Config.ini" For /f "usebackq delims=" %%x in ("Files\Config.ini") do (set "%%x")
If Not Exist "%location-of-files%" Del /q "C:\Users\%username%\Desktop\%ep2% - %Serie_Anime%.lnk">nul 2>&1 & Start /Min /Wait Files\DesktopRefresh.exe>nul 2>&1 & Goto end
Dir /a-d /b "%location-of-files%" >Files\Files.ini
Echo r1u4unoiwqa6.ending >>Files\Files.ini
Start "exclamation01" /Min /Wait "Files\exclamation01.vbs">nul 2>&1
Set location-of-files > Files\Config.ini
Set Serie_Anime >> Files\Config.ini
Set Number > Files\command.ini
If Exist "C:\Users\%username%\Desktop\%ep2% - %Serie_Anime%.lnk" Del /q "C:\Users\%username%\Desktop\%ep2% - %Serie_Anime%.lnk">nul 2>&1 & Start /Min /Wait Files\DesktopRefresh.exe>nul 2>&1
setlocal EnableDelayedExpansion
For /f "usebackq delims=" %%x in ("Files\command.ini") do (set "%%x")
For /f "usebackq delims=" %%x in ("Files\Config.ini") do (set "%%x")
set "cmd=findstr /R /N "^^" Files\Files.ini | find /C ":""
for /f %%a in ('!cmd!') do set Numbers=%%a
set lines=%Number%
set Atual=1
for /f "delims=" %%a in ('type Files\Files.ini') do (
for %%b in (!lines!) do (
if !Atual!==%%b Set "Ep1=%%a"
)
set /a "Atual = Atual + 1"
)
Set "Ep2=%Ep1%"
set "find=*."
call set delete=%%Ep2:!find!=%%
call set Ep2=%%Ep2:!delete!=%%
Set Ep2=%Ep2:.=%
Set Ep1 > Files\command.ini
Set Ep2 >> Files\command.ini
Set lines >> Files\command.ini
Set Number >> Files\command.ini
endlocal
Start "exclamation02" /Min /Wait "Files\exclamation02.vbs">nul 2>&1
For /f "usebackq delims=" %%x in ("Files\command.ini") do (set "%%x")
For /f "usebackq delims=" %%x in ("Files\Config.ini") do (set "%%x")
IF "%Ep2%"=="r1u4unoiwqa6" Goto end
Start /Min /Wait Files\Shortcut.exe /F:"C:\Users\%username%\Desktop\%ep2% - %Serie_Anime%.lnk" /A:C /t:"%location-of-files%\%Ep1%" /D:"Episode %Serie_Anime%">nul 2>&1
If Not Exist "C:\Users\%username%\Desktop\[ shortcuts ].lnk" Echo %Serie_Anime%>Files\shortcut.ini & Start /Min /Wait Files\shortcut.vbs>nul 2>&1
Set /A Number = %lines% + 1
:::::::::::::::::::::::::::::::::::::::::::::
Set location-of-files > Files\Config.ini
Set Serie_Anime >> Files\Config.ini
:::::::::::::::::::::::::::::::::::::::::::::
Set Ep1 > Files\command.ini
Set Ep2 >> Files\command.ini
Set Number >> Files\command.ini
:::::::::::::::::::::::::::::::::::::::::::::
Exit
:end
If Not Exist "%location-of-files%" Start /Wait Files\PDoM.vbs>nul 2>&1
If Exist "%location-of-files%" Start /Wait Files\ending.vbs>nul 2>&1
If Exist "%location-of-files%" Start "Anime" "%location-of-files%">nul 2>&1
Del /q "Files\Files.ini">nul 2>&1
Del /q "Files\shortcut.ini">nul 2>&1
Del /q "Files\command.ini">nul 2>&1
Del /q "Files\Config.ini">nul 2>&1
Set "location-of-files=">nul 2>&1
Set "Serie_Anime=">nul 2>&1
Set "lines=">nul 2>&1
Set "Ep1=">nul 2>&1
Set "Ep2=">nul 2>&1
Goto LocationofFiles
Part where you need to use the DIR:
:shortcuts
If Exist "Files\Config.ini" For /f "usebackq delims=" %%x in ("Files\Config.ini") do (set "%%x")
If Not Exist "%location-of-files%" Del /q "C:\Users\%username%\Desktop\%ep2% - %Serie_Anime%.lnk">nul 2>&1 & Start /Min /Wait Files\DesktopRefresh.exe>nul 2>&1 & Goto end
Dir /a-d /b "%location-of-files%" >Files\Files.ini
Echo r1u4unoiwqa6.ending >>Files\Files.ini
Start "exclamation01" /Min /Wait "Files\exclamation01.vbs">nul 2>&1
Set location-of-files > Files\Config.ini
Set Serie_Anime >> Files\Config.ini
Set Number > Files\command.ini
If Exist "C:\Users\%username%\Desktop\%ep2% - %Serie_Anime%.lnk" Del /q "C:\Users\%username%\Desktop\%ep2% - %Serie_Anime%.lnk">nul 2>&1 & Start /Min /Wait Files\DesktopRefresh.exe>nul 2>&1
setlocal EnableDelayedExpansion
For /f "usebackq delims=" %%x in ("Files\command.ini") do (set "%%x")
For /f "usebackq delims=" %%x in ("Files\Config.ini") do (set "%%x")
set "cmd=findstr /R /N "^^" Files\Files.ini | find /C ":""
for /f %%a in ('!cmd!') do set Numbers=%%a
set lines=%Number%
set Atual=1
for /f "delims=" %%a in ('type Files\Files.ini') do (
for %%b in (!lines!) do (
if !Atual!==%%b Set "Ep1=%%a"
)
set /a "Atual = Atual + 1"
)
Set "Ep2=%Ep1%"
set "find=*."
call set delete=%%Ep2:!find!=%%
call set Ep2=%%Ep2:!delete!=%%
Set Ep2=%Ep2:.=%
Set Ep1 > Files\command.ini
Set Ep2 >> Files\command.ini
Set lines >> Files\command.ini
Set Number >> Files\command.ini
endlocal
Thanks in advance.
Set Arg = WScript.Arguments
set WshShell = createObject("Wscript.Shell")
Set Inp = WScript.Stdin
Set Outp = Wscript.Stdout
Set rs = CreateObject("ADODB.Recordset")
If LCase(Arg(1)) = "n" then
With rs
.Fields.Append "SortKey", 4
.Fields.Append "Txt", 201, 5000
.Open
Do Until Inp.AtEndOfStream
Lne = Inp.readline
SortKey = Mid(Lne, LCase(Arg(3)), LCase(Arg(4)) - LCase(Arg(3)))
If IsNumeric(Sortkey) = False then
Set RE = new Regexp
re.Pattern = "[^0-9\.,]"
re.global = true
re.ignorecase = true
Sortkey = re.replace(Sortkey, "")
End If
If IsNumeric(Sortkey) = False then
Sortkey = 0
ElseIf Sortkey = "" then
Sortkey = 0
ElseIf IsNull(Sortkey) = true then
Sortkey = 0
End If
.AddNew
.Fields("SortKey").value = CSng(SortKey)
.Fields("Txt").value = Lne
.UpDate
Loop
If LCase(Arg(2)) = "a" then SortColumn = "SortKey ASC"
If LCase(Arg(2)) = "d" then SortColumn = "SortKey DESC"
.Sort = SortColumn
Do While not .EOF
Outp.writeline .Fields("Txt").Value
.MoveNext
Loop
End With
ElseIf LCase(Arg(1)) = "d" then
With rs
.Fields.Append "SortKey", 4
.Fields.Append "Txt", 201, 5000
.Open
Do Until Inp.AtEndOfStream
Lne = Inp.readline
SortKey = Mid(Lne, LCase(Arg(3)), LCase(Arg(4)) - LCase(Arg(3)))
If IsDate(Sortkey) = False then
Set RE = new Regexp
re.Pattern = "[^0-9\\\-:]"
re.global = true
re.ignorecase = true
Sortkey = re.replace(Sortkey, "")
End If
If IsDate(Sortkey) = False then
Sortkey = 0
ElseIf Sortkey = "" then
Sortkey = 0
ElseIf IsNull(Sortkey) = true then
Sortkey = 0
End If
.AddNew
.Fields("SortKey").value = CDate(SortKey)
.Fields("Txt").value = Lne
.UpDate
Loop
If LCase(Arg(2)) = "a" then SortColumn = "SortKey ASC"
If LCase(Arg(2)) = "d" then SortColumn = "SortKey DESC"
.Sort = SortColumn
Do While not .EOF
Outp.writeline .Fields("Txt").Value
.MoveNext
Loop
End With
ElseIf LCase(Arg(1)) = "t" then
With rs
.Fields.Append "SortKey", 201, 260
.Fields.Append "Txt", 201, 5000
.Open
Do Until Inp.AtEndOfStream
Lne = Inp.readline
SortKey = Mid(Lne, LCase(Arg(3)), LCase(Arg(4)) - LCase(Arg(3)))
.AddNew
.Fields("SortKey").value = SortKey
.Fields("Txt").value = Lne
.UpDate
Loop
If LCase(Arg(2)) = "a" then SortColumn = "SortKey ASC"
If LCase(Arg(2)) = "d" then SortColumn = "SortKey DESC"
.Sort = SortColumn
Do While not .EOF
Outp.writeline .Fields("Txt").Value
.MoveNext
Loop
End With
ElseIf LCase(Arg(1)) = "tt" then
With rs
.Fields.Append "SortKey", 201, 260
.Fields.Append "Txt", 201, 5000
.Open
Do Until Inp.AtEndOfStream
Lne = Inp.readline
SortKey = Trim(Mid(Lne, LCase(Arg(3)), LCase(Arg(4)) - LCase(Arg(3))))
.AddNew
.Fields("SortKey").value = SortKey
.Fields("Txt").value = Lne
.UpDate
Loop
If LCase(Arg(2)) = "a" then SortColumn = "SortKey ASC"
If LCase(Arg(2)) = "d" then SortColumn = "SortKey DESC"
.Sort = SortColumn
Do While not .EOF
Outp.writeline .Fields("Txt").Value
.MoveNext
Loop
End With
End If
To use
cscript //nologo script.vbs sort {n|d|t|tt} {a|d} startcolumn endcolumn < input.txt > output.txt
Options
n - extracts a number from the columns specified. Looks for the first number.
d - extracts a time or date from the columns specified. Looks for the first date.
t - extracts a text string including spaces from the columns specified.
tt - extracts a text string discarding leading and trailing spaces from the columns specified.
a - sorts acending
d - sorts decending
startcolumn - the starting column, the first character is column 1
endcolumn - the ending column
This is what command line synax means
The following table describes the notation used to indicate command-line syntax.
Notation Description
Text without brackets or braces
Items you must type as shown
<Text inside angle brackets>
Placeholder for which you must supply a value
[Text inside square brackets]
Optional items
{Text inside braces}
Set of required items; choose one
Vertical bar (|)
Separator for mutually exclusive items; choose one
Ellipsis (…)
Items that can be repeated
After much searching, I found the hybrid JScript/batch utility called REPL.BAT the dbenham and got what I wanted, based on my code the script is:
Del /q "Files\Files.ini">nul 2>&1
for /f "tokens=2 delims=:" %%F in (
'dir /b /a-d "%location-of-files%\*.*"^|Files\repl "^(\w+).*" "00000$1:$&" a^|Files\repl ".*(\d{5}:)" "$1"^|sort'
) do echo %%F >> Files\Files.ini
I have a batch file which is used by dragging a folder containing .mp3s into the batch.
#echo off
cd %~dp0
setlocal enabledelayedexpansion enableextensions
set FLDR="%1"
if not defined FLDR ( echo Drag a folder to the batch to play its contents.
pause
goto:EOF )
for %%x in (%FLDR%\*.mp3) do set "MP3=!MP3! "%%x""
mp3player %MP3%
pause
It works fine with actual folders, but when dragging shortcuts, the variable %FLDR% ends up as "c:\link location\folder.lnk" instead of the actual folder location.
I have no idea how to get around this.
Here is a way to get the target using a little hybrid VBS/Batch file function.
#echo off
setlocal
Call :GetTarget "%~1" tgt
echo %tgt%
pause
exit /b
:GetTarget
#echo off & setlocal
set gt=%temp%\_.vbs
echo set WshShell = WScript.CreateObject("WScript.Shell")>%gt%
echo set Lnk = WshShell.CreateShortcut(WScript.Arguments.Unnamed(0))>>%gt%
echo wscript.Echo Lnk.TargetPath>>%gt%
set script=cscript //nologo %gt%
For /f "delims=" %%a in ( '%script% "%~1"' ) do set target=%%a
del %gt%
endlocal & set %~2=%target%
exit /b
HYBRID SCRIPT! No silly little temporary files.
::'<SUB>#echo off
::'<SUB>set shortcut=%~1
::'<SUB>if not defined shortcut goto 'usage
::'<SUB>if not %shortcut:~-4%==.lnk (if not %shortcut:~-4%==.url (set errorlevel=1
::'<SUB>goto 'usage ))
::'<SUB>if not exist %shortcut% (echo Error: Nonexistent shortcut
::'<SUB>set errorlevel=1
::'<SUB>goto:EOF )
::'<SUB>setlocal
::'<SUB>for /f "delims=" %%T in ('cscript //nologo //e:vbs %~nx0 "%shortcut%"') do set thing=%%T
::'<SUB>endlocal & set shortcut=%thing%
::'<SUB>goto:EOF
:'usage
::'<SUB>echo command-line shortcut redirect utility
::'<SUB>echo Usage: shortcut [file.lnk ^| file.url]
::'<SUB>echo The resulting link will be output to the %%shortcut%% variable.
::'<SUB>goto:EOF
set WshShell = WScript.CreateObject("WScript.Shell")
set Lnk = WshShell.CreateShortcut(WScript.Arguments.Unnamed(0))
wscript.Echo Lnk.TargetPath
Where <SUB> indicates the substitute character.
UPDATE: I found a much fully vbscript solution over at Wayne's World of IT, and modified it slightly to suit my needs:
If WScript.Arguments.UnNamed.Count = 1 Then
strShortcut = WScript.Arguments.UnNamed(0)
Else
WScript.Echo "Please supply the name of an lnk file or directory to read, eg c:\test.lnk or c:\shortcuts"
WScript.Quit(1)
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FolderExists(strShortCut) Then
Set objFolder = objFSO.getFolder(strShortcut)
For Each objfile in objFolder.Files
If objfile.type = "Shortcut" Then
Call Readshortcut(objFile.Path, strProperties)
dtmCreationDate = objFile.DateCreated
WScript.Echo dtmCreationDate & "," & strProperties
End If
Next
ElseIf objFSO.FileExists(strShortCut) Then
Call Readshortcut(strShortcut, strProperties)
WScript.Echo strProperties
Else
WScript.Echo "Error: Could not read '" & strShortcut & "'"
WScript.Quit(2)
End If
Set objFSO = Nothing
Function Readshortcut(ByRef strShortcut, ByRef strProperties)
set objWshShell = WScript.CreateObject("WScript.Shell")
set objShellLink = objWshShell.CreateShortcut(strShortcut)
strProperties = objShellLink.TargetPath & " " & objShellLink.Arguments
Set objShellLink = Nothing
Set objWshshell = Nothing
End Function
I am making a script that can allow me to archive all files of a given directory whom last modified date is superior to 30 days.
The files should be moved to a new folder and this folder must be zipped afterwards.
Aditionaly - and this is a bit crutial - in the archiving process, the files should be grouped by month. The name of the zipped folder should indicate the month and year of the contained files.
Example:
2012_12.zip (contains all files from December 2012) ;
2013_01.zip (contains all files from January 2013)
This is what I have so far:
ECHO OFF
ECHO.
SET /p folder=Which folder you want to archive?
ECHO.
ECHO %folder%
CHDIR %folder%
MKDIR Archive
ROBOCOPY "%folder%" "%folder%\Arquivo" /E /V /ETA /MOVE /XD "%folder%\Archive"
:: Exclude files newer than 30 days
FORFILES /P "%folder%\Archive" /D -31/12/2012 /D +1/12/2012 /C GOTO :ZIP
CALL:ZIP
SET filetozip="%folder%\Archive"
set tempdir=C:\Users\tiago.campos\Documents\OMS\FilesArchiver\tempdir
mkdir %tempdir%
copy %filetozip% %tempdir%
mkdir "%filetozip%\Archive"
rmdir %tempdir%
realdate
echo Set objArgs = WScript.Arguments > _zipIt.vbs
echo InputFolder = objArgs(0) >> _zipIt.vbs
echo ZipFile = objArgs(1) >> _zipIt.vbs
echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipIt.vbs
echo Set objShell = CreateObject("Shell.Application") >> _zipIt.vbs
echo Set source = objShell.NameSpace(InputFolder).Items >> _zipIt.vbs
echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipIt.vbs
echo wScript.Sleep 2000 >> _zipIt.vbs
CScript _zipIt.vbs %tempdir% "%filetozip%\Archive\2013.01.zip"
del "_zipIt.vbs"
pause
As a bonus feature, it would be very useful if instead of giving the directory as an input, the script would read from a csv file with more than one directory.
I'm a bit lost in the momement.
I thank in advance for every reply!
Since you're already using vbscript for zipping and vbscript is also better for performing arithmetic with dates, might as well do the whole thing in vbscript.
I didn't do the csv thing, but maybe you could call the script with a batch for %%I in (csvfile) do cscript /nologo archive.vbs %%I or similar. If no argument is passed, it archives the current working directory.
' archive.vbs
' usage: cscript archive.vbs (directory, optional)
if not wscript.arguments.count then
dir = left(WScript.ScriptFullName,(Len(WScript.ScriptFullName))-(len(WScript.ScriptName)))
else
dir = wscript.arguments(0)
if not Right(dir, 1) = "\" then
dir = dir & "\"
end if
end if
set fso = createobject("scripting.filesystemobject")
set shl = createobject("shell.application")
set osh = createobject("wscript.shell")
set files = fso.getFolder(dir).files
dim zips
dim folders
redim zips(-1)
redim folders(-1)
for each file in files
if DateDiff("d", file.datelastmodified, Date()) > 30 then
yyyymm = DatePart("yyyy", file.datelastmodified) & "_" & Right("0" & DatePart("m", file.datelastmodified), 2)
dest = dir & yyyymm & "\"
if not fso.folderexists(dest) then
fso.createFolder dest
zip = dir & yyyymm & ".zip"
redim preserve zips(ubound(zips) + 1)
redim preserve folders(ubound(folders) + 1)
zips(ubound(zips)) = zip
folders(ubound(folders)) = dest
end if
Wscript.echo "Moving " & file & " to " & dest
fso.moveFile file, dest
end if
next
set files = nothing
Wscript.echo "Copying finished."
on error resume next
for i = lbound(zips) to ubound(zips)
Wscript.echo i & ": Zipping " & folders(i) & " to " & zips(i)
set zip = fso.createtextfile(zips(i))
zip.write "PK" & chr(5) & chr(6) & string(18, chr(0))
zip.close
set zip = Nothing
shl.namespace(zips(i)).copyhere shl.namespace(folders(i)).items
do until shl.namespace(zips(i)).items.count = shl.namespace(folders(i)).items.count
wscript.sleep 100
loop
' This method of deleting folders is more reliable than fso.deletefolder
' for paths with long filenames.
osh.run "cmd /c rmdir /q /s """ & folders(i) & """", 1, true
next
Wscript.Echo "Done."