vbs/batch folder name with spacing issue - windows

Im having an issue where i am trying to create shortcuts but the vbs script is cutting out when it reaches a space in the path.
i have had a look around but many of the ones i have seen deal with the string being in vbs not being passed from a batch file.
here is my code so you can get a better understanding
Batch File:
#echo off
set office7="C:\ProgramData\Microsoft\Windows\Start Menu\Strategix Programs\Office Programs"
mkdir %office7%
cscript "H:\Installation Batch Files\createLink.vbs" ""%office7%\Purchase Order Entry.lnk"" "\\192.168.0.7\Temp\stock\Porder10.exe" "T:\Stock"
pause
Vbs file:
Set oShell = CreateObject("WScript.Shell") Set args = WScript.Arguments
sShortcut = oShell.ExpandEnvironmentStrings("" & args.Item(0) & "") sTarget = args.Item(1) sStartIn = args.Item(2)
WScript.Echo "Shortcut: " & sShortcut WScript.Echo "Target: " & sTarget WScript.Echo "StartIn: " & sStartIn
Output:
Shortcut: C:\ProgramData\Microsoft\Windows\Start Menu\Strategix Programs\Office Programs\Purchase
Target: Order
StartIn: Entry.lnk

Batch part
#echo off
set "office7=C:\ProgramData\Microsoft\Windows\Start Menu\Strategix Programs\Office Programs"
mkdir "%office7%"
cscript "H:\Installation Batch Files\createLink.vbs" "%office7%\Purchase Order Entry.lnk" "\\192.168.0.7\Temp\stock\Porder10.exe" "T:\Stock"
pause
The "correct" way of dealing with quotes is not include them in the value. If later you need them, adding them is easy (look the mkdir command and the arguments), but removing them is not. Without a good reason, do not include them. So, the "correct" way is
set "var=value"
That will assign the value to the variable, take care of problematic characters (all the assignation is inside quotes) and keep possible spaces at the end of the line out of the variable value.
Now, to the vbs part
Dim oShell
Set oShell = CreateObject("WScript.Shell")
Dim args
Set args = WScript.Arguments
Dim sShortcut, sTarget, sStartIn
sShortcut = args.Item(0)
sTarget = args.Item(1)
sStartIn = args.Item(2)
WScript.Echo "Shortcut: " & sShortcut
WScript.Echo "Target: " & sTarget
WScript.Echo "StartIn: " & sStartIn
There is no need for ExpandEnvironmentStrings, this has been done when the batch line was parsed in cmd. %office7% is a reference to the value of the variable, not the name of the variable, and the parser replaces variable reads with variable values.
And for the shortcut creation
With oShell.CreateShortcut( sShortcut )
.TargetPath = sTarget
.WorkingDirectory = sStartIn
.Save
End With

Related

Cant move VBScript to another directory, it says "File not found"

