VBScript Compilation Error, unable to resolve - command-line

So I'm trying to run a CMD prompt as a VBScript because I can't just drop this CMD Line.
Set cmdl = WScript.CreateObject("WScript.Shell")
cmdl.Run "cmd.exe ""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe""--app="https://app.powerbi.com/"""--kiosk""--fullscreen""--user-data-dir=c:/monitor1""
My dilemma is that every time I try and run this I get the following error:
Script: Script.vbs
Line: 2
Char: 90
Error: Expected end of statement
Code: 800A0401
Source: Microsoft VBScript compilation error
I've tried putting in quotes, taking out quotes, moving spaces, etc. and this dang thing is driving me crazy. Does anyone see where my mistake may lie?

Your command string is broken. In VBScript a string is defined by putting a character sequence between double quotes:
s = "some string"
If you want to use double quotes within a string you need to escape them by doubling them:
s = "some ""quoted"" string"
Also, you don't need cmd.exe for starting an executable via Run, but you do need whitespace between the parameters to the executable.
Change this:
cmdl.Run "cmd.exe ""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe""--app="https://app.powerbi.com/"""--kiosk""--fullscreen""--user-data-dir=c:/monitor1""
into this:
cmdl.Run """C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"" --app=https://app.powerbi.com/ --kiosk --fullscreen --user-data-dir=c:/monitor1"

The rule is: Use "" to insert " in VBScript literals.
The first violation in your
"cmd.exe ""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe""--app="https://app.powerbi.com/"""--kiosk""--fullscreen""--user-data-dir=c:/monitor1""
is
--app="https
This
"cmd.exe ""C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"" --app=""https://app.powerbi.com/"" --kiosk --fullscreen --user-data-dir=""c:/monitor1"""
may be what you want.
A better (scaling) approach is to use a quote function and an array for the parts/arguments:
Function qq(s)
qq = """" & s & """"
End Function
s = Join(Array( _
"cmd.exe" _
, qq("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe") _
, "--app=" & qq("https://app.powerbi.com/") _
, "--kiosk" _
, "--fullscreen" _
, "--user-data-dir=" & qq("c:/monitor1") _
), " ")
WScript.Echo s
output:
cscript a.vbs
cmd.exe "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --app="https://app.powerbi.com/" --kiosk
--fullscreen --user-data-dir="c:/monitor1"

This solution is based from #Ekkehard.Horner
So, i liked his method when using the join function with the array.
And, i tried it on my windows 7 (32 bits) and it works like a charme ;)
Function qq(s)
qq = chr(34) & s & chr(34)
End Function
s = Join(Array( _
"cmd /c start chrome" _
, "--app=" & qq("https://app.powerbi.com/") _
, "--kiosk" _
, "--fullscreen" _
, "--user-data-dir=" & qq("c:/monitor1") _
), " ")
WScript.Echo s
set ws = CreateObject("wscript.shell")
ws.run s,0,false

Related

Alternative to command line for short path names

There is a specific case where having "path with space" doesn't work and I need to get the Windows short path names (e.g. Program Files = Progra~1 and Program Files (x86) = Progra~2).
Here what I'm doing for now :
[status, PATHROOT] = dos([ ...
'for %A in ("' ...
myPathWithSpace ...
'") do #echo %~sA' ...
]);
Now, I tried using regexp and regexprep to format the file path, but it fails in some case to reproduce the dos short names. So how can I reproduce the dos command with MATLAB commands?
And here my ugly try with regexp and regexprep:
PATHROOT = regexprep(regexprep(regexp(myPathWithSpace,'\w:\\\w*\s\w*\\.*','match'),'\s', ''),'(\w:\\\w{6})\w*','$1~1');
Use this function:
function shortPath = getshortpath(longPath)
fs = actxserver('Scripting.FileSystemObject');
shortPath = fs.GetFolder(longPath).ShortPath;
fs.delete;

List files in one folder structure which aren't in another

