Example code:
Dim a As String
a = 1234,5678,9123
I want to add literal double quotes to the variable a
Expected Output:
a = "1234,5678,9123"
How do I format the string so when I print it, it has double quotes around it?
If you want to include " in a string, supply "" where you want the quote to appear. So your example should read...
a = """1234,5678,9123"""
The current answers are correct and valid but sometimes the following can improve readability:
a = Chr$(34) & "1234,5678,9123" & Chr$(34)
To make Chr$(34) more readable:
Dim quote as string
quote = Chr$(34)
a = quote & "1234,5678,9123" & quote
This makes it easier to get the correct number of " symbols everywhere and is readable.
a = """1234,5678,9123"""
or
a= """" & a & """"
You just use Chr$(34) to insert a double quotes.
Eg:
Dim i as String
i = Chr$(34) & "Hello World" & Chr$(34) 'Shows "Hello World"
No need to add any kind of complicated functions just use following example to insert double in text box or rich text box.
Dim dquot=""""
TextBox1.AppendText("Hello " &dquot &"How are you ?" ")
or
Dim dquot=""""
RichTextBox1.AppendText("Hello " &dquot &"How are you ?" ")
I used the Chr$(34) method, like this:
Sub RunPython()
Dim scriptName As String
Dim stAppName As String
scriptName = ActiveWorkbook.Path & "\aprPlotter.py"
stAppName = "python.exe " & Chr$(34) & scriptName & Chr$(34)
Debug.Print stAppName
Call Shell(stAppName, vbHide)
End Sub
I was using the same path for the python script as the Excel Workbook, to keep it easier for the users. I monkeyed with the quotes for 45 minutes before I found this thread. When the paths are sourced from active working locations (especially ones with spaces in Windows), I think this is a preferred method. Hopefully, this will help someone else.
Related
I thought I had this correct but I don't. I'm trying to have an executable called from user profile directory. The variable is not expanding properly. This is the code example:
userProfilePath = oShell.ExpandEnvironmentStrings("%UserProfile%")
exePath = userProfilePath + "\test1.exe"
Set WshShell = WScript.CreateObject(""WScript.Shell"")
WshShell.Run """ & exePath & """
When the VBScript runs, it doesn't properly show the path of ("C:\Users\John Doe\test1.exe"). What am I missing on how to use the variable and string correctly?
Your quoting is incorrect. WScript.Shell must be in a single pair of double quotes, and if you want to add double quotes before and after the value of a variable you need to use either Chr(34)
WshShell.Run Chr(34) & exePath & Chr(34)
or sequences of 4 double quotes:
WshShell.Run """" & exePath & """"
The reason for the 4 consecutive double quotes is that VBScript string literals must begin and end with a double quote, and nested double quotes inside a string literal must be escaped by doubling them (so they don't prematurely terminate the string). Your literal """ & exePath & """ defines the literal text " & exePath & ", not the value of the variable exePath between two double qoutes.
With that said, in your particular case you don't need the whole concatenation shebang, because the Run method can handle environment variables by itself. The following code should suffice for your needs:
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run """%USERPROFILE%\test1.exe"""
strTarget = "C:\My Name\K.jpg"
as you can see there is a space in the address which is stored in strTarget, Now I\m trying to pass it to an application, but it won't work because there is space in address :(
TargetApp.Run """C:\My App\here.exe"" " & strTarget ,,true
if I change strTarget into "C:\MyName\K.jpg" which does not have space it will work.
How to solve this problem?
You need to add double quotes around the image path the same way you did around the executable path:
TargetApp.Run """C:\My App\here.exe"" """ & strTarget & """" ,,true
I usually recommend using a quoting function for this, because it significantly increases the readability:
Function qq(str) : qq = Chr(34) & str & Chr(34) : End Function
app = "C:\My App\here.exe"
img = "C:\My Name\K.jpg"
TargetApp.Run qq(app) & " " & qq(img), 0, True
Please how to pass the 'inp" variable from this piece of vbs to my batch named job.bat? Indeed when doing echoing (echo %2) from job.bat, i notice that the inp is not passed properly. prompt command views inp and not the value retrieved from vbs. Thanks
For Each listElement In xmlDoc.selectNodes("document/Lists/list")
msgbox "toto"
inp=listElement.selectSingleNode("entry").text
out= listElement.selectSingleNode("output").text
jeton= listElement.selectSingleNode("token").text
dim shell
set shell=createobject("wscript.shell")
shell.run "job.bat ""a file"" **inp** "
set shell=nothing
Next
I think what you're looking for is this.
shell.run "job.bat ""argfile.ext"" " & inp
However, as Ansgar Wiechers points out, this is a potentially severe security hole, as a treacherously crafted XML file could run arbitrary commands. To encapsulate your batch file arguments and prevent unintended consequences, consider switching to the Shell.Application object's ShellExecute method.
For Each listElement In xmlDoc.selectNodes("document/Lists/list")
msgbox "toto"
inp = listElement.selectSingleNode("entry").text
out = listElement.selectSingleNode("output").text
jeton = listElement.selectSingleNode("token").text
set shell=CreateObject("Shell.Application")
shell.ShellExecute "job.bat", """a file"" " & inp, "path\to\batfile\", "runas", 1
set shell=nothing
Next
Unlike several other languages VBScript doesn't expand variables inside strings. Because of that, inp in the string
"job.bat ""a file"" inp "
is just the literal string "inp", not the value of the variable inp. To produce a string with the value of a variable, you have to concatenate base string and variable like #rojo suggested:
shell.run "job.bat ""a file"" " & inp
I would, however, not recommend doing this without some safety precautions. For one thing you should always put double quotes around your arguments, in case they contain spaces. I normally use a quoting function for this to prevent the instruction from becoming riddled with quad-quotes:
Function qq(str) : qq = Chr(34) & str & Chr(34) : End Function
'...
shell.run "job.bat " & qq("a file") & " " & qq(inp)
You should also always apply sanitizing to all user input that is passed to a shell command. Otherwise your users might wreak havoc by entering something like foo & del /s /q C:\*.*. Common practice is to allow only known-good characters in the input string and replace everything else with a safe character (e.g. an underscore). You can achieve this with a regular expression:
Set re = New RegExp
re.Pattern = "[^ a-z0-9äöü.,_$%()-]"
re.Global = True
re.IgnoreCase = True
inp = re.Replace(inp, "_")
As I read and experienced for myself VBScript removes all double quotes from and argument. Does anyone know a way around this? How to pass double quotes into the script?
If that parameter requires quotes you could use a named parameter to identify it and then enclose the value with the double quotes
dim arg
if WScript.Arguments.Named.Exists("a") then
arg = WScript.Arguments.Named("a")
arg = chr(34) & arg & chr(34)
end if
and used thus:
cscript test.vbs /a:"a parameter"
but this doesn't help if you merely want to keep quotes if supplied. Single quotes are accepted though, so you could alternatively use single quotes (or another character/string) and do a Replace(arg, "'", chr(34)) to convert to double-quotes.
This script will get the command line as it is, with double quotes and everything to a variable called strLine, and display it:
Set objSWbemServices = GetObject("WinMgmts:Root\Cimv2")
Set colProcess = objSWbemServices.ExecQuery("Select * From Win32_Process")
For Each objProcess In colProcess
If InStr (objProcess.CommandLine, WScript.ScriptName) <> 0 Then
strLine = Mid(objProcess.CommandLine, InStr(objProcess.CommandLine , WScript.ScriptName) + Len(WScript.ScriptName) + 1)
End If
Next
WScript.Echo(strLine)
So running that with:
cscript scriptname.vbs "option" ""other option"" third option
would result in:
"option" ""other option"" third option
Rather than check for a command line to include WScript.ScriptName, you can get the current PID like in https://stackoverflow.com/a/13212628/1752986
Edit: Misunderstood the question so new answer here:
I don't think you can do that in any way. However, a work around might be to use the CommandLine property of the Win32_Process class, which should get you the complete commandline I think.
For example try this script:
Set wmi = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set processes = wmi.ExecQuery("SELECT * FROM Win32_Process")
For Each proc in processes
If InStr(proc.CommandLine, "double quotes") > 0 Then
wscript.echo proc.CommandLine
End IF
Next
With the parameters as: "some long commandline enclosed in double quotes here"
I am not sure if this works, but while passing parameter I guess you can do something like -
chr(34) + <your argument string> + chr(34)
The chr(34) stands for double quotes.
Unfortunately, I do not know any escape methods to pass double-quotes because its an argument delimiter. All I can suggest is to modify your script, or add the quotes from there.
Here's answer that draws upon/combines some of the others here and queries the process info based on the script's pid:
Function ArgumentsString()
Dim nPid : nPid = ThisProcessId()
For Each oPrc In GetObject("winmgmts:\\.\root\cimv2").ExecQuery(_
"Select * From Win32_Process Where ProcessId=" & nPid )
Exit For : Next
ArgumentsString = Mid( oPrc.CommandLine, _
InStr(oPrc.CommandLine, WScript.ScriptName) + _
Len(WScript.ScriptName) + 1 )
End Function
Function ThisProcessId()
ThisProcessId = 0
Dim sTFile, oPrc
With CreateObject("Scripting.FileSystemObject")
sTFile = .BuildPath(.GetSpecialFolder(2), "sleep.vbs")
With .OpenTextFile(sTFile, 2, True)
.Write "WScript.Sleep 1000"
End With
End With
With CreateObject("WScript.Shell").Exec("WScript " & sTFile)
For Each oPrc In GetObject("winmgmts:\\.\root\cimv2").ExecQuery(_
"Select * From Win32_Process Where ProcessId=" & .ProcessID)
Exit For : Next
ThisProcessId = oPrc.ParentProcessId
End With
End Function
I have this code:
a = "xyz"
g = "abcd " & a
After running it, the value of g is abcd xyz.
However, I want quotes around the value of a in g. After running the code, g should be abcd "xyz" instead.
How can I accomplish this?
You can escape by doubling the quotes
g="abcd """ & a & """"
or write an explicit chr() call
g="abcd " & chr(34) & a & chr(34)
You have to use double double quotes to escape the double quotes (lol):
g = "abcd """ & a & """"
I usually do this:
Const Q = """"
Dim a, g
a = "xyz"
g = "abcd " & Q & a & Q
If you need to wrap strings in quotes more often in your code and find the above approach noisy or unreadable, you can also wrap it in a function:
a = "xyz"
g = "abcd " & Q(a)
Function Q(s)
Q = """" & s & """"
End Function
The traditional way to specify quotes is to use Chr(34). This is error resistant and is not an abomination.
Chr(34) & "string" & Chr(34)
You can do like:
a="""xyz"""
g="abcd " & a
Or:
a=chr(34) & "xyz" & chr(34)
g="abcd " & a
I don't think I can improve on these answers as I've used them all, but my preference is declaring a constant and using that as it can be a real pain if you have a long string and try to accommodate with the correct number of quotes and make a mistake. ;)
I designed a simple approach using single quotes when forming the strings and then calling a function that replaces single quotes with double quotes.
Of course this approach works as long as you don't need to include actual single quotes inside your string.
Function Q(s)
Q = Replace(s,"'","""")
End Function
...
user="myself"
code ="70234"
level ="C"
r="{'User':'" & user & "','Code':'" & code & "','Level':'" & level & "'}"
r = Q(r)
response.write r
...
Hope this helps.
I found the answer to use double and triple quotation marks unsatisfactory. I used a nested DO...LOOP to write an ASP segment of code. There are repeated quotation marks within the string. When I ran the code:
thestring = "<asp:RectangleHotSpot Bottom=""" & bottom & """ HotSpotMode=""PostBack"" Left="""& left & """ PostBackValue=""" &xx & "." & yy & """ Right=""" & right & """ Top=""" & top & """/>"
the output was:
<`asp:RectangleHotSpot Bottom="28
'Changing the code to the explicit chr() call worked:
thestring = "<asp:RectangleHotSpot Bottom=""" & bottom & chr(34) & " HotSpotMode=""PostBack"" Left="""& left & chr(34) & " PostBackValue=""" &xx & "." & yy & chr(34) & " Right=""" & right & chr(34) & " Top=""" & top & chr(34) &"/>"
The output:
<asp:RectangleHotSpot Bottom="28" HotSpotMode="PostBack" Left="0" PostBackValue="0.0" Right="29" Top="0"/>