VBS How to call cmd.exe using a string variable with spaces - vbscript

I need to call the following:
set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd /c copy /y C:\input\" & WScript.Arguments(0) & " C:\output", 0
where the input argument may be "File Name.txt". I have seen countless examples of people doing the same thing using double quotes for a hard coded file location, but nothing using an input argument or variable. What syntax is required so that the command line receives:
copy /y "C:\input\File Name.txt" C:\output
and not
copy /y C:\input\File Name.txt C:\output
for an arbitrary file name?

Embed the needed quotes (escaped via doubling) in the surrounding literals:
WshShell.Run "cmd /c copy /y ""C:\input\" & WScript.Arguments(0) & """ C:\output", 0
background, further reading

Related

VBScript Command window - passing a command syntax

I'm trying to get a command to run in a cmd vindow via VBS. Just like this answer:
How to keep the VBScript command window open during execution
The command I'm trying to issue is this, as written it works in a .cmd file.
"\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\dtexec" /x86 /f "\\path\folder\folder with space\Import.dtsx"
I've been unable to get it to work in the syntax from the above answer:
objShell.run "%comspec% /c ""SomeProgram.exe -R & pause""", 1, True
Figure it's a double quote issue, but I can't find it.
(I have to use the whole path to dtexec to force usage of the 16bit version.)
Followup: =======================================================
This works:
oShell.Run "%comspec% /C ""\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\dtexec"" /x86 /f c:\temp\Import.dtsx & Pause", 1, True
This does not:
oShell.Run "%comspec% /C ""\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\dtexec"" /x86 /f ""c:\temp\temp two\Import.dtsx"" & Pause", 1, True
nor this:
oShell.Run "%comspec% /C ""\Program Files (x86)\Microsoft SQL Server\120\DTS\Binn\dtexec /x86 /f c:\temp\temp two\Import.dtsx"" & Pause", 1, True
It's that space in the filename argument that is hosing it.
You don't need pause, just tell CMD to keep the window open after the command finishes (/k) instead of closing it (/c):
objShell.Run "%comspec% /k program.exe -R", 1, True
Nested double quotes are only required when you have a path with spaces in it, e.g.:
objShell.Run "%comspec% /k ""C:\some folder\program.exe"" -R", 1, True
Edit: If arguments in your commandline are paths with spaces as well you need quotes around each path and another set of quotes around the entire statement:
objShell.Run "%comspec% /c """"C:\some folder\program.exe"" /p ""foo bar"" & pause""", 1, True

How do I avoid using absolute filepaths if I want files created on a user's desktop?

Right now my script uses an absolute filepath for the output folder on the desktop of a known user, but what if I want to allow the script to work on the desktop of a user whose username I do not know?
Example - here's the line I'm currently using. It works fine, but will obviously only work for "John". I need to make it work with any potential username - Tom, Dick, Harry, and so on and so forth.
' Creating log repository
objFSO.CreateFolder "C:\Users\John\Desktop\Output"
To avoid extended discussions in comments, here I place a self-explanatory example.
' helper function to quote strings
' useful in commands
Function Quot(str)
Quot = Chr(34) & str & Chr(34)
End Function
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("Wscript.Shell")
' get user's desktop directory and introduce a variable
currentDesktop = WshShell.SpecialFolders("Desktop") 'another way to do it
' introduce output directory variable <currentDesktop>\Output
outputDir = objFSO.BuildPath(currentDesktop, "Output")
' create <outputDir> if not exists
If Not objFSO.FolderExists(outputDir) Then
objFSO.CreateFolder outputDir
End If
' example usage in a command
' send command output to <outputDir>\network_config.txt
WshShell.Run "%COMSPEC% /c ipconfig /all >" & Quot(objFSO.BuildPath(outputDir, "network_config.txt"))
The easy way but fails if the desktop is not in the usual place for a user is, this may be coporate environments.
dir "%userprofile%\Desktop"
A better way is
for /f "skip=2 tokens=3" %A in ('Reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Desktop"') do set doc=%A
dir "%doc%" /a
(Remember %%A in a batch and %A if typing) I thought your question was about batch. Both methods are as easy as each other in VBScript.
set WshShell = WScript.CreateObject("WScript.Shell")
WScript.Echo "WinDir is " & WshShell.ExpandEnvironmentStrings("%userprofile%\Desktop\Output")
or
bKey = WshShell.RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Desktop")
or
strDesktop = WshShell.SpecialFolders("Desktop")