Just got a new phone and have temporarily copied the old ones files onto my PC C:\OldPhone\
On my PC are all my photos, in various folders below D:\Photos.
I want some code to list all the .jpg files below C:\OldPhone\ which are not anywhere below D:\Photos\
Does that make sense? Just to stress, the folder structures are not identical and I don't mind where the file is, just as long as it's there. Filename comparison would do for starters, option to add size would be a bonus!
CMD, VBS or powershell would be good, but anything visual studio can cope with would be ok too.
try this:
for /r "D:\Photos" %%a in (*.jpg) do set "$%%~na=1"
for %%a in (C:\OldPhone\*.jpg) do if not defined $%%~na echo %%~a not in d:\photos
cmd has associative arrays, like awk. This doesn't work with file names containing =.
This should do the trick in PowerShell"
$ht=#{} # initialize empty hashtable
dir C:\OldPhone\*.jpg -r -file | Foreach {$ht["$($_.Name):$($_.Length)"] = $_.FullName}
dir D:\Photos\*.jpg -r file | Foreach {$ht.Remove("$($_.Name):$($_.Length)")}
$ht # dump remaining hashtable contents
This also takes into account the size of the file in case you have multiple files with the same name. Ideally, to really ensure their are the same, you would include the MD5 file hash instead of the file length as part of the hashtable $ht key for each file. Note that the -file parameter is new in PowerShell V3. You probably don't need it unless you have some folders with .jpg as part of their name.
For /R %%i In (newfiles\*.jpg) Do Call :Check "%%~fi"
GoTo :EOF
:Check
For /R %%i In (existingfiles\*.jpg) Do If /I "%%~nxi"=="%~nx1" GoTo :Found
Echo File %1 doesn't already exist!
GoTo :EOF
:Found
Echo File %1 already exists!
GoTo :EOF
Here's what I ended up with, based on Endoro's answer. I really should put the folder locations into variables, but it works now, so that's all I need! I should also put the setlocal ... endlocal lines into a subroutine too.
Now I look at it, OLDFOLDER is a daft name too. This is poor coding!
It copies any missing .jpg or .mp4 files into a folder for ease of copying.
echo off
set OLDFOLDER=C:\OldPhone
cls
echo Checking for files in %OLDFOLDER% which aren't in D:\Pictures
del /f /q "D:\Documents\MissingFiles\*"
setlocal
for /r "D:\Photos" %%a in (*.jpg) do set "$%%~nxa=1"
for /r "%OLDFOLDER%" %%a in (*.jpg) do if not defined $%%~nxa copy "%%~a" "D:\Documents\MissingFiles\"
endlocal
setlocal
for /r "D:\Photos" %%a in (*.mp4) do set "$%%~nxa=1"
for /r "%OLDFOLDER%" %%a in (*.mp4) do if not defined $%%~nxa copy "%%~a" "D:\Documents\MissingFiles\"
endlocal
if exist "D:\Documents\MissingFiles\*.*p*" (
echo Files missing from D:\Photos copied to D:\Documents\MissingFiles\
) else (
echo There are no files in %OLDFOLDER% which aren't in D:\Photos
)
pause
Use fciv (and grep):
fciv .\old -r | grep jpg > old.txt
fciv .\new -r | grep jpg > new.txt
To get
old.txt
6d5f1279d4deccbaeef5d074b13ed2f4 .\old\b\100_1608.jpg
d95e29e2c0172dea438b12c418b09fd3 .\old\b\100_1610.jpg
19f9cda002c951f7a9f870ce74fb1224 .\old\b\100_1601.jpg
32b154f796303a8e9caff0c9d55ba713 .\old\b\100_1600.jpg
26ff43419c4f30764fb015f6d7c869c1 .\old\b\100_1609.jpg
d95e29e2c0172dea438b12c418b09fd3 .\old\a\100_1610.jpg
19f9cda002c951f7a9f870ce74fb1224 .\old\a\100_1601.jpg
32b154f796303a8e9caff0c9d55ba713 .\old\a\100_1600.jpg
new.txt
545b2121a3af2a8e5aa3c5946b450e87 .\new\c\100_1605.jpg
02a1638739302f3c17253beaa3fe9c1b .\new\c\100_1603.jpg
d95e29e2c0172dea438b12c418b09fd3 .\new\c\100_1610.jpg
19f9cda002c951f7a9f870ce74fb1224 .\new\c\100_1601.jpg
32b154f796303a8e9caff0c9d55ba713 .\new\a\100_1600.jpg
use a schema.ini file:
[old.txt]
Format=Delimited( )
ColNameHeader=False
Col1=MD5 CHAR
Col2=PATH CHAR
[new.txt]
Format=Delimited( )
ColNameHeader=False
Col1=MD5 CHAR
Col2=PATH CHAR
and VBScript:
Option Explicit
Dim goFS : Set goFS = CreateObject("Scripting.FileSystemObject")
Dim oDb : Set oDb = CreateObject("ADODB.Connection")
Dim sCS : sCS = Join(Array(_
"Provider=MSDASQL" _
, "Driver={Microsoft Text Driver (*.txt; *.csv)}" _
, "DBQ=" & goFS.GetAbsolutePathName("..\data") _
), ";")
Dim sSQL : sSQL = "SELECT O.* FROM [old.txt] O LEFT JOIN [new.txt] N ON O.MD5 = N.MD5 WHERE N.MD5 IS NULL"
oDb.Open sCS
Dim oRS : Set oRS = oDb.Execute(sSQL)
If Not oRS.EOF Then WScript.Echo oRS.GetString(2, , "|", vbCrLf, "NULL")
oDB.Close
output:
6d5f1279d4deccbaeef5d074b13ed2f4|.\old\b\100_1608.jpg
26ff43419c4f30764fb015f6d7c869c1|.\old\b\100_1609.jpg
ADDED:
By using
Dim sSQL : sSQL = "SELECT O.*, N.PATH FROM [old.txt] O INNER JOIN [new.txt] N ON O.MD5 = N.MD5"
you could get the duplicates:
d95e29e2c0172dea438b12c418b09fd3|.\old\a\100_1610.jpg|.\new\c\100_1610.jpg
d95e29e2c0172dea438b12c418b09fd3|.\old\b\100_1610.jpg|.\new\c\100_1610.jpg
19f9cda002c951f7a9f870ce74fb1224|.\old\a\100_1601.jpg|.\new\c\100_1601.jpg
19f9cda002c951f7a9f870ce74fb1224|.\old\b\100_1601.jpg|.\new\c\100_1601.jpg
32b154f796303a8e9caff0c9d55ba713|.\old\a\100_1600.jpg|.\new\a\100_1600.jpg
32b154f796303a8e9caff0c9d55ba713|.\old\b\100_1600.jpg|.\new\a\100_1600.jpg
(cf. same approach, similar problem)