Set objShell = CreateObject("Wscript.Shell")
strFile ="Lafarrel.vbs"
dim fso, fullPath
set fso = CreateObject("Scripting.FileSystemObject")
fullPath = fso.GetAbsolutePathName(strFile)
Wscript.Echo fullPath
Wscript.Sleep 1000
dim SourceLocation
dim DestinationLocation
dim FileName
SourceLocation = fullPath
DestinationLocation = """C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\"""
FileName = "Lafarrel.vbs"
fso.MoveFile SourceLocation & "" & FileName, DestinationLocation & ""
Error starts at line 14
Maybe because the last line is incorrect?
Explain what I want VBScript to do:
I want this VBScript to find itself and then change to a different directory
Use Option Explicit, for everyones' sanity.
Wscript.Sleep 1000 is unnecessary.
This line has problems: DestinationLocation = """C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\"""
This string-literal contains excessive double-quotes (VBScript uses double-double-quotes to escape individual double-quote chars, but strings containing only paths and filenames should not have internal delimiting quotes.
Also, %username% won't be expanded by FileSystemObject.MoveFile.
You will need to use WshShell.ExpandEnvironmentStrings first.
Also, C:\Users\%username%\AppData\Roaming\... is a poor choice of environment-variable'd-path as the Users directory might not be on C:\, and it might not even be named "Users".
Instead, you should use %APPDATA%.
obj prefixes are ugly and unnecessary.
Dim SourceLocation is redundant as it's an alias of fullPath. Ditto Dim FileName.
GetAbsolutePathName does not verify that the file actually exists: you'll get a runtime error if "Lafarrel.vbs" does not exist in the expected location when the script runs - so expect this situation and add an If guard.
So your code should look like this:
Option Explicit
Dim shell
Set shell = CreateObject( "WScript.Shell" ) ' aka WshShell
Dim fso
Set fso = CreateObject( "Scripting.FileSystemObject" )
Dim lafarrelVbsPath
lafarrelVbsPath = fso.GetAbsolutePathName( "Lafarrel.vbs" )
If fso.FileExists( lafarrelVbsPath ) Then
Dim destinationPath
destinationPath = "%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\"
destinationPath = shell.ExpandEnvironmentStrings( destinationPath )
Wscript.Echo "Moving """ & lafarrelVbsPath & """ to """ & destinationPath & """..."
' When `destinationPath` ends with a slash, then "Lafarrel.vbs" won't be renamed (phew).
fso.MoveFile lafarrelVbsPath, destinationPath
Else
Wscript.Echo "Error: File not found: """ & lafarrelVbsPath & """."
End If
WScript.ScriptFullName returns the script path and filename in full.
This sample demonstrates a couple of things including a simple way to isolate the script folder (not really needed for your use case though).
If you save this exact script into your local %temp% folder, and create a folder '%temp%\temp two' (space in there) you can just run it.
Also you MUST use ExpandEnvironmentStrings method to use env vars in a string
strFileName = WScript.Scriptname
strCurrDir = Replace(WScript.ScriptFullName, WScript.Scriptname, "")
Set wshShell = CreateObject("WScript.Shell")
strDestination = wshShell.ExpandEnvironmentStrings("%temp%\temp two\") ' note the space, but no need to double-up quotes. You MUST use ExpandEnvironmentStrings method to use env vars in a string
Wscript.Echo "I am '" & strFileName & "' and I am in '" & strCurrDir & "'"
WScript.Echo "My full path and name in one is: " & WScript.ScriptFullName
' so for moving the file, no need to separate the path and filename, as 'WScript.ScriptFullName' contains all of it (dest file must NOT exist)
' no need to double-up quotes for destination path, as this is not batch and will treat the whole string as path including spaces
Set fso = CreateObject("Scripting.FileSystemObject")
fso.MoveFile WScript.ScriptFullName, strDestination
WScript.Echo "I've now been moved to: " & strDestination

Use VBS to run a program with parameters

I'm a total vbs novice trying to perform the supposedly simple task of using a vbscript to run a single program (with parameters).
The path the to program is:
C:\Program Files (x86)\SpeedyFox\speedyfox.exe
and the parameter switch that must go with it is:
/Firefox:C:\Program Files\Firefox\Data\profile
If I wrap both sections in quotes (due to the spaces in their paths) it gives the following combined single command:
"C:\Program Files (x86)\SpeedyFox\speedyfox.exe" "/Firefox:C:\Program Files\Firefox\Data\profile"
If I then paste this into Start > Run it works exactly as I want.
I'm just trying to achieve the same thing from a vbs script instead of manually pasting into the Run box.
I do not want the command to run within a CMD console (as other questions on here have asked). All I am trying to do is to get "C:\Program Files (x86)\SpeedyFox\speedyfox.exe" "/Firefox:C:\Program Files\Firefox\Data\profile" to work with the shell.ShellExecute line of the script below.
Set objShell = Wscript.CreateObject ("Wscript.shell")
set shell=CreateObject("Shell.Application")
shell.ShellExecute ** WHAT DO I PUT HERE? **
set shell=nothing
but try as I might, I just keep getting WSH "Expected end of statement" error messages.
1.First : I recommend you Make it a habit to use this quote function
to make it easy for you to quote variables in these situations !
2. Second : You should use MsgBox or Wscript.echo in order to show
and debug your variables easily !
Wscript.echo DblQuote("Hello World !")
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
So, I downloaded this application (speedyfox.exe) and i tested it on my Windows 10 (32bits)
So, here is what i tested and it works like a charm on my side :
Option Explicit
Dim objShell,MyCommand,strProgramFiles,SpeedyFoxfile,Title
Title = "Execute SpeedyFox in Commandline"
Set objShell = CreateObject("Shell.Application")
strProgramFiles = GetProgramFilesPath()
SpeedyFoxfile = strProgramFiles & "\SpeedyFox\speedyfox.exe"
MsgBox "Without Double Quotes" & vbCrlf & SpeedyFoxfile,vbInformation,Title
MsgBox "With Double Quotes" & vbCrlf & DblQuote(SpeedyFoxfile),vbInformation,Title
MyCommand = "CD /D "& DblQuote(strProgramFiles &"\SpeedyFox\") &"&"& DblQuote(SpeedyFoxfile) & " " & DblQuote("/Firefox:default") & " " & DblQuote("/Chrome:Default")
MsgBox MyCommand,vbInformation,Title
Call Execute(MyCommand)
'-----------------------------------------
Function Execute(StrCmd)
Dim ws,MyCmd,Result
Set ws = CreateObject("wscript.Shell")
MyCmd = "CMD /K " & StrCmd & ""'
Result = ws.run(MyCmd,1,True)
Execute = Result
End Function
'-----------------------------------------
Function DblQuote(Str)
DblQuote = Chr(34) & Str & Chr(34)
End Function
'-----------------------------------------
Function GetProgramFilesPath()
Dim ws,OsType,strProgramFiles
Set ws = createObject("WScript.Shell")
OsType = ws.RegRead("HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE")
If OsType = "x86" then
strProgramFiles = ws.ExpandEnvironmentStrings("%PROGRAMFILES%")
elseif OsType = "AMD64" then
strProgramFiles = ws.ExpandEnvironmentStrings("%PROGRAMFILES(x86)%")
end if
GetProgramFilesPath = strProgramFiles
End Function
'-----------------------------------------
Sigh, reminds me of my vbscript days, now I use Ruby and it's just as simple as
´my_shell_command params´
However, back to your question: the shortest way to use ShellExecute is
CreateObject("Shell.Application").ShellExecute "application", "parameters", "dir", "verb", window
See this documentation for explanation of the parameters.
EDIT:
You have to pay attention at the quotes, they need to be passed to the shell also by using two quotes
eg CreateObject("Shell.Application").ShellExecute "C:\Program Files (x86)\SpeedyFox\speedyfox.exe", """/Waterfox:C:\Program Files\Waterfox\Data\profile"""

Unable to find file in VBScript

The VBE encoder section works (from prior experience but this time around it cannot find the required file. The file is in the %temp% folder so there are spaces in the path but I have used the "" as can be seen in the code. The MsgBox shows the correct file and I can confirm its existence but the code fails when fso.GetFile.
This is part of a larger script that is called with the target file (full path) as the argument. The target file is previously created by the calling script.
Main script (gets called with target file):
Set fso = CreateObject("Scripting.FileSystemObject")
Set wshShell = WScript.CreateObject("WScript.Shell")
textFile = WScript.Arguments(0)
GetExtension = fso.GetExtensionName(fso.GetFileName(textFile))
If LCase(GetExtension) = "vbs" Then
Set oFilesToEncode = WScript.Arguments
Set oEncoder = CreateObject("Scripting.Encoder")
For i = 0 To oFilesToEncode.Count - 1
file = """" & Trim(oFilesToEncode(i)) & """"
MsgBox file
If fso.FileExists(Left(file, Len(file) - 3) & "vbe") Then fso.DeleteFile(Left(file, Len(file) - 3) & "vbe")
Set oFile = fso.GetFile(file)
Set oStream = oFile.OpenAsTextStream(1)
sSourceFile = oStream.ReadAll
oStream.Close
sDest = oEncoder.EncodeScriptFile(".vbs", sSourceFile, 0, "")
sFileOut = Left(file, Len(file) - 3) & "vbe"
Set oEncFile = fso.CreateTextFile(sFileOut)
oEncFile.Write sDest
oEncFile.Close
Next
End If
WScript.Quit
Section of calling script:
Do While fso.FileExists(strTempVBS) = False
Loop
strKey = "HKEY_CLASSES_ROOT\Engineers-Toolbox\Multi-Tool\Installed\Path\"
value = wshShell.RegRead( strKey )
arg = " " & strTempVBS
running = "C:\Custom\Multi-Tool\Multi-Tool.exe " & """" & arg & """"
wshShell.Run running, True
I have tried using hard coding the path to the exe to get it going, 'value' contains the path to the main script.
Do not prematurely add quotes around paths. I'm always confused why people keep doing this, because it creates more problems than it solves. Add double quotes when they're actually required, but not before.
FileSystemObject methods can handle paths with spaces without the additional double quotes. In fact, they will interpret double quotes in a path string as part of the path and throw an error, because they can't find a file with a double quote in its name (which would be invalid anyway).
Your check for the existence of a file also doesn't work, because you don't account for the quotes you added to the path string:
file = """C:\some\folder\file.vbs"""
WScript.Echo file
WScript.Echo Left(file, Len(file) - 3) & "vbe"
The output of the above code snippet is
"C:\some\folder\file.vbs"
"C:\some\folder\file.vvbe
Change this:
file = """" & Trim(oFilesToEncode(i)) & """"
into this:
file = Trim(oFilesToEncode(i))
and the problem will disappear.
Ok, the solution is to (predictably) add the quotes in the calling script, that way the VBS to VBE encoder section can remain standard.
strTEMP = wshShell.ExpandEnvironmentStrings( "%UserProfile%" ) & "\AppData\Local\Multi-Tool\"
strTempVBS = strTEMP & "observe.vbs"
strKey = "HKEY_CLASSES_ROOT\Engineers-Toolbox\Multi-Tool\Installed\Path\"
value = wshShell.RegRead( strKey ) & " "
running = value & "" & chr(34) & strTempVBS & chr(34) & ""
wshShell.Run running ,True
Interesting was how the quotes are added. This made the called script find the required file even tho the full path contained spaces.

How to run a file on background using vbscript with launch options

I need to run a batch file in the background with launch option "1" (so it will %1 in the batch file).
here is my code:
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "C:\Program Files\Pineapplesoft\Lost computer\lostcomputeraudio.bat" & Chr(34), 0
Set WshShell = Nothing
Use a function to quote strings, and - optionally - a sub to map all elements of an array via a manipulator function to build command lines in a structured/well scaling way; use Join() to put the parts together (with automagical space separator):
Option Explicit
Function qq(s) : qq = """" & s & """" : End Function
Sub mapF(a, f)
Dim i
For i = LBound(a) To UBound(a)
a(i) = f(a(i))
Next
End Sub
Dim sFSpec : sFSpec = "C:\Program Files\Pineapplesoft\Lost computer\lostcomputeraudio.bat"
Dim aParms : aParms = Split("1#/pi:pa po#last parm", "#")
mapF aParms, GetRef("qq")
Dim sCmd : sCmd = Join(Array( _
qq(sFSpec) _
, Join(aParms) _
))
WScript.Echo qq(sCmd)
output:
cscript startaudio.vbs
""C:\Program Files\Pineapplesoft\Lost computer\lostcomputeraudio.bat" "1" "/pi:pap po" "last parm""
The script you ask is as follows:
Set objArgs = Wscript.Arguments
Set WshShell = WScript.CreateObject("WScript.Shell")
Return = WshShell.Run("C:\Program Files\Pineapplesoft\Lost computer\lostcomputeraudio.bat " & objArgs(0), 0, false)
Save it for example as myscript.vbs.
Note that the parameter 0 in the code means that the window will be hidden. The paremeter false in the code means that the excution of the .vbs will not wait for the .bat to finish.
What will happen is that, the .vbs will start the .bat and finish its execution, leaving the .bat being executed in the background, as you request.
Exeucute it like this:
c:\<whatever>\wscript myscript.vbs <the_parameter>

vbScript to execute all files in a dir

I'm trying to write a vbScript that will execute all files in a given directory (will be mostly batch files).
I've tried to modify a script that deletes all files but I'm not able to get it to work.
Here is what I have:
Option Explicit
'===========================================================================
' Scheduled Task - Visual Basic ActiveX Script
'===========================================================================
Call ExecuteDirectory("c:\users\public\documents\schedule\daily")
Function ExecuteDirectory(strPath2Folder)
Dim fso, f, fc, f1, strFiles, intFiles
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
strFiles = ""
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FolderExists(strPath2Folder)) Then
Set f = fso.GetFolder(strPath2Folder)
Set fc = f.Files
'-- Execute each file in Folder
For Each f1 in fc
strFiles = strFiles & f1.Name & vbCrLf
msgbox strPath2Folder & "\" & strFiles
WshShell.Run Chr(34) & strFiles & Chr(34), 1, true
Next
Set f1 = Nothing
Set fc = Nothing
Set f = Nothing
End If
Set fso = Nothing
End Function
The msgbox line displays the full path and file name that I want to execute, but the run line generates file not found error.
The variable strFiles continually builds up a list of files with line breaks in between. For example, if your folder contains the files "test1.bat" and "test2.bat", you will end up with this:
Iteration 1:
strFiles =
test1.bat
Iteration 1:
strFiles =
test1.bat
test2.bat
I don't think this is what you want to do. If you want to just run each script in order, you should just pass the single script name.
Try changing the inner loop to this:
For Each f1 in fc
Dim fileToRun
fileToRun = strPath2Folder & "\" & f1.Name
WshShell.Run Chr(34) & fileToRun & Chr(34), 1, true
Next
This is a very sloppy approach. If you are needing to execute an entire directory of batch files at one time, then you are not using them correctly. You should only need one batch file or one script an any time. I would begin looking at your whole system for a better approach to whatever it is that you are trying to accomplish.

Resources