Echo Code into a File using VBScript

I am writing a VBScript which I want to use to echo the code of another VBScript into an output file.
However, I am unable to write some of the characters to the output file using this method.
If I use the command line method:
cmd.exe /c "#echo "hello"">output.vbs
This works and the string: "hello" is written to the output file.
However, when I do the same using a VBScript, it does not work.
Set objShell = CreateObject("Wscript.Shell")
objShell.Run "%comspec% /c ""#echo ""hello"">output.vbs"
So, is there a way I can echo it into another file retaining the double quotes?
Thanks.
Your quoting is wrong.
Change this:
objShell.Run "%comspec% /c ""#echo ""hello"">output.vbs"
into this:
objShell.Run "%comspec% /c #echo ""hello"">output.vbs"

Run batch CODE in a vbscript file

I am trying to make a vbscript file that can run batch code (Note: Not a batch file, but batch code)
The code, which works in a batch file:
IF EXIST "%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms" (
"%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"
) ELSE (start /b "" cmd /c del "%~f0"&exit /b)
I can make the vbscript code almost do what I want using:
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\myscript.bat" & Chr(34), 0
Set WshShell = Nothing
Now I would like to combine these two pieces of code into one file, so something along the lines of:
Set WshShell = CreateObject("WScript.Shell" )
WshShell.Exec "IF EXIST ""%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"" (""%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"") ELSE (start /b """" cmd /c del ""%~f0""&exit /b)"
Set WshShell = Nothing
However when I run this code I get The system cannot find the file specified. This is expected, since Exec (or Run, or Execute) runs a batch file and not batch code. So, is there a command similar to Exec that will run batch code and not a batch file?
Some extra info that I don't think is necessary to a solution (But included for the sake of completedness):
This code is placed in the startup folder
The code is created in C# in order to run a ClickOnce application on startup
The reason I want to use vbscript is that the batch file opens a cmd window for a second, which is undesirable. My understanding is that the line Set WshShell = Nothing will make the command run invisibly
I have tried including >nul at the end of each line of the batch file, since I read that it will stop the output. This did not work for me.
It is theoretically possible for this to work by using both a .bat and a .vbs file, but this would require putting the .bat file in some other directory and feels generally hackish
I am open to other solutions besides vbscript, provided they can check if the .appref file exists, run the file if so, and delete itself if the file doesn't exist. This may be trivial in vbscript but I've never used vbscript before.
EDIT:
According to #Jason's comment, I have modified the code as follows. Now it runs with no output and without running my app (AKA it doesn't do $#!+)
Set WshShell = CreateObject("WScript.Shell" )
WshShell.Run "cmd.exe /C ""IF EXIST ""%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"" (""%appdata%\Microsoft\Windows\Start Menu\Programs\MyManufacturer\MyClickOnceApp.appref-ms"") ELSE (start /b """" cmd /c del ""%~f0""&exit /b)", 0
Set WshShell = Nothing
The problem are the string in the path ! like this it work :
Dim objShell
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "cmd /c if exist test1.txt (echo ok & del test1.txt & pause) else (echo ko & pause)"
Try to work with 8.3 format. To resolve the composed-name and don't use string.
But if you're programming in VBS why do you want to use batch code in it ?
If you want to use both make a .BAT file. Or generate it from you're VBS and call it.
Here is a example:
you have a batch called regex.bat :
#echo off &setlocal
for /f "tokens=1* delims=:" %%i in (
'netsh wlan show interfaces ^| findstr /rxc:"[ ]* SSID [ ]*: ..*"'
) do for /f "tokens=*" %%k in ("%%j") do set "SSID=%%k"
echo %SSID% > regex.txt
the vbs looks like this:
Set WshShell = WScript.CreateObject( "WScript.Shell" )
WshShell.Run "regex.bat",0,True
This works for me fine. No cmd-Windows comes up. Hope this helpes you

