The VBScript Command Line Conundrum? - vbscript

I have an HTA where I can pass an IP (user input in an HTML text box as txtIP.value) to a vendor's management software - all that works. However, sometimes the device won't respond to a GUI request, but will respond to a ping request. I have a really nice ping command I use which passes what the ping command returns to another cmd which changes the prompt to show the times for each reply which allows me to watch multiple devices and coordinate lost or high pings. I cannot for the life of me get this command to pass to the command line. Any and all help is appreciated.
'********************************************************************
'Trying to run the following command:
'* ping -t 172.17.100.33|cmd /q /v /c "(pause&pause)>nul & for /l %a in () do (set /p "data=" && echo(!time! !data!)&ping -n 2 localhost>nul"
'********************************************************************
Sub TimedPing
'Set the HTML Field value - for testing purposes
txtIP.value = "172.17.100.33"
strIP1 = "ping -t "
strIP2 = txtIP.value
strIP3 = "|cmd /q /v /c "
strIP4 = """(pause&pause)>nul & "
strIP5 = "for /l %a in ()"
strIP6 = "do (set /p "
strIP7 = " ""data="" && echo(!time! !data!)&ping -n 2 localhost>nul"""
Set objShell = CreateObject ("WScript.Shell")
MsgBox("Step 1: " & strIP1 & strIP2 & strIP3 & strIP4 & strIP5 & strIP6 & strIP7)
txtCmd1.value = strIP1 & strIP2 & strIP3 & strIP4 & strIP5 & strIP6 & strIP7
objShell.Run strIP1 & strIP2 & strIP3 & strIP4 & strIP5 & strIP6 & strIP7
MsgBox("Step 2: " & "ping -t 172.17.100.33|cmd /q /v /c ""(pause&pause)>nul & for /l %a in () do (set /p ""data="" && echo(!time! !data!)&ping -n 2 localhost>nul""")
txtCmd2.value = "ping -t 172.17.100.33|cmd /q /v /c ""(pause&pause)>nul & for /l %a in () do (set /p ""data="" && echo(!time! !data!)&ping -n 2 localhost>nul"""
objShell.Run "ping -t 172.17.100.33|cmd /q /v /c ""(pause&pause)>nul & for /l %a in () do (set /p ""data="" && echo(!time! !data!)&ping -n 2 localhost>nul"""
MsgBox("Step 3: " & strIP1 & strIP2)
objShell.Run strIP1 & strIP2
MsgBox("Step 4: CMD")
objShell.Run "cmd"
End Sub
Step 1 compiles (HTA refreshes without an error message) and run without visible error. The DOS screen opens and closes instantly, without showing anything. I have tried to put a pause in there, but it doesn't work either.
Step 2 does the same thing.
Step 3 works fine.
Step 4 works fine.
I dumped the values I am sending the objShell.Run command to separate text boxes to compare how they match up to the original. After getting the results identical to the original command, I can copy the text from the HTA and run it in a command window without error for both step one and two, but I get nothing but a quickly closing command window from the Run command. Any ideas?

