Use a variable in file path in .vbs - variables

Is it possible to usa variable in a path in .vbs. My basic situation is I have a vbs script that will often be run on a computer with one person logged in and run by an admin with a completely different user name (assume the file will be right clicked and "Run As").
The script edits an ini file that is located in the user directory for the person logged in. I know in batch I could simply insert the variable "C:\Users\%Logger%\AppData\Local\stat.ini" and the variable would be replaced. But I can't do this in .vbs. My script thus far. Or look at the bulk of it in an answer here.
Dim blnRes: blnRes = 0
Dim strOld, strNew, logger
strOld = "frogg"
strNew = "frog"
logger = Inputbox("What is your Domain ID exactly as entered when you log into this machine?","Domain ID")
On Error Resume Next
Call update("C:\Users\logger\AppData\Local\stat.ini", strOld, strNew)
blnRes = blnRes Or (Err.Number = 0): Err.Clear
Is there some way I can flag logger as a variable, or is there an easier way to do this?

I guess you meant a script variable. Try this:
logger = Inputbox("What is ID?","Domain ID")
Call update("C:\Users\"& logger &"\AppData\Local\stat.ini", strOld, strNew)

You can use command line arguments with vbs. See the following technet site:
http://technet.microsoft.com/en-us/library/ee156618.aspx
using the example vbs at the bottom, you can have Ping.vbs reply based on the computer name entered after the script name when its called (C:\scripts\Ping.vbs Hostname)
Here's more info on WScript.Aurguments
https://www.google.com/search?q=WScript.Arguments&sourceid=ie7&rls=com.microsoft:en-us:IE-Address&ie=&oe=
'Ping.vbs:
Dim arArguments, strArgument
Set arArguments = WScript.Arguments
WScript.Echo WScript.Arguments.Count
For Each strArgument in arArguments
If Ping(strArgument) Then
WScript.Echo strArgument & " is available."
Else
WScript.Echo strArgument & " is not available."
End If
Next
Function Ping( myHostName )
Dim colPingResults, objPingResult, strQuery
strQuery = "SELECT * FROM Win32_PingStatus WHERE Address = '" & myHostName & "'"
Set colPingResults = GetObject("winmgmts://./root/cimv2").ExecQuery( strQuery )
For Each objPingResult In colPingResults
If Not IsObject( objPingResult ) Then
Ping = False
ElseIf objPingResult.StatusCode = 0 Then
Ping = True
Else
Ping = False
End If
Next
Set colPingResults = Nothing
End Function

If I understand what you're after correctly, you're either going to need to do a string concatenation where you build a string like "string part 1" & logger & "string part 2" or use the replace function to replace %Logger% (e.g. Replace(templateString, "%Logger%", logger)) with your logger variable. There's not a direct equivalent to the %1 sort of format used in batch files.

This worked for me:
Dim fs, ws, Path
Set ws = CreateObject( "WScript.Shell" )
Path = ws.ExpandEnvironmentStrings( "%UserProfile%\testfile.txt" )
ws = Nothing
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.CreateTextFile (Path, True)
f.WriteLine("This is a test")
f.Close()
f = Nothing
Don't assume "C:\Users" will be valid on every system. There are times when you may want to use a different location for user profiles. I also looked at the %AppData% environment variable, but in my case that pointed to AppData\Roaming, and you want AppData\Local.

Related

how can a target the current user's documents folder?

So we have a system that requires users to log in and it has there own roaming profile. So in this string of code how can i target the current users document folder? (FYI excel 2010)
'WORKAROUND:
Dim PID As Double
Dim strRootPath As String
Const strExpExe = "explorer.exe"
Const strArg = " " '" /e,/root, "
'this is where i need to figure out how to target current user's documents
'// Change rootpath here
strRootPath = "C:\Data Files"
PID = Shell(strExpExe & strArg & strRootPath, 3)
the rest of the function does great... it opens file explorer i just cant figure the syntax for telling it to look for the current user.
Probably the best way would be with a function like this:
Function docsFolder() As String
docsFolder = CreateObject("WScript.Shell").SpecialFolders("MyDocuments")
End Function
There are other ways too but this one will work on any version of Windows and with user customizations.
For example, in my case, I have my documents folder on a mapped X: drive, so simply stuffing my username into a C:\ path would not work.
More Information:
Stack Overflow : Language independent way to get “My Documents” folder in VBA
Microsoft Technet : What is the path to My Documents?
MSDN : Wshell: SpecialFolders Property
I'm not sure how flexible you want this to be but you could try the following
strRootPath = "C:\Users\" + Environ("Username") + "\Documents"
Got it! thanks! for anyone that might care... The final string that made her run!
Function docsFolder() As String
docsFolder =
CreateObject("WScript.Shell").SpecialFolders("MyDocuments")
End Function
Private Sub test()
Dim PID As Double
Dim strRootPath As String
Const strExpExe = "explorer.exe"
Const strArg = " " '" /e,/root, "
'// Change rootpath here
strRootPath = "C:\Users\" + Environ("Username") + "\Documents"
PID = Shell(strExpExe & strArg & strRootPath, 3)
End Sub

Add new network location, not map network drive

Let's say I have 100 users and I need to add several network locations for each user. They cannot be network drives (e.g. Q:) as some users already have more than 26 drives mapped.
I was hoping to do this using either a batch file or a VB script. I've managed to get it working using a VB script by adding network shortcuts but this isn't the solution the users need.
I've been searching and can't find anything related specifically to Network Locations.
I'm open to trying other methods.
EDITED to properly answer the question; the original answer, that creates a shortcut in Network Locations, is kept at the end.
After some testing, a network location is a read-only folder located in the %AppData%\Microsoft\Windows\Network Shortcuts folder, with two files inside: desktop.ini with a precise content (see in code) and a target.lnk shortcut to the target.
Option Explicit
Function CreateNetworkLocation( networkLocationName, networkLocationTarget )
Const ssfNETHOOD = &H13&
Const fsATTRIBUTES_READONLY = 1
Const fsATTRIBUTES_HIDDEN = 2
Const fsATTRIBUTES_SYSTEM = 4
CreateNetworkLocation = False
' Instantiate needed components
Dim fso, shell, shellApplication
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set shell = WScript.CreateObject("WScript.Shell")
Set shellApplication = WScript.CreateObject("Shell.Application")
' Locate where NetworkLocations are stored
Dim nethoodFolderPath, networkLocationFolder, networkLocationFolderPath
nethoodFolderPath = shellApplication.Namespace( ssfNETHOOD ).Self.Path
' Create the folder for our NetworkLocation and set its attributes
networkLocationFolderPath = fso.BuildPath( nethoodFolderPath, networkLocationName )
If fso.FolderExists( networkLocationFolderPath ) Then
Exit Function
End If
Set networkLocationFolder = fso.CreateFolder( networkLocationFolderPath )
networkLocationFolder.Attributes = fsATTRIBUTES_READONLY
' Write the desktop.ini inside our NetworkLocation folder and change its attributes
Dim desktopINIFilePath
desktopINIFilePath = fso.BuildPath( networkLocationFolderPath, "desktop.ini" )
With fso.CreateTextFile(desktopINIFilePath)
.Write "[.ShellClassInfo]" & vbCrlf & _
"CLSID2={0AFACED1-E828-11D1-9187-B532F1E9575D}" & vbCrlf & _
"Flags=2" & vbCrlf
.Close
End With
With fso.GetFile( desktopINIFilePath )
.Attributes = fsATTRIBUTES_HIDDEN + fsATTRIBUTES_SYSTEM
End With
' Create the shortcut to the target of our NetworkLocation
Dim targetLink
targetLink = fso.BuildPath( networkLocationFolderPath, "target.lnk" )
With shell.CreateShortcut( targetLink )
.TargetPath = networkLocationTarget
.Save
End With
' Done
CreateNetworkLocation = True
End Function
CreateNetworkLocation "Tests", "\\192.168.1.2\c$"
Tested in Windows 7.
Original answer - Just in case someone finds it useful.
All you need to do is to create a shortcut in the folder:
%AppData%\Microsoft\Windows\Network Shortcuts
Just a VBScript sample (as indicated in the question, not sure if the tags points to another needs):
Option Explicit
Const ssfNETHOOD = &H13&
Dim fso, shell, shellApplication
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set shell = WScript.CreateObject("WSCript.Shell")
Set shellApplication = WScript.CreateObject("Shell.Application")
Dim networkLocationsFolder
networkLocationsFolder = shellApplication.Namespace( ssfNETHOOD ).Self.Path
With shell.CreateShortcut(fso.BuildPath( networkLocationsFolder, "Test PC.lnk" ))
.TargetPath = "\\192.168.1.10\c$"
.WindowStyle = 1
.IconLocation = "shell32.dll, 9"
.Description = "Access to Test computer drive"
.WorkingDirectory = "\\192.168.1.10\c$"
.Save
End With

Strange symbols stopping my batch file running in VB.net

I am trying to create and run a batch file from VB.net, then get the output and print it out. But when it runs it is appended by these symbols '´╗┐. Causing this error '´╗┐cd' is not recognized as an internal or external command, operable program or batch file. When I look at the batch file in notepad++ there is no symbol there! What is happening! Thanks James.
Code:
Dim path As String = Directory.GetCurrentDirectory()
Dim command As String = "cd " & path & " & " & argument
MsgBox(command)
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter(tempFile, False)
file.WriteLine("#ECHO OFF")
file.WriteLine(command)
file.Close()
Dim objProcess As New Process()
Dim SROutput As System.IO.StreamReader
With objProcess.StartInfo
.FileName = tempFile
.RedirectStandardOutput = True
.UseShellExecute = False
.Arguments = ""
End With
objProcess.Start()
SROutput = objProcess.StandardOutput
Do While SROutput.Peek <> -1
'MessageBox.Show(SROutput.ReadLine)
rtbOutput.Text = rtbOutput.Text & SROutput.ReadLine & vbNewLine
Loop
objProcess.Dispose()
'Process.Start(tempFile)
rtbOutput.Text = rtbOutput.Text & message & vbNewLine
That's a Byte Order Mark.
It means the OpenTextFileWriter() method is using a different encoding than you expect. You can fix the problem by using OpenTextFileWriter() overload that allows you pick an encoding like ASCII with no byte order mark or use the encoding with the byte order mark that matches what the DOS subsystem is expecting.
Solved, Im not entirely sure what was happening when it was writing the file, but I have changed it to this
Using writer As StreamWriter = New StreamWriter(tempFile)
writer.Write(command)
End Using
and its now running fine!. Thanks for any time spent on this and feel free to post an explination as to why this was happening.

Permission Denied accessing csv file with VBS

I'm trying to create a line in VBS that will create a file path with the file name as a variable, but I'm getting a Permission Denied error.
This is what I have so far:
filename = WScript.Arguments.unnamed(0) 'this value is transfered from a batch file.
Const ForReading = 1, ForWriting = 2, ForAppending = 8, CreateIfNeeded = true
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.Async = "False"
xmlDoc.Load ("C:\Users\c1921\Ayla_Data\XMLFile.xml")
Set colNodes = xmlDoc.SelectNodes _
("/properties/property/(name)")
For Each objNode In colNodes
strSource = "C:\Users\c1921\Ayla_Data\AylaDatapoints\" & filename & ".csv"
Dim fso, f
Set fso = WScript.CreateObject("Scripting.Filesystemobject")
Set f = fso.OpenTextFile(strSource, 2)
I've also added a msgbox(filename) line to see what value I get and it is the correct value.
I've also tried something like this to see if it would help and it doesn't work either:
Set f = fso.OpenTextFile("C:\Users\c1921\Ayla_Data\AylaDatapoints\AC000N000004593.csv", 2)
This should be easy I don't know where I'm going wrong. Any help finding the right direction would be greatly appreciated.
I've also tried something like this (among other variations) if it's relevant:
Set f = fso.OpenTextFile("C:\Users\c1921\Ayla_Data\AylaDatapoints\" & Chr(34) & filename & Chr(34) & " " & ".csv", 2) & Chr(34)
Edit:
Tried making the file in VBs with this code:
strSource = "C:\Users\c1921\Ayla_Data\AylaDatapoints\" & filename & ".csv"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLogFile = objFSO.CreateTextFile(strSource, _
ForWriting, True)
objLogFile.Writeline
I still get Permission Denied run time error. The file is created but this is the only thing written in it:
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.
If your .bat file re-directs the (StdOut) output of curltest.vbs into a .csv file then it makes no sense to create (or write to) the .csv in the .vbs. Instead you should WScript.Echo the info you want to appear in the .csv.
In addition, you need to get rid of the logo - either by starting the .vbs with //NoLogo or 'burning' the //NoLogo switch into the user's c/wscript by using the //S option.
Evidence:
copy con curltest.vbs
WScript.Echo "WScript.Echoed into whatever.csv"
^Z
cscript //NoLogo curltest.vbs >whatever.csv
type whatever.csv
WScript.Echoed into whatever.csv

where are the windows users names stored in xp...?

I am writing an application that searches for a particular file in the C:\Documents and Settings\user accounts\Application Data folder. Now i am trying to make this application generic. I can make this application search in a particular users application data folder. But what i am tryin to do is take the user name from a certain file or place where windows xp stores it. Then make it search for that user. Is there a particular way to do it.
Need ideas and suggestions.
User Names are Stored in Windows Registry or Use Can get FolderNames as C:\Documents and Settings contains Every Folder with a UserName
The problem here is that Microsoft has not provided an API method of doing this directly. Perhaps it was an oversight. That being said, any solution you find is going to be some kind of workaround and is going to present some kind of limitations.
Using the registry to get this information is not officially supported by Microsoft and thus, may not work going forward.
Iterating through user profile folders is unreliable because the folder is not always named after its user and because you can change its location.
And so on.
All of that being said, I use a combination of WMI and the registry to accomplish this. Here's what it looks like in VBScript, you should be able to adapt it to your needs.
' Create some arrays to hold the data.
arrUsers = Array()
arrSIDs = Array()
arrAppDataFolders = Array()
' Get a list of all the non-system users with their SID
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2"
Set colUsers = objWMIService.ExecQuery _
("Select * from Win32_UserAccount Where Status = 'OK'")
i = 0
For Each objUser in colUsers
ReDim Preserve arrUsers(i)
ReDim Preserve arrSIDs(i)
arrUsers(i) = objUser.Name
arrSIDs(i) = objUser.SID
i = i + 1
Next
Set colUsers = Nothing
Set objWMIService = Nothing
' Now go to the registry and get the Document folder location using the SID
Const HKEY_USERS = &H80000003
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\default:StdRegProv")
ReDim arrAppDataFolders(UBound(arrSIDs))
For i = 0 to UBound(arrSIDs)
strKeyPath = arrSIDs(i) & "\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
strValueName = "AppData" ' or "Local AppData"
intReturn = objRegistry.GetExpandedStringValue HKEY_USERS, strKeyPath, strValueName, strValue
If (intReturn = 0) And (Err.Number = 0) Then
arrAppDataFolders(i) = strValue
Else
arrAppDataFolders(i) = vbNull
End If
Next
Set objRegistry = Nothing
net user
from a command prompt will return a list of all users... probably more than what you're asking for. Your best bet is to do what you had already planned on doing with your Documents and Settings.