Evaluating the First Character of a User Defined Variable is Uppercase

I have a template document that I want to convert to another file with a user defined name. The following is the code I have pieced together.
rem #echo off
setlocal enableDelayedExpansion
cls
:Check_Filename
set "_Filename="
set /p _Filename=Enter filename to be created:
if not defined _Filename echo You must enter a value. Try again.&goto Check_Filename
set "test=%_Filename:~0,1%"
for %%C in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if defined test set "test=!test:%%C=!"
if defined test echo Invalid input. Try again.&goto Check_Filename
if not defined test echo %_Filename%
Set "errorlevel="
echo %_Filename% | findstr /i /R ".java" > nul
if %errorlevel% == 0 (
echo Java extention located
type f:\java\Template.txt > f:\java\%_Filename%
echo %errorlevel%
) else (
echo Java extention not located
echo %errorlevel%
type f:\java\Template.txt > f:\java\%_Filename%.java
)
)
It works but because the file is being used to create the backbone of Java script I want the FOR statement to evaluate the case of the first character which it does not presently do. I tried using HEX representation of these characters in the FOR statement as well, but without success.
Could someone please help me?
Thank you.
Try this:
#echo off & setlocal
:Check_Filename
set "_Filename="
set /p "_Filename=Enter filename to be created: "
if not defined _Filename echo You must enter a value. Try again.&goto:Check_Filename
echo(%_Filename:~0,1% | findstr /r "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]" || (echo Invalid input. Try again.&goto:Check_Filename)

vbscript pass the current directory as named argument

I'm trying to pass the working directory to vbscript as a named argument. The system normally expands "." to the current path, but when I check the named argument I just get the string "."
Here's the command line:
cscript myscript.vbs /a:"first arg" /b:second /c:.
Here's the script:
dim args : set args = wscript.arguments.named
wscript.echo args.item("a")
wscript.echo args.item("b")
wscript.echo args.item("c")
Here's the output:
first arg
second
.
Set fso = CreateObject("Scripting.FileSystemObject")
WScript.Echo fso.GetAbsolutePathName(args("c"))
Or you could use /c:"%CD%" instead of /c:..
If you always want to know the current directory, you don't need to pass it as an argument, though. Simply use
cwd = CreateObject("WScript.Shell").CurrentDirectory

How do I pass a property value containing a semicolon on the MSBuild command line when running it from PowerShell?

I'm attempting to pass a property to MSBuild. The property is a semicolon-delimited list of values. Unlike this question, I'm running MSBuild from PowerShell.
I get:
PS> msbuild .\Foo.sln /p:PackageSources="\\server\NuGet;E:\NuGet"
MSBUILD : error MSB1006: Property is not valid.
Switch: E:\NuGet
If I run the same command from Command Prompt, it works fine. How do I get it to work in PowerShell?
Wrap the parameter in single quotes:
... '/p:PackageSources="\\Server\NuGet;E:\NuGet"'
On PowerShell v3 try this:
msbuild .\Foo.sln --% /p:PackageSources="\\Server\NuGet;E:\NuGet"
Also using ASCIII value helps:
msbuild .\Foo.sln /p:PackageSources="\\Server\NuGet%3BE:\NuGet"
VBScript function below can be used to escape property values passed to MSBuild.exe inside double quotes:
Function Escape(s)
Escape = s
Set objRegEx = CreateObject("VBScript.RegExp")
objRegEx.Global = True
objRegEx.Pattern = "(\\+)?"""
Escape = objRegEx.Replace(Escape,"$1$1\""")
objRegEx.Pattern = "(\\+)$"
Escape = objRegEx.Replace(Escape,"$1$1")
End Function
The following example demonstrates usage of Escape() function
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "msbuild.exe echo.targets /p:Param1=""" & Escape("ParamValue1") & """,Param2=""" & Escape("ParamValue1") & """", 1, True