Maybe one day, someone will find an answer to this. Until then, the only way I could execute this command was to use a bat file (after hours of trying to not make one - I got this working with variable IP address and colors in a couple hours). Funny enough, like Geert Bellekens mentioned, I had to start the bat file with some other command (I used #echo off), and then I had to double up on the percent sign in the command itself. For completeness sake, below is the code to run call the bat file, pass some variables (IP Address and Color Theme) and then the bat file working. FYI, I used an If-Then-Else statement to check which Theme the user has selected and the second variable in the VBS script change according to the color they selected. I'll show the default.
VBScript in HTA triggered by HTML button click.
Sub TimedPing
Set objShell = CreateObject ("WScript.Shell")
objShell.Run "TimedPing.bat " & txtIP.value & " " & 07
End Sub
Bat file stored in the same directory as the HTA:
#echo off
title Timed Ping
color %2
#ping -t %1|cmd /q /v /c "(pause&pause)>nul & for /l %%a in () do (set /p "data=" && echo(!time! !data!)&ping -n 2 localhost>nul"

Related

Access is denied when use del /f in windows 10 64bit

I'm going to delete 1.mp3 but it gives me the error "Access is denied".
More info about file's perms:
attrib 1.mp3
A C:\Users\Alipour\Desktop\1\1.mp3
I also used attrib -s -h 1.mp3
but still it can not be deleted by
del /f/s/q 1.mp3 > NUL
or
del /f/s/q 1.mp3
or
del /f 1.mp3
There are several methods to remove such a file:
1. Process Explorer if the file is in use:
You can use ProcessExplorer from Windows Sysinternals to identifiy which program locks the file. Download and start ProcessExplorer and go to Find|Find Handle or DLL... Ctrl+F and enter the name of the locked file: 1.mp3.
ProcessExplorer will show you the process that is responsible for the lock because of accessing the file. If you've got the proccess kill that one and delete the file.
Example with MS Word accessing a file called LockedFile.docx:
2. Safe mode boot:
Another possibility is to boot into safe mode. In pre Windows 8 era this was done by pressing F8 before Windows boots.
In Windows 8 and higher you can press Shift+F8 before Windows boots or more easily you can hold Shift and click Restart in the login screen or even in Windows. If this was too short, look here how to get into safe mode.
Once you're in the safe mode you can try again deleting that file.
3. Remove file on Windows boot via PendingFileRenameOperations:
With PendingFileRenameOperations you can rename and even delete a file on Windows boot procedure when nothing else can access and block that file.
PendingFileRenameOperations will be entered in the Windows registry and consists of pairs of file paths.
You can do it manually as described below or again with a Windows Sysinternals program called MoveFile. Download that program and use it in a console window (Start -> Run or Windows-Key+R, type cmd and press ENTER).
Type movefile foo.exe "" to delete a file on reboot.
Manual method via registry:
The 1st path is the file to be renamed.
The 2nd path is the new file path.
If the 2nd path is empty (0x0000) the file get's removed.
Start -> Run or Windows-Key+R
Type in regedit, and press ENTER
Goto HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
Create a new Multi-String value: PendingFileRenameOperations
Enter \??\filepath as the data (e.g. \??\C:\Users\xyz\Desktop\foo.exe)
Press OK
Right-click on the key, click Modify Binary Data
At the end of the hex string, add 0000 (4 zeros which represent an empty string)
Press OK
Restart your computer
Lean and mean batch-file only alternatives for PendingFileRenameOperations:
~ Scripts will add an entry to right-click -- "SendTo" menu
~ Accepting a single parameter, either File or Folder
~ Confirmation prompt ([Cancel] to Clear previous entries)
~ Basic idiot proofing (don't process %Windir% for example)
Rename_On_Boot.bat
goto="Batch" /* Rename_On_Boot by AveYo v1
:RenOnBoot
set "input=%*" & call set "input=%%input:?=%%" &rem line below adds entry to right-click -- "SendTo" menu
if /i "_%~dp0"=="_%APPDATA%\Microsoft\Windows\SendTo\" (set .=) else copy /y "%~f0" "%APPDATA%\Microsoft\Windows\SendTo\" >nul 2>nul
if "_%1"=="_" color 4f & echo ERROR! No input provided & ping -n 6 localhost >nul & exit /b
for %%# in ("C:\" "C:\Boot" "C:\Recovery" "%WINDIR%" "%WINDIR%\system32" "%ProgramData%" "%ProgramFiles%" "%USERPROFILE%") do (
if /i "_%input%"=="_%%~#" color 4f & echo ERROR! %%# is not safe to delete & ping -n 6 localhost >nul & exit /b
)
color 0B & echo Please wait, folders might take a while .. & call cscript /nologo /e:JScript "%~f0" RenOnBoot "%input%" & exit /b
:RenOnBoot_Run_As_Admin
color 4f & echo Asking permission to run as Admin.. & call cscript /nologo /e:JScript "%~f0" RunAsAdmin "%~f1???" & exit /b
:"Batch"
#echo off & setlocal disabledelayedexpansion & mode 96,4 & echo. & title %~nx0 by AveYo & if not exist "%~f1" goto :RenOnBoot
reg query HKEY_USERS\S-1-5-20\Environment /v temp 1>nul 2>nul && goto :RenOnBoot || goto :RenOnBoot_Run_As_Admin
:"JScript" */
function RenOnBoot(f){
var HKLM=0x80000002, k='SYSTEM\\CurrentControlSet\\Control\\Session Manager', v='PendingFileRenameOperations';
var reg=GetObject('winmgmts:{impersonationLevel=impersonate}!//./root/default:StdRegProv'), ws=WSH.CreateObject('WScript.Shell');
var confirmation=ws.Popup(" Rename on next boot? [OK]\n Clear previous entries? [Cancel]\n\n "+f,0,'Rename_On_Boot by AveYo',33);
if (confirmation == 2) { reg.DeleteValue(HKLM, k, v); WSH.quit(); } // Clear existing entries on Cancel press and quit script
var mtd=reg.Methods_('GetMultiStringValue').InParameters.SpawnInstance_(); mtd.hDefKey=HKLM; mtd.sSubKeyName=k; mtd.sValueName=v;
var query=reg.ExecMethod_('GetMultiStringValue', mtd), regvalue=(!query.ReturnValue) ? query.SValue.toArray():[,], entries=[];
var fso=new ActiveXObject('Scripting.FileSystemObject'), fn=fso.GetAbsolutePathName(f);
entries.push('\\??\\'+fn,'\\??\\'+fn+'.ren');
reg.CreateKey(HKLM, k); reg.SetMultiStringValue(HKLM, k, v, entries.concat(regvalue));
}
if (WSH.Arguments.length>=2 && WSH.Arguments(0)=='RenOnBoot') RenOnBoot(WSH.Arguments(1));
function RunAsAdmin(self, arguments) { WSH.CreateObject('Shell.Application').ShellExecute(self, arguments, '', 'runas', 1) }
if (WSH.Arguments.length>=1 && WSH.Arguments(0)=='RunAsAdmin') RunAsAdmin(WSH.ScriptFullName, WSH.Arguments(1));
//
Delete_On_Boot.bat
goto="Batch" /* Delete_On_Boot by AveYo v1
:DelOnBoot
set "input=%*" & call set "input=%%input:?=%%" &rem line below adds entry to right-click -- "SendTo" menu
if /i "_%~dp0"=="_%APPDATA%\Microsoft\Windows\SendTo\" (set .=) else copy /y "%~f0" "%APPDATA%\Microsoft\Windows\SendTo\" >nul 2>nul
if "_%1"=="_" color 4f & echo ERROR! No input provided & ping -n 6 localhost >nul & exit /b
for %%# in ("C:\" "C:\Boot" "C:\Recovery" "%WINDIR%" "%WINDIR%\system32" "%ProgramData%" "%ProgramFiles%" "%USERPROFILE%") do (
if /i "_%input%"=="_%%~#" color 4f & echo ERROR! %%# is not safe to delete & ping -n 6 localhost >nul & exit /b
)
color 0B & echo Please wait, folders might take a while .. & call cscript /nologo /e:JScript "%~f0" DelOnBoot "%input%" & exit /b
:DelOnBoot_Run_As_Admin
color 4f & echo Asking permission to run as Admin.. & call cscript /nologo /e:JScript "%~f0" RunAsAdmin "%~f1???" & exit /b
:"Batch"
#echo off & setlocal disabledelayedexpansion & mode 96,4 & echo. & title %~nx0 by AveYo & if not exist "%~f1" goto :DelOnBoot
reg query HKEY_USERS\S-1-5-20\Environment /v temp 1>nul 2>nul && goto :DelOnBoot || goto :DelOnBoot_Run_As_Admin
:"JScript" */
function DelOnBoot(f){
ListDir=function(src, _root,_list) {
_root=_root || src, _list=_list || [];
var root=fso.GetFolder(src), files=new Enumerator(root.Files), dirs=new Enumerator(root.SubFolders);
while (!files.atEnd()) { _list.push(files.item()); files.moveNext(); }
while (!dirs.atEnd()) { _list=ListDir(dirs.item().path, _root,_list); _list.push(dirs.item()); dirs.moveNext(); }
return _list;
};
var HKLM=0x80000002, k='SYSTEM\\CurrentControlSet\\Control\\Session Manager', v='PendingFileRenameOperations';
var reg=GetObject('winmgmts:{impersonationLevel=impersonate}!//./root/default:StdRegProv'), ws=WSH.CreateObject('WScript.Shell');
var confirmation=ws.Popup(" Delete on next boot? [OK]\n Clear previous entries? [Cancel]\n\n "+f,0,'Delete_On_Boot by AveYo',33);
if (confirmation == 2) { reg.DeleteValue(HKLM, k, v); WSH.quit(); } // Clear existing entries on Cancel press and quit script
var mtd=reg.Methods_('GetMultiStringValue').InParameters.SpawnInstance_(); mtd.hDefKey=HKLM; mtd.sSubKeyName=k; mtd.sValueName=v;
var query=reg.ExecMethod_('GetMultiStringValue', mtd), regvalue=(!query.ReturnValue) ? query.SValue.toArray():[,], entries=[];
var fso=new ActiveXObject('Scripting.FileSystemObject'), fn=fso.GetAbsolutePathName(f);
if (fso.FolderExists(fn)) { var list=ListDir(fn); for (var i in list) entries.push('\\??\\'+list[i],''); }
entries.push('\\??\\'+fn,'');
reg.CreateKey(HKLM, k); reg.SetMultiStringValue(HKLM, k, v, entries.concat(regvalue));
}
if (WSH.Arguments.length>=2 && WSH.Arguments(0)=='DelOnBoot') DelOnBoot(WSH.Arguments(1));
function RunAsAdmin(self, arguments) { WSH.CreateObject('Shell.Application').ShellExecute(self, arguments, '', 'runas', 1) }
if (WSH.Arguments.length>=1 && WSH.Arguments(0)=='RunAsAdmin') RunAsAdmin(WSH.ScriptFullName, WSH.Arguments(1));
//
You can find out which program is locking a certain file with “Process Explorer → Find → Find handles or DLLs.”
For example, if the locker is explorer.exe, the Windows explorer, you can delete the file after killing Windows explorer in Task manager.
When del /f <FILE> producing an Access Denied error, you need to firstly take owner and grant access using takeown and icacls command line utilities, Please see an example: Delete a specific file on Windows.

How can I write a config file from batch script using vbscript variables in output redirect

In a bash script I write for creating a config file for dosbox, I can define the Current Resolution:
#!/bin/bash
#
if [ "$Resolucion" = "1152x864" ]; then
windowresolution=$(echo windowresolution=1024x768)
scaler=$(echo scaler=2xsai)
fi
Full script is available here.
In bash I can make
echo '
Line 1
Line 2
Line with Varible 1 fullResolution='"$Resolucion"'
Line with Varible 2 '"$windowresolution"'
Line with Varible 3 '"$output"'
Line with Varible 4 '"$scaler"'
Lines :
#echo off
mount c '"$Ruta_Actual/.$Titulo"'
c:
'"$Ejecutable"'
exit' | tee "$PWD/dosbox.conf" &> /dev/null
Now I need to do the same in a batch script, but I don't know how make batch + VBScript working.
I wrote the following for testing purposes:
#echo off
setlocal enabledelayedexpansion
color A
title BattleChess
set DIR="%CD%"
set PWD=%CD%\Juegos\Inukaze\BattleChess
set TITULO="BattleChess"
set SCRIPT="%TEMP%\%RANDOM%-%RANDOM%-%RANDOM%-%RANDOM%.vbs"
echo strComputer = "." >> %SCRIPT%
echo Set objWMIService = GetObject("winmgmts:" _ >> %SCRIPT%
echo & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") >> %SCRIPT%
echo Set colItems = objWMIService.ExecQuery("Select * from Win32_DesktopMonitor") >> %SCRIPT%
cscript /nologo %SCRIPT%
for /F %%* in (%SCRIPT%) do set RES=%%A
echo %RES% >> %CD%\RES.TXT
The RES.TXT just have a %A in it, but I can get the current resolution with this VBScript:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_DesktopMonitor")
For Each objItem in colItems
msgbox( "Current Resolution : " & objItem.ScreenWidth & "x" & objItem.ScreenHeight)
Next
However, I don't know how to make a file %CD%\dosbox.conf with multiples lines and using the "Current Resolution" from VBScript.
The lines of VBScript show me an error.
The Error :
""{impersonationLevel=impersonate}\\"" is not recognized as an internal or external command, program or batch file.
"strComputer" is not recognized as an internal or external command,
program or batch file.
The system can not find the path specified.
Well i dont know how to export the script .
But the answer :
for /F %%A in (
'wmic desktopmonitor get ScreenHeight^,ScreenWidth /value ^| find "="'
) do set "%%A"
set "RES=%ScreenWidth%x%ScreenHeight%"
echo %RES%
That solves that for me.
OK, this almost ready, I just need to know how I can make the following from bash script:
# Resolutions 4:3
if [ "$Resolucion" = "640x480" ]; then
windowresolution=$(echo windowresolution=512x384)
scaler=$(echo scaler=2xsai)
fi
if [ "$Resolucion" = "800x600" ]; then
windowresolution=$(echo windowresolution=640x480)
scaler=$(echo scaler=2xsai)
fi
if [ "$Resolucion" = "1024x768" ]; then
windowresolution=$(echo windowresolution=800x600)
scaler=$(echo scaler=2xsai)
fi
if [ "$Resolucion" = "1152x864" ]; then
windowresolution=$(echo windowresolution=1024x768)
scaler=$(echo scaler=2xsai)
fi
into batch script. I really don't know if the next are right:
REM "Resolutions 4:3"
if %RES% = 800x600
set windowresolution=640x480
set scale=2xsai
I need specify multiple resolutions and windowresolutions in the script
for better config file.
echo "lines" >> %CONFIG%
echo "%variable%" >> %CONFIG%
which I need use for each
"if %RES%=Numbers X Numbers"
windowresolution=%WINRES%
scale=something
to export to the config file the follow
Resolution=800x600
windowresolution=640x480
scale=2xsai
I can't help you with the vbs-parts, but:
for /F %%* in (%SCRIPT%) do set RES=%%A
seems quite wrong. first, you have to use then same for-variable : EITHER %%* OR %%A:
for /F %%A in (%SCRIPT%) do set RES=%%A
Second: with this syntax you read the file %script%, assingning every line to RES, resulting in %RES% being the last line of your file.
To use the result of the executed script, use:
for /F %%A in ('%SCRIPT%') do set RES=%%A
Note the single qoutes ('), which tell forto execute the script.
Note: you can also get your screen-parameters with batch:
for /f %%i in ('wmic desktopmonitor get screenheight^,screenwidth /value^|find "="') do set %%i
echo %Screenheight%x%ScreenWidht%
First and foremost: always post the actual error information (error message, error number, the actual line raising the error, …). Since we're not sitting in front of your computer screen you need to tell us what's on it.
With that said, you're probably getting an error, because the & operator has a special meaning in batch files. It separates two commands from each other, so you need to escape it if you want to print a literal &:
C:\>echo foo & echo bar
foo
bar
C:\>echo foo ^& echo bar
foo & echo bar
You're getting %A in the output file, because the syntax of your for loop is entirely wrong. The loop variable must be defined as %%A, not %%*, and the statement you want to run must be put between single quotes (or backticks, if you set the usebackq option). Also, you must run the script with cscript.exe, because the default interpreter (wscript.exe) doesn't write to StdOut, so you'd have no output to process. Change this:
for /F %%* in (%SCRIPT%) do set RES=%%A
into this:
for /F %%A in ('cscript //NoLogo %SCRIPT%') do set RES=%%A
to make the loop work correctly.
Just fixing the loop won't help much, though, because the VBScript you generate doesn't produce any output in the first place. You can't pass VBScript variables back to the batch script, only printed output (WScript.Echo or WScript.StdOut.WriteLine), or perhaps variables in the volatile environment.
However, as #Stephan already pointed out, you don't need the VBScript in the first place, because you can run WMI queries from batch files with the wmic command-line utility:
for /F %%A in (
'wmic desktopmonitor get ScreenHeight^,ScreenWidth /value ^| find "="'
) do set "%%A"
set "RES=%ScreenHeight%x%ScreenWidth%"
Note that you need to escape both , and | in the subexpression (escape character in batch is ^).
To create an output file with multiple lines you have to either echo one line at a time:
set "CONFIG=%CD%\dosbox.conf"
type nul >"%CONFIG%"
echo foo >>"%CONFIG%"
echo windowresolution=%RES% >>"%CONFIG%"
echo bar >>"%CONFIG%"
or escape line breaks like this:
set "CONFIG=%CD%\dosbox.conf"
echo foo ^
windowresolution=%RES% ^
bar >"%CONFIG%"
Writing several lines depending on the value of %RES% can be handled like this:
REM "Resolutions 4:3"
if "%RES%" = "800x600" (
echo Resolution=%RES% >>"%CONFIG%"
echo windowresolution=640x480 >>"%CONFIG%"
echo scale=2xsai >>"%CONFIG%"
)

How to End a VBScript Called from a Batch File and loop through the Batch File

Currently I have a batch file that calls a VBScript and executes the script and exits from that script into the command prompt window that I called the batch file from. I am wanting to return to the batch file from the VBScript and loop back into the beginning of the batch file and ask for the information from the user again and then go back into the script and repeat. I would also like to query the user as to whether they would like to quit or repeat after the VBscript has been run.
Here is my batch file:
#echo off
C:
cd C:\Users\Jared\Documents\Research\jared
Set "File=basic.dat"
Del "%File%" 2>NUL & If exist "%File%" (
Echo [+] File failed to delete: "%File%" >> "Report.txt"
)
Set /P datafile=Please enter data file to be analyzed:
Set /P filename=Please enter name for canvas file:
mklink basic.dat %datafile%
cscript Root_VBS_Script_1.vbs %filename%
And here is my VBScript (Disregard the SendKeys method, I understand how unreliable it is and will modify this later to not use it):
Set wshShell = CreateObject("Wscript.Shell")
Set args = WScript.Arguments
arg1 = args.Item(0)
Dim filename
filename = ""&arg1&""
WshShell.AppActivate "Command Prompt"
WshShell.SendKeys "root -b"
WshShell.SendKeys "~"
WshShell.AppActivate "ROOT session"
WshShell.SendKeys ".x analysis.C"
WshShell.SendKeys "~"
WshShell.SendKeys ".x double_gaus.C"
WshShell.SendKeys "~"
WshShell.AppActivate "ROOT session"
WshShell.SendKeys "c1->SaveAs{(}"""&filename&"""{)}"
WshShell.SendKeys "~"
WshShell.SendKeys ".q"
WshShell.SendKeys "~"
WScript.Quit
I have tried various ways of using the IF ERRORLEVEL command and keeping in mind that it must be in descending order when checked, but nothing is working.
#echo off
C:
cd C:\Users\Jared\Documents\Research\jared
Set "File=basic.dat"
:loop
Del "%File%" 2>NUL & If exist "%File%" (
Echo [+] File failed to delete: "%File%" >> "Report.txt"
)
set "datafile="
Set /P datafile=Please enter data file to be analyzed:
if not defined datafile echo all done - exiting&goto :eof
set "filename="
Set /P filename=Please enter name for canvas file:
if not defined filename echo all done - exiting&goto :eof
mklink basic.dat %datafile%
cscript Root_VBS_Script_1.vbs %filename%
goto loop
This should get you going.
Can't see what errorlevels have to do with anything. You appear not to be setting the vbscript exit code (need WScript.Quit yourerrorlevel else it will exit with errorlevel 0, I am told)
If you clear the values before they are input, then you can take advantage of the set /p behaviour that the value will remain unchanged if you simply reply with Enter
You can also use this characteristic to establish a default value, if that suits.
OR you could define a specific exit codeword like quit or exit. Using this method, you'd code a line
if /i "%var%"=="exit" echo Bye-bye&goto :eof
where the quotes protect against an empty or space-containing entry by the user into var, the & is an inline statement-separator and :eof is a special label predefined and understood by cmd to mean end of file (the colon is required)
This has a loop and a method to exit from the loop.
#echo off
:loop
C:
cd C:\Users\Jared\Documents\Research\jared
Set "File=basic.dat"
Del "%File%" 2>NUL & If exist "%File%" (
Echo [+] File failed to delete: "%File%" >> "Report.txt"
)
"set datafaile="
Set /P datafile=Please enter data file to be analyzed or press Enter to Quit:
if not defined datafile goto :EOF
Set /P filename=Please enter name for canvas file:
mklink basic.dat %datafile%
cscript Root_VBS_Script_1.vbs %filename%
goto :loop
As #brianadams suggested, there's no need for a batch script here. You can do the entire prompting and looping in VBScript and shell out for external commands like mklink.
Set sh = CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Function qq(str) : qq = Chr(34) & str & Chr(34) : End Function
sh.CurrentDirectory = "C:\Users\Jared\Documents\Research\jared"
basicfile = "basic.dat"
Do
If fso.FileExists(basicfile) Then
On Error Resume Next
fso.DeleteFile basicfile, True
If Err Then fso.OpenTextFile("Report.txt", 8, True).WriteLine _
"[+] File failed to delete: " & qq(basicfile)
On Error Goto 0
End If
datafile = InputBox("Please enter data file to be analyzed:")
filename = InputBox("Please enter name for canvas file:")
sh.Run "cmd /c mklink " & qq(basicfile) & " " & qq(datafile)
sh.AppActivate "Command Prompt"
sh.SendKeys "root -b"
'...
Loop

Batch Command Line to Eject CD Tray?

I'm currently trying to move my CD's of backup to my Backup HDD.
To automate the task I'm trying to create a batch to copy the files with the label of the CD than eject the media.
The code looks like this so far:
#echo off
SET dest=F:\Backup\
d:
:: routine to retrieve volume label.
for /f "tokens=1-5*" %%1 in ('vol') do (
set vol=%%6 & goto done
)
:done
:: create destination folder
set dest=%dest%%vol%
mkdir "%dest%"
:: copy to destiny folder
xcopy "d:" "%dest%" /i /s /exclude:c:\excludes.txt
::eject CD
c:
I'm stuck at eject part. I'm trying to eject the CD because I want a clear line to draw my attention when the copy finished (I thought opening the tray to be a good one).
Any ideas how to do it using Batch? Or any other ways to "draw the attention" to the end of the copy event?
Thanks :)
if you have no installed media player or anti virus alarms check my other answer.
:sub echo(str) :end sub
echo off
'>nul 2>&1|| copy /Y %windir%\System32\doskey.exe '.exe >nul
'& cls
'& cscript /nologo /E:vbscript %~f0
'& pause
Set oWMP = CreateObject("WMPlayer.OCX.7" )
Set colCDROMs = oWMP.cdromCollection
if colCDROMs.Count >= 1 then
For i = 0 to colCDROMs.Count - 1
colCDROMs.Item(i).Eject
Next ' cdrom
End If
This is a batch/vbscript hybrid (you need to save it as a batch) .I don't think is possible to do this with simple batch.On windows 8/8.1 might require download of windows media player (the most right column).Some anti-virus programs could warn you about this script.
I know this question is old, but I wanted to share this:
#echo off
echo Set oWMP = CreateObject("WMPlayer.OCX.7") >> %temp%\temp.vbs
echo Set colCDROMs = oWMP.cdromCollection >> %temp%\temp.vbs
echo For i = 0 to colCDROMs.Count-1 >> %temp%\temp.vbs
echo colCDROMs.Item(i).Eject >> %temp%\temp.vbs
echo next >> %temp%\temp.vbs
echo oWMP.close >> %temp%\temp.vbs
%temp%\temp.vbs
timeout /t 1
del %temp%\temp.vbs
just make sure you don't have a file called "temp.vbs" in your Temp folder. This can be executed directly through a cmd, you don't need a batch, but I don't know any command like "eject E:\". Remember that this will eject all CD trays in your system.
UPDATE:
A script that supports also ejection of a usb sticks - ejectjs.bat:
::to eject specific dive by letter
call ejectjs.bat G
::to eject all drives that can be ejected
call ejectjs.bat *
A much better way that does not require windows media player and is not recognized by anti-virus programs (yet) .Must be saves with .bat extension:
#cScript.EXE //noLogo "%~f0?.WSF" //job:info %~nx0 %*
#exit /b 0
<job id="info">
<script language="VBScript">
if WScript.Arguments.Count < 2 then
WScript.Echo "No drive letter passed"
WScript.Echo "Usage: "
WScript.Echo " " & WScript.Arguments.Item(0) & " {LETTER|*}"
WScript.Echo " * will eject all cd drives"
WScript.Quit 1
end if
driveletter = WScript.Arguments.Item(1):
driveletter = mid(driveletter,1,1):
Public Function ejectDrive (drvLtr)
Set objApp = CreateObject( "Shell.Application" ):
Set objF=objApp.NameSpace(&H11&):
'WScript.Echo(objF.Items().Count):
set MyComp = objF.Items():
for each item in objF.Items() :
iName = objF.GetDetailsOf (item,0):
iType = objF.GetDetailsOf (item,1):
iLabels = split (iName , "(" ) :
iLabel = iLabels(1):
if Ucase(drvLtr & ":)") = iLabel and iType = "CD Drive" then
set verbs=item.Verbs():
set verb=verbs.Item(verbs.Count-4):
verb.DoIt():
item.InvokeVerb replace(verb,"&","") :
ejectDrive = 1:
exit function:
end if
next
ejectDrive = 2:
End Function
Public Function ejectAll ()
Set objApp = CreateObject( "Shell.Application" ):
Set objF=objApp.NameSpace(&H11&):
'WScript.Echo(objF.Items().Count):
set MyComp = objF.Items():
for each item in objF.Items() :
iType = objF.GetDetailsOf (item,1):
if iType = "CD Drive" then
set verbs=item.Verbs():
set verb=verbs.Item(verbs.Count-4):
verb.DoIt():
item.InvokeVerb replace(verb,"&","") :
end if
next
End Function
if driveletter = "*" then
call ejectAll
WScript.Quit 0
end if
result = ejectDrive (driveletter):
if result = 2 then
WScript.Echo "no cd drive found with letter " & driveletter & ":"
WScript.Quit 2
end if
</script>
</job>
Requiring administrator's rights is too abusing :)
I am using wizmo:
https://www.grc.com/WIZMO/WIZMO.HTM

How to set environment variables in vbs that can be read in calling batch script

I have a batch file that calls a vbscript file. I am trying to have the vbscript file change an environment variable that is later used in the batch file that calls the vbscript file.
Here are snippetes from the files.
Parent.bat
Set Value="Initial Value"
cscript Child.vbs
ECHO Value = %VALUE%
Child.vbs
Set wshShell = CreateObject( "WScript.Shell" )
Set wshSystemEnv = wshShell.Environment( "Process" )
wshSystemEnv("VALUE") = "New Value"
You can't. A process can pass environment variables to child processes, but not to its parent - and in this case the parent is cmd.exe, which is running your Parent.bat file.
There are of course other ways to communicate information back to the parent batch file - outputting to stdout or a file is an obvious way, e.g.
== Child.vbs ===
WScript.echo "New Value"
== Parent.cmd ===
for /f "tokens=*" %%i in ('cscript //nologo child.vbs') do set Value=%%i
echo %Value%
yes, you can.... however, you'll have to resetvars in your session. see the following link:
Is there a command to refresh environment variables from the command prompt in Windows?
'RESETVARS.vbs
Set oShell = WScript.CreateObject("WScript.Shell")
filename = oShell.ExpandEnvironmentStrings("%TEMP%\resetvars.bat")
Set objFileSystem = CreateObject("Scripting.fileSystemObject")
Set oFile = objFileSystem.CreateTextFile(filename, TRUE)
set oEnv=oShell.Environment("System")
for each sitem in oEnv
oFile.WriteLine("SET " & sitem)
next
path = oEnv("PATH")
set oEnv=oShell.Environment("User")
for each sitem in oEnv
oFile.WriteLine("SET " & sitem)
next
path = path & ";" & oEnv("PATH")
oFile.WriteLine("SET PATH=" & path)
oFile.Close
This is how I did it:
SET oShell = CREATEOBJECT("Wscript.Shell")
dim varSet
SET varSet = NOTHING
SET varSet = oShell.Environment("SYSTEM")
varSet("WinVer") = "6.0.2008"
Then in a separate VB script (resetvars.vbs) I called from CMD script:
cscript //nologo \\%APPSERVER%\apps\IE9.0\restartvars.vbs
call %TEMP%\resetvars.bat
I don't think you can do this. At least, you would need to mess with the environment block in the calling process, and there's no guarantee that it will respect this...
Ho about this:
#echo off
set vbsFile=%temp%\createguid.vbs
call :CreateVbs
call :GetGuid NewGuid
echo.%NewGuid%
del %vbsFile%>nul
GOTO:EOF
:CreateVbs
echo.set obj = CreateObject("Scriptlet.TypeLib")>%vbsFile%
echo.WScript.StdOut.WriteLine obj.GUID>>%vbsFile%
GOTO:EOF
:GetGuid
for /f "tokens=*" %%i in ('cscript //nologo %vbsFile%') do set %1=%%i
GOTO:EOF
It is not pure batch script but works ok.
#echo off&color 4a&title %~n0&AT>NUL
IF %ERRORLEVEL% EQU 0 (
goto 2
) ELSE (
echo.
)
if not "%minimized%"=="" goto 1
set minimized=true & start /min cmd /C "%~dpnx0"&cls&exit
:1
wmic process where name="cmd.exe" CALL setpriority "realtime">nul&echo set shell=CreateObject("Shell.Application") > %~n0.vbs&echo shell.ShellExecute "%~dpnx0",,"%CD%", "runas", 1 >> %~n0.vbs&echo set shell=nothing >> %~n0.vbs&start %~n0.vbs /realtime&timeout 1 /NOBREAK>nul& del /Q %~n0.vbs&cls&exit
:2
echo %~dpnx0 admin mode look up&wmic process where name="cmd.exe" CALL setpriority "realtime"&timeout 3 /NOBREAK>nul
:3
echo x=msgbox("end of line" ,48, "%~n0") > %~n0.vbs&start %~n0.vbs /realtime&timeout 1 /NOBREAK>nul& del /Q %~n0.vbs&cls&exit

Resources