I'm using VBS to build a batch file for installing updates. To make sure it works the way I expected it to, I built this little test script, however the generated batch file errors out on launch with an unrecognized character, no matter what the first character is. VBS script:
option explicit
Dim objFSO, objFile, objWShell
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile("Test.bat", 2, True)
Set objWShell = CreateObject("WScript.Shell")
objFile.Write("#echo off" & vbCrLf & "echo " & chr(34) & "this is a test" & chr(34) & vbCrLf & "echo " & chr(34) & "This is only a test" & chr(34) & vbCrLf & "timeout /t 5")
Set objFile = Nothing
objWShell.Run "Test.bat"
wscript.quit
Running the script creates and instantly closes the window the bat runs in, but launching the generated bat from a command line yields that the first command being passed (in this case #echo off, but have tried with others) includes an extra character at the beginning, and only passes that character (which appears as a solid square, presumably one windows doesn't know) and the first character of the first command in the batch file. Thus I get something similar to '▬# is not a recognized internal or external command, operable program or batch file.'
Selecting "Show all characters" in npp when viewing both the batch file and the generating script shows no extra characters and all line breaks in both are crlf. Any ideas?
Changing the last parameter of CreateTextFile to False makes the file ASCII and it then runs properly. (You're currently saving it as Unicode which doesn't usually play nice with command prompt)
Related
I have spent several hours trying to get this to work. For some reason, my file paths register just fine in command prompt, but if I try to reference the file path using a FileSystemObject it doesn't work and tells me the file can't be found.
Dim g_shell
Set g_shell = CreateObject("WScript.Shell")
strCurDir = g_shell.CurrentDirectory
strValue = someName 'This is actually passed from a function argument
Set objFSO = CreateObject("Scripting.FileSystemObject")
configPath = strCurDir & "\maintLogs\" & strValue & "\MaintGuy_" & strValue & ".config"
Set objStream = objFSO.OpenTextFile(configPath) ' This throws a file not found error
g_shell.Run "cmd /c" & configPath & "& pause" 'This opens the file with no problem
'Let's Try something else:
Set objFSO = CreateObject("Scripting.FileSystemObject")
aPath = objFSO.BuildPath(g_shell.CurrentDirectory, "maintLogs")
bPath = objFSO.BuildPath(aPath, strValue)
cPath = objFSO.BuildPath(bPath, "MaintGuy_" & strValue & ".config")
Set objStream = objFSO.OpenTextFile(cPath) ' still doesn't work
g_shell.Run "cmd /c " & cPath & "& pause" ' This works (opens the file)
So my question is, why does this give me a file not found, when it works in command prompt and is an existing file. What am I missing?
In the example I am trying to read a text file, but I also could not get these file paths to work when I was trying to create a folder, move files into folders, and other file manipulation techniques. I accomplished it through launching the command prompt but could not get them to work using Scripting.FileSystemObject service.
Operating System: Windows 10
Scripting Language: VisualBasic Script
Application: SecureCRT
I figured it out. It turns out, because I was moving a file into the location I was trying to read from, it was trying to read the file BEFORE the file was there. I added a sleep function to the code, and it worked!
I have a .vbs file, which I have set to run at startup through regedit. Basically what the vbs does, is execute another program in the same directory (I will paste the vbs script below). Normally, the vbs script works great and everything is good. However, whenever the vbs script run at startup (i.e auto running right after the computer is booted), I always get a error message, telling me that Windows cannot find my file (i.e hello.exe), even though the exe file is right there.
I have tried setting a delay to the script, but that resulted in the same problem. I am extremely confused because everytime I run the vbs manually (like double click it), everything works fine, no problem.
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run chr(34) & "hello.exe" & Chr(34), 0
Set WshShell = Nothing
The expected result is that the vbs script will just run normally, like how it runs everytime i manually launch it. The error message is "Line 2: File cannot be found", or something along the lines of that.
As Hackoo is getting to, use the full path to the EXE you are running:
WshShell.Run chr(34) & "C:\My Hello App\hello.exe" & Chr(34), 0
This will run the exe file if its in the same folder as your script.
strPath = Left(WScript.ScriptFullName, InStrRev(WScript.ScriptFullName,"\"))
WshShell.Run chr(34) & strPath & "hello.exe" & Chr(34), 0
I'm attempting to call some code remotely using Window 10 WMIC.
rem command prompt, machine 1 (main computer)
WMIC /node:"MACHINE_2" process call create "cmd.exe /k "%USERPROFILE%\test.vbs" "
This call seems to go through correctly. It produces partial output from test.vbs (shown below), which means the file is called and executing.
' test.vbs, machine 2 (MACHINE_2, in above code)
Set objFSO=CreateObject("Scripting.FileSystemObject")
outFile="%USERPROFILE%\out.txt"
Set objFile = objFSO.CreateTextFile(outFile,True)
objFile.Write "test1" & vbCrLf
objFile.Close
MsgBox("hi")
' CreateObject("WScript.Shell").Run "cmd /c ""nircmd.exe sendkey 0xB3 press"" ", 0
' Set WshShell = Nothing
outFile="%USERPROFILE%\out.txt"
Set objFile = objFSO.CreateTextFile(outFile,True)
objFile.Write "test2" & vbCrLf
objFile.Close
Expected behaviour: The script should write "test1" to out.txt. Then it should open a MsgBox. And after the MsgBox is closed on Machine_2, it should override the contents of out.txt with "test2."
The two lines of commented code below MsgBox can be substituted for the MsgBox code, and also have the same behaviour.
When executing the vbs file locally, the expected behaviour happens. However, when using the WMIC call, "test1" is printed, and then execution seems to stop. The MsgBox is never shown, and "test2" never overrides the content of out.txt.
I'm quite lost as to why this happens, and the steps I might take to make it work. At this point I've exhausted my google-fu.
You CANNOT display a user interface on remote scripts.
You may not mess with the logged on user.
In batch file I have the command below:
WScript ABC.vbs
In ABC.vbs:
Set WshShell = WScript.CreateObject("WScript.Shell")
WScript.Echo "Hello"
When I run the batch file there is a pop-up message with the text "Hello". But what I want is showing the message "Hello" in the Command Prompt window like I do the right click on ABC.vbs and then select "Open with command prompt".
In addition to the two comments to use cscript.exe ABC.vbs as your command line, here is a function you can put in your .vbs script to ensure it always runs with the cscript engine, no matter how it's called.
Sub checkengine
pcengine = LCase(Mid(WScript.FullName, InstrRev(WScript.FullName,"\")+1))
' BEGIN CALLOUT A
If Not pcengine="cscript.exe" Then
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run "CSCRIPT.EXE """ & WScript.ScriptFullName & """"
WScript.Quit
End If
' END CALLOUT A
End Sub
From this site: Forcing VBScript Files to Run in CScript Mode
Put Call checkengine at the beginning of your vbscript. If it detects that cscript.exe is not in the command line, it relaunches the script with that engine.
I'm trying to run a run the following command line for each specific file type (as example for each .txt file) in the current directory:
"C:\Program Files (x86)\some program\someprogram.exe" "file.txt" "file.txt.mod" -someparameter
When I run this exact command from an open Windows command prompt (including all the quotation marks), it works.
But when I run it through this VB, it does nothing/closes right away.
What am I doing wrong? I have a feeling it has to do with the quotes, but my head can't sort it out.
Set objFSO = CreateObject("Scripting.FileSystemObject")
objStartFolder = left(WScript.ScriptFullName,(Len(WScript.ScriptFullName))-(len(WScript.ScriptName)))
Set objFolder = objFSO.GetFolder(objStartFolder)
Set colFiles = objFolder.Files
For Each objFile in colFiles
strFileName = objFile.Name
If objFSO.GetExtensionName(strFileName) = "txt" Then
RunCommand()
End If
Next
Sub RunCommand
Set oShell = WScript.CreateObject ("WScript.Shell")
oShell.run "cmd.exe /C ""C:\Program Files (x86)\some program\someprogram.exe"" """ & objFile.Path & """ """ & objFile.Path & ".mod"" -someparameter"
Set oShell = Nothing
End Sub
You should
Reduce risk of failures
by
using "Option Explicit"
avoiding clever "roll your own" hacks by using standard methods (.GetParentFolderName) instead
using type prefixes correctly (objStartFolder)
avoiding variables just used once (objFolder, colFiles)
not using globals to pass parameters into Subs/Functions (objFile)
avoiding (unnecessary) stress (.Run without wait, new WScript.Shell for each file, "cmd" instead of "%comspec%")
using cscript in a 'dos box' instead of double click/wscript
and
check your assumptions
by
diagnostic output (.Echo objFile.Name immediately before calling RunCommand, use a variable to store and .Echo the command send to .Run)
Check return values of functions that provide diagnostics (.Run)
sanity checks like:
(just to tame the formatter)
>> WScript.Echo goFS.GetExtensionName("A.TXT")
>>
TXT