How can I get a one liner xcopy command to run in vbscript?

I have an xcopy that cannot run correctly in a .bat (batch) file because of some Norwegian characters.
The line is:
xcopy /I /V /H /R /C /Y /K /O /X "G:\P - cad_files\Drawings\163997 Ø1000XØ90 T7-8-9.PDF" "F:\CAD\P - cad_files\Drawings\163997 Ø1000XØ90 T7-8-9.PDF"
If I run it from a batch file it fails as "0 files copied" because it translates the source file incorrectly due to the character set.
I've tried changing the charsets using chcp as well as using Notepad++ and encoding it with various charsets but it still fails due to a limitation I guess in batch processing in Windows.
So my question is, how can I get the line above to execute in a vbscript and record the xcopy output?
I tried:
set objShell = CreateObject("wscript.Shell")
strSource = "G:\P - Tdwos_cad_files\Drawings\163997 Ø1000XØ90 T7-8-9.PDF"
strDest = "F:\CAD\P - Tdwos_cad_files\Drawings\163997 Ø1000XØ90 T7-8-9.PDF"
command = "xcopy /I /V /H /R /C /Y /K /O /X " & chr(34) & strSource & chr(34) &chr(32) & chr(34) & strDest & chr(34) & " > F:\testvbs.log 2>&1"
objshell.run command
and then execute "cscript test.vbs"
But unfortunately this doesn't work despite the fact that if I change the objshell.run to wscript.echo it does show the proper output for the "command" variable...meaning it shows the right syntax.
So...any programmers know how I can properly run that original xcopy line in a vbscript? If you know how to run it in a batch file properly with the encoding, that's fine too...I just haven't figured that out yet.
Next script works with combined Norwegian-Czech folder and file names under under next conditions:
save the script UTF-16LE encoded with the 0xFFFE byte order mark, and
run the script as administrator!
Here's commented code snippet:
' save the script UTF-16LE encoded with the 0xFFFE byte order mark
' run the script as administrator!
' consider //U option: Use Unicode for redirected I/O from the console
' cscript //U 30767978.vbs
'
option explicit
dim objShell, strSource, strDest, command, cmd, xx
set objShell = CreateObject("wscript.Shell")
strSource = "D:\test\éíáýžřčšě\a Ø1000XØ90 b.txt"
strDest = "D:\test\ěščřžýáíé\a Ø1000XØ90 b.txt"
' chcp does not matter: `dir` as well as `xcopy` work for all
cmd = "%comspec% /U /C chcp 65000 & "
cmd = "%comspec% /U /C chcp 65001 & "
cmd = "%comspec% /U /C chcp 437 & "
cmd = "%comspec% /U /C chcp 852 & "
cmd = "%comspec% /U /C chcp 1250 & "
' chcp supposedly matters for redirected output
command = "dir " & """" & strSource & """ """ & strDest & """" & " & pause "
xx = objShell.Run( cmd & command, 1, true)
command = "xcopy /I /V /H /R /C /-Y /K /O /X " _
& """" & strSource & """ """ & strDest & """" & " & pause "
xx = objShell.Run( cmd & command, 1, true)
Wscript.Echo xx, cmd & command
While the accepted answer by JosefZ works well, I found that I could handle this much easier by simply taking my lines of xCopy and moving them from the .bat file to a Powershell .ps1 file and running it. Powershell doesn't balk at the character sets like Batch files do for some reason.
So I installed Powershell on the 2003 server and ran the script that way and it worked well.
I accepted JosefZ's answer since it answered the actual question, but posting this here in case others come across the same issue and want to utilize Powershell instead.

Resources