I have the below VBScript (values and names changed)
Dim InstanceName
Set objShell = WScript.CreateObject("WScript.Shell")
Set objEnv = objShell.Environment("USER")
objEnv("PLUGIN") = "plugin"
objEnv("CONF") = "location"
Set ArgObj=Wscript.Arguments
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("path.txt", 1)
AbsolutePath = objTextFile.ReadLine
objTextFile.Close
directory = "C:\Program Files\"&AbsolutePath&"\bin"
executable = directory&"\app-"&InstanceName&".exe"
objShell.CurrentDirectory = directory
objShell.Run Chr(34) & executable & Chr(34), 1, false
Set objShell = Nothing
My program uses the environment variables PLUGIN and CONF. However, the first time the program is launched using the script, it cannot find the environment variables. The subsequent launches work fine as the environment variables are already set.
I can see them when I check in control panel even after the first launch but the executable doesn't seem to pick them up.
How can I make the variables be set correctly for the executable the first time the script is run?
Thanks!
The problem is that the values are not being stored as User environment variables. Reading through the documentation you want to make sure that you set the Environment property of the WScript.Shell object to the correct set of environment variables, as per the documentation the values are;
System
User
Volatile
Process
Would recommend changing the code to use;
Set objEnv = objShell.Environment("SYSTEM")
and go from there.
Related
I have this script saved in "test.vbs":
Set FSO = CreateObject("Scripting.FileSystemObject")
Set File = FSO.OpenTextFile(workFolder &"\test.txt", 2, True)
File.Write "testing"
File.Close
Set File = Nothing
Set FSO = Nothing
Set workFolder = Nothing
When I run the script I want to pass the value of the "workFolder" variable.
How can I do this? Can I do it? Something like "cscript test.vbs workFolder:'C:\temp\'" perhaps?
Bonus question: Is it neccessary to clean up the passed variable with "Set workFolder = Nothing" or does VBSCript do that automatically when it terminates? Maybe "Set File = Nothing" and "Set FSO = Nothing" is unneccessary also? Please let me know if you know the answer to both these questions.
You can use WScript.Arguments to access the arguments passed to your script.
Calling the script:
cscript.exe test.vbs "C:\temp\"
Inside your script:
Set File = FSO.OpenTextFile(WScript.Arguments(0) &"\test.txt", 2, True)
Don't forget to check if there actually has been an argument passed to your script. You can do so by checking the Count property:
if WScript.Arguments.Count = 0 then
WScript.Echo "Missing parameters"
end if
If your script is over after you close the file then there is no need to set the variables to Nothing. The resources will be cleaned up automatically when the cscript.exe process terminates. Setting a variable to Nothing usually is only necessary if you explicitly want to free resources during the execution of your script. In that case, you would set variables which contain a reference to a COM object to Nothing, which would release the COM object before your script terminates. This is just a short answer to your bonus question, you will find more information in these related questions:
Is there a need to set Objects to Nothing inside VBA Functions
When must I set a variable to “Nothing” in VB6?
Inside of VBS you can access parameters with
Wscript.Arguments(0)
Wscript.Arguments(1)
and so on. The number of parameter:
Wscript.Arguments.Count
Each argument passed via command line can be accessed with: Wscript.Arguments.Item(0) Where the zero is the argument number: ie, 0, 1, 2, 3 etc.
So in your code you could have:
strFolder = Wscript.Arguments.Item(0)
Set FSO = CreateObject("Scripting.FileSystemObject")
Set File = FSO.OpenTextFile(strFolder, 2, True)
File.Write "testing"
File.Close
Set File = Nothing
Set FSO = Nothing
Set workFolder = Nothing
Using wscript.arguments.count, you can error trap in case someone doesn't enter the proper value, etc.
MS Technet examples
You can also use named arguments which are optional and can be given in any order.
Set namedArguments = WScript.Arguments.Named
Here's a little helper function:
Function GetNamedArgument(ByVal argumentName, ByVal defaultValue)
If WScript.Arguments.Named.Exists(argumentName) Then
GetNamedArgument = WScript.Arguments.Named.Item(argumentName)
Else
GetNamedArgument = defaultValue
End If
End Function
Example VBS:
'[test.vbs]
testArg = GetNamedArgument("testArg", "-unknown-")
wscript.Echo now &": "& testArg
Example Usage:
test.vbs /testArg:123
To answer your bonus question, the general answer is no, you don't need to set variables to "Nothing" in short .VBS scripts like yours, that get called by Wscript or Cscript.
The reason you might do this in the middle of a longer script is to release memory back to the operating system that VB would otherwise have been holding. These days when 8GB of RAM is typical and 16GB+ relatively common, this is unlikely to produce any measurable impact, even on a huge script that has several megabytes in a single variable. At this point it's kind of a hold-over from the days where you might have been working in 1MB or 2MB of RAM.
You're correct, the moment your .VBS script completes, all of your variables get destroyed and the memory is reclaimed anyway. Setting variables to "Nothing" simply speeds up that process, and allows you to do it in the middle of a script.
I'm coding a new VBS script, which should create a TXT file in the Documents directory. While with other inputs I used %USERNAME% for the User Name of the PC, the command "CreateTextFile" seems to want the real directory, without including any variables like %USERNAME%.
I'm kinda of new to this so I can't figure it out.
That's what I tried:
Dim objFS, objFile
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.CreateTextFile("C:\Users\%USERNAME%\Documents\Demo.txt", true)
objFile.WriteLine("some sample text")
It should understand %USERNAME% as the UserName of the PC, but doesn't.
What I get as result is the program saying he can't find the directory C:\Users\%USERNAME%\Documents.
To get the desktop one uses
SpecialFolders Property
Returns a SpecialFolders object (a collection of special folders).
object.SpecialFolders(objWshSpecialFolders)
Arguments
object WshShell object.
objWshSpecialFolders The name of the special folder. (eg Desktop)
Environment strings are not expanded. You can pass an entire string containing environmental variables. EG "%userprofile%\Desktop". This code lists all variables available https://pastebin.com/rrEyVxFd.
ExpandEnvironmentStrings Method
Returns an environment variable's expanded value.
object.ExpandEnvironmentStrings(strString)
Arguments
object WshShell object.
strString String value indicating the name of the environment variable
you want to expand.
There are plenty longer drawn-out, which are appropriate but these are a couple examples - much easier:
Option Explicit
Msgbox CreateObject("WScript.Network").UserName
' or into a variable
Dim oShell : set oShell = CreateObject("WScript.Network")
Dim UserName : UserName = oShell.UserName
Msgbox UserName
Set oShell = Nothing
I am trying to run a VBScript which opens a program with elevated privileges and also pass it parameters.
Set oShell = CreateObject("Shell.Application")
Dim path = "app.exe"
If WScript.Arguments.Count = 1 Then
path = path & WScript.Arguments(0)
End If
oShell.ShellExecute path, , , "runas", 1
I get an error in the 2nd line. I tried using As String but that also didn't work.
Any ideas?
You are not allowed to declare a variable and set a value at the same time. Try this syntax instead.
Dim path
path = "app.exe"
or alternatively:
Dim path : path = "app.exe"
Where is the object WScript coming from? I don't see it initialized.
A great 'feature' to turn on is Option Explicit. When activated you must explicitly declare all variables by using the Dim or ReDim statements. If you try to use an undeclared variable name, an error occurs at compile time. This makes it easier to spot problems.
I've created a VBScript to run a macro from excel without opening the file.
Set objExcel = CreateObject("Excel.Application")
objExcel.Application.Run "'C:\Users\MyUser\Desktop\RM.xlsm'!Module4.Email"
objExcel.DisplayAlerts = False
objExcel.Application.Quit
Set objExcel = Nothing
I want to use this VBScript & XLSM file on different computers, so how can i change this script to work without editing the path every time?
(Maybe a code to run from current folder or a code to run from any user desktop)
If the file will always be on the desktop of every user then you can use environment variables to determine the location.
Set wshShell = CreateObject( "WScript.Shell" )
userName = wshShell.ExpandEnvironmentStrings( "%UserName%" )
path = "'C:\Users\" + userName + "\Desktop\RM.xlsm'!Module4.Email"
Set objExcel = CreateObject("Excel.Application")
objExcel.Application.Run path
objExcel.DisplayAlerts = False
objExcel.Application.Quit
Set objExcel = Nothing
(Untested code)
If the file is not on each user's desktop then you'll need to store it in a common location on the network and have each user access it from there, e.g. in .
\\YourFileSever\SharedFiles\RM.xlsm
In practical terms the latter is preferable as it means the workbook is in only one place and when it comes to releasing a new version you only have to update one copy
I am trying to run a vb script using task scheduler.
I am using the .GetAbsolutePathName(".") to get the full path of the script.
When I run the script manually, it was able to get the correct path. But when run as scheduled task, it outputs "C:\Windows\System32\ as the path.
I am using the path name to get the full path of an Excel file that I would like to run. The excel file is saved within the same path as the script.
Below is my code:
Set fso = CreateObject("Scripting.FileSystemObject")
scurDir = fso.GetAbsolutePathName(".")
set fso = nothing
Set myxlApplication = CreateObject("Excel.Application")
wscript.echo scurDir & "\OOO Automation Tool.xlsm"
Set myWorkBook = myxlApplication.Workbooks.Open( scurDir & "\OOO Automation Tool.xlsm" )
myxlApplication.Visible = False
myxlApplication.Wait(Now + TimeValue("0:00:10"))
'Run routine
myWorkBook.Application.Run "MOutofOffice.pDetectIdleTime"
'Close application
myxlApplication.Quit
'Release objects
set myxlApplication = nothing
set myWorkBook = nothing
Can you help me get the correct path?
You can try with
With WScript.CreateObject("Scripting.FileSystemObject")
WScript.Echo .GetFile(WScript.ScriptFullName).ParentFolder.Path
End With
You need the path where the script is stored, not the current active directory, what you retrieve with the "." reference.