This thread outlines how to code batch hybrids that may include a combination of several scripting languages, such as batch, VBS, JScript, PowerShell, etc. The question is, whether a batch hybrid treats "foreign" language blocks as "functions", meaning calls to these blocks may include arguments like regular and delayed expansion batch variables, that are referenced as usual arguments like %1, %2, etc?
Example below shows the approach in the task of unzipping a file, while using this file unzip code, but it gives an error in Win10 64-bit - why? Note, the linked file unzip code gives an error as well when run in Win 10, but a different one.
<!-- : Begin batch script
#echo off
set "dir=C:\Temp\" & set "file=%USERPROFILE%\Downloads\archive.zip\"
cscript //nologo "%~f0?.wsf" "%dir%" "%file%"
exit /b
----- Begin wsf script --->
<job><script language="VBScript">
set fso = CreateObject("Scripting.FileSystemObject")
If NOT fso.FolderExists(%1) Then
fso.CreateFolder(%1)
End If
set objShell = CreateObject("Shell.Application")
set FilesInZip = objShell.NameSpace(%2).items
objShell.NameSpace(%1).CopyHere(FilesInZip)
set fso = Nothing
set objShell = Nothing
</script></job>
:: Error
..\test.bat?.wsf(9, 8) Microsoft VBScript compilation error: Invalid character
In vbscript the first argument is : wscript.Arguments(0)
the second argument is : wscript.Arguments(1)
So,you should write it like that :
`
----- Begin wsf script --->
<job><script language="VBScript">
set fso = CreateObject("Scripting.FileSystemObject")
If NOT fso.FolderExists(wscript.Arguments(0)) Then
fso.CreateFolder(wscript.Arguments(0))
End If
set objShell = CreateObject("Shell.Application")
set FilesInZip = objShell.NameSpace(wscript.Arguments(1)).items
objShell.NameSpace(wscript.Arguments(0)).CopyHere(FilesInZip)
set fso = Nothing
set objShell = Nothing
</script></job>
Related
I am trying to share values between my batch file and embedded script within it and I can't find a way to make it work. I am relatively new to embedded scripting...
I have tried to find an answer on the web and I can't find an answer to my question. It would need to be (all the scripts) in the same .bat file...
<!-- : Begin batch script
#echo off
cls
set "Shared_UserName=VelocityDK"
goto ShareValue
:ShareValue
cls
cscript //nologo "%~f0?.wsf" //job:UserName
pause >nul
cls & exit /force
----- Begin wsf script --->
<package>
<job id="UserName">
<script language="VBScript">
Dim Shared_UserName As String = %Shared_UserName%
WScript.Echo "Your username is: " & Shared_UserName
</script>
</job>
</package>
I am expecting the embedded VBScript to write the following output: Your username is VelocityDK. but instead, I get a message saying:
Microsoft VBScript compilation error: Expected end of statement
If you plan to use shell methods inside VBScript then use Windows Scripting Host (WSH) automation object. Please find the code:
Set wshShell = CreateObject( "WScript.Shell" )
userName = wshShell.ExpandEnvironmentStrings("%Shared_UserName%")
WScript.Echo "Your username is: " & userName
See refs :devguru.com or ss64.com
I have a text file that has the record of all the services in a server. I want to keep '#' for the few entries at the beginning of the line. I have created one vbscript file that contains the following code:
Const Readpurpose = 1
Const Writepurpose = 2
strServiceMonFile = WScript.Arguments(0)
strOldText = WScript.Arguments(1)
strNewText = WScript.Arguments(2)
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strServiceMonFile, Readpurpose)
strText = objFile.ReadAll
objFile.Close
Set objFile = objFSO.OpenTextFile(strServiceMonFile, Writepurpose)
strNewText = Replace(strText, strOldText, strNewText)
objFile.Write strNewText
objFile.Close
In order to execute the code, I am using a batch file and the code used is as follows:
cscript D:\Users\krkarthi\Desktop\replace.vbs "D:\Users\krkarthi\Desktop\test.txt" "Windows Update" "#Windows Update"
In the above mentioned batch code, I need to manually enter each and every entry which I need to keep # comment and for a plenty of services it is very difficult to proceed. I am thinking another way to have a separate text file lets say test1.txt that contains all the unwanted entries. A variable will define in a for loop to run on test1.txt and will run the above mentioned cscript code after do. The imaginative code is as follows:
FOR /f %%G in (D:\Users\krkarthi\Desktop\test1.txt)
DO
cscript D:\Users\krkarthi\Desktop\replace.vbs "D:\Users\krkarthi\Desktop\test.txt" "%%G" "#%%G"
Unfortunately, the above code didn't work at all. I don't understand where the error exists.
Try removing one % from the parameters in your code. It should work. Also you will not need double quotes while passing values to your code.
Corrected:
FOR /F %%G IN (D:\Users\krkarthi\Desktop\test1.txt) DO cscript D:\Users\krkarthi\Desktop\replace.vbs "D:\Users\krkarthi\Desktop\test.txt" "%%G" "#%%G"
Please check what is wrong with the below code. I'm trying to zip the file of one folder and placing it in other folder. I have 94 files but out of that only 80 to 82 or like that some files are zipping. I am using a .bat file:
#setlocal
#echo off
set TIMESTAMP = %DATE:~4,2%-%DATE:~7,2%-%DATE:~10,4%
::CD C:\Desktop\Batchscripts\TESTZIP
::md C:\Desktop\Batchscripts\TESTZIP\%TIMESTAMP%
ECHO ------- BEGIN zip ----------------
CScript "C:\Desktop\Batchscripts\TESTZIP\zip.vbs" "C:\Desktop\Batchscripts\%TIMESTAMP%\" C:\Desktop\Batchscripts\TESTZIP\%TIMESTAMP%.zip
ECHO All production export xml files are completed. please find the location C:\Desktop\Batchscripts\TESTZIP\%TIMESTAMP%.zip
Pause
IF NOT %ERRORLEVEL% EQU 0 (goto :error)
ECHO ------- END zip------------------
which is calling a VBScript:
'Get command-line arguments.
Set objArgs = WScript.Arguments
InputFolder = objArgs(0)
ZipFile = objArgs(1)
'Create empty ZIP file.
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set objShell = CreateObject("Shell.Application")
Set source = objShell.NameSpace(InputFolder).Items
objShell.NameSpace(ZipFile).CopyHere(source)
'Required!
wScript.Sleep 2000
Most likely your VBScript doesn't wait long enough. Try increasing the value to 5000 or 10000 milliseconds.
The Problem with the CopyHere method is that it runs asynchronously, i.e. it returns immediately instead of waiting until the operation is finished. However, the Shell.Application object is automatically destroyed when the script exits, thus terminating an ongoing CopyHere operation. If that operation wasn't completed at that point, your zip archive will be a couple files short.
I have several files where the filename consists of a date. I want to change the date & time of the files (filestamp) into that one which is in the filename by using a windows batchfile. Let assume the file is 2013-02-20.txt and I want that file having a datestamp correspondending to which is in the filename and thus set to 20130220, while the timestamp can be set to "00:00". I extract the year, month and date from the filename into variables but how to filestamp these files with that date & time?
for %%f in (*.txt) do (
set FILENAME=%%~nf
set YEAR=!FILENAME:~0,4!
set MONTH=!FILENAME:~5,2!
set DAY=!FILENAME:~8,2!
set TIME=00:00
)
Question is how to change the filedate and filetime using the variables YEAR, MONTH, DAY and TIME (in Linux I do it with the 'touch' command)?
I did my own CLI app written in .NET to get/set filestamps, it's so easy to use and has beneffits than filetouch for windows, maybe you will preffer to use mine app.
Download: http://elektrostudios.tk/FileDate.zip
Does it have to be a Batch File?
You can do it in Batch, but not easily. Stay with me here and don't lose heart. :)
Starting in this post - http://www.dostips.com/forum/viewtopic.php?f=3&t=4846
And there is some bleed-over to this post - http://www.dostips.com/forum/viewtopic.php?p=27422#p27422 and I will be perfectly honest with you, I have not re-timestamped a file using direct batch.
Have done it with the next thought or idea:
You can do this pretty easily in VBScript or in PowerShell..
VBS:
Set fso = CreateObject("Scripting.FileSystemObject")
' -- Re-date files
' Call Touch(Server.MapPath("/"), "somefile.htm", "2005-09-01")
' Call Touch("C:\", "somefile.txt", "2012-01-01")
Sub Touch(strDir, strFileName, NewDate)
Dim objShell, objFolder, objFile
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.NameSpace(strDir)
Set objFile = objFolder.ParseName(strFileName)
If fso.FileExists(strDir & strFileName) Then
objFile.ModifyDate = NewDate
End If
End Sub
PowerShell:
if ($DTNew) {
(dir $aZip).lastwritetime = $DTNew
}
I fixed it with 'touch' which is in the coreutils package. I downloaded coreutils from here. Then I added the folder C:\Program Files (x86)\GnuWin32\bin to the windows PATH and used this batch file:
#echo off
set TIME=0000
for %%f in (*.txt) do (
set FILENAME=%%~nf
set YEAR=!FILENAME:~0,4!
set MONTH=!FILENAME:~5,2!
set DAY=!FILENAME:~8,2!
set NEW_STAMP=!YEAR!!MONTH!!DAY!!TIME!
touch -t !NEW_STAMP! %%f
)
goto:EOF
:EOF
pause
VB scripting is completely alien to me but today landed in a situation to write a small one. I need Admin rights to run my .bat file. So I am trying to elevate to Admin rights if not have them. With the help of SO and Google I reached upto:
Function Length()
Set WshShell = WScript.CreateObject("WScript.Shell")
If WScript.Arguments.length = 0 Then
Set ObjShell = CreateObject("Shell.Application")
ObjShell.ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """" & " RunAsAdministrator", , "runas", 1
Else
Dim shell
set shell=createobject("wscript.shell")
shell.run "ExtractFiles.bat"
End If
End Function
Length
Here, this .vbs and ExtractFiles.bat are saved in same folder. I opened 2 command prompts. One in Admin mode and other normal. When running this script thorugh command prompt in Admin mode, I am getting success. But in normal mode, first I get a window to switch to Admin mode and I press Yes on it. Then I get below error:
Can anyone point me to correct code. I am getting error in line shell.run "ExtractFiles.bat". Please help!
As I have also mentioned the requirement, a different approach is also welcome. In this problem, I am not sure how I am able to run the bat file in admin mode and failing in normal mode.
Add the Admin VBS code into your bat file. Here is my routine for the job.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:Admin <Return> [Needed] [Success]
:: Check for Administrator privileges and request privileges if Needed 'true'.
:::: Usage: call :Admin xReturn true
:: Return success value, if user is Admin. Default `true` if Success not set.
setlocal
set "xVBUAC=%Temp%\AdminUAC.vbs"
set "xSuccess=true"
set "xAdmin=false"
if not "%~3"=="" set "xSuccess=%~3"
:: Check for Access
::net session >nul 2>&1
>nul 2>&1 "%SystemRoot%\system32\cacls.exe" "%SystemRoot%\system32\config\system"
if %ErrorLevel% EQU 0 set "xAdmin=%xSuccess%"
:: Execute UAC
if /i not "%xAdmin%"=="%xSuccess%" if not "%~2"=="" if /i "%~2"=="true" (
echo Set UAC = CreateObject^("Shell.Application"^) > "%xVBUAC%"
echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%xVBUAC%"
if exist "%xVBUAC%" (
"%xVBUAC%"
rem if %ErrorLevel% EQU 5 echo Access Denied. Launching UAC.
del "%xVBUAC%"
)
)
endlocal & if not "%~1"=="" set "%~1=%xAdmin%"
goto :eof
How to Use it
:: Example Admin check
#echo off
setlocal EnableExtensions
call :Admin xReturn true 1
if not "%xReturn%"=="1" goto End
:: Do my .bat stuff here.
goto End
:: TODO Place the admin function here.
:End
Depending on how you launch the VBScript the directory in which the scripts reside isn't necessarily the working directory. Try this:
Set fso = CreateObject("Scripting.FileSystemObject")
scriptDir = fso.GetParentFolderName(WScript.ScriptFullName)
shell.run "%COMSPEC% /c """ & fso.BuildPath(scriptDir, "ExtractFiles.bat") & """"
What you enter in the command prompt? Is it...
InstallACS.vbs ExtractFiles.bat
Your script works just fine on XP x64 (if that important) never mind how I'll run it - from the sell or from the console, and also work with and without argument.