I've a batch script which calls a vbs file to do some operations on a web page. From this batch file, I pass 4 parameters(string) to vbs file.
Now I'm looking to integrate this with my QTP framework.
So I need to call this batch file from framework and I'll pass these parameters from QTP to Batch file which batch file will further pass to vbs code.
Here is what I'm trying:
QTP Code:
Dim BatchRun
Set BatchRun = CreateObject ("WSCript.shell")
lob=DataTable("LOB",IntSheetNo-1)
mailto=DataTable("EmailTo",IntSheetNo-1)
mailcc=DataTable("EmailCC",IntSheetNo-1)
BatchRun.Run "C:\invoke.bat " & lob & " " & mailto & " " & mailcc
Set BatchRun = Nothing
Batch Code:
C:
cscript kamal.vbs %1 %2 %3
vbs code :
Set args = Wscript.Arguments ' to accept command line arguments
xprod = args(0)
mailto=args(1)
mailcc=args(2)
And I used these for some operations through vbs.
I did search on google and stackoverflow to find spome examples but none worked for me so far.
Not sure what QTP is, and assuming DataTable(....) returns a string, your problem probably is the spaces in data. When calling a batch file, parameter separation is determined by spaces. If there are any space in lob, mailto or mailcc, arguments are not correctly parsed. You need to wrap each of the arguments in quotes (and ensure inner quotes in arguments are escaped to no interfere)
So, QTP
lob= Chr(34) + Replace(DataTable("LOB",IntSheetNo-1), Chr(34), Chr(34)+Chr(34)) + Chr(34)
mailto=Chr(34) + Replace(DataTable("EmailTo",IntSheetNo-1), Chr(34), Chr(34)+Chr(34)) + Chr(34)
mailcc=Chr(34) + Replace(DataTable("EmailCC",IntSheetNo-1), Chr(34), Chr(34)+Chr(34)) + Chr(34)
Dim BatchRun
Set BatchRun = CreateObject ("WSCript.shell")
BatchRun.Run "C:\invoke.bat " & lob & " " & mailto & " " & mailcc
Set BatchRun = Nothing
Batch Code
C:
cscript kamal.vbs "%~1" "%~2" "%~3"
And VBS code without changes
Related
I am trying to open an HTML file with a specific destination anchor from a batch file like so:
start iexplore %~dps0nl752.htm#01
exit
nl753.htm is on the local drive.
How can I get Windows to open the HTML file with the destination anchor in the default browser instead of Internet Explorer?
If you want to start the default browser then you should obviously not hardcode iexplore! The start command will figure out the system default on its own based on the file extension or URL protocol.
On my Windows 8.1 machine anchors work fine:
start "" "http://example.com#whatever"
it does seem to work without quotes as well but I personally prefer them just in case there is a space or a & there.
In my experience Internet Explorer will sometimes do some kind of internal redirection when dealing with local .htm[l] files and/or file:// URLs and this seems to strip away the anchor. There is not much you can do about that.
Just to be clear, appending a anchor to a plain file system path will not work because it technically changes the extension. A file:// URL will work because Windows only looks at the protocol when dealing with URLs.
On my system start "" "file:///C:/Program%20Files/Common%20Files/microsoft%20shared/Stationery/Soft%20Blue.htm#whatever" does work as far as accepting the command and starting the browser. This does not mean that the browser will respect the anchor but that is a implementation detail in the browser that you have no control over and results might vary depending on which browser is the default.
If this is not good enough then you can try using IE Automation to start and control Internet Explorer. This means you have to give up using the users default browser and I would not recommend it for this reason...
Relying on the file:// protocol and a .html extension to execute a browser and not a HTML editor is somewhat risky as pointed out in another answer but I'm not sure if I would dare to query the registry in a batch-file either.
The absolute best solution is to call ShellExecuteEx with a forced progid but that is only possible in a real application.
The second best solution is to write a Windows Scripting Host script instead of a batch file since it is much safer to read and parse the registry there...
In the case of opening files, using file:// is the same as calling the file directly.
That is,
start "" "file://%cd:\=/%/myfile.html"
is the same as
start "" "myfile.html"
Which is all well and good if your default program for opening HTML files is a browser, but it may not be.
To use the browser, the only thing I can think of is getting it from the registry:
#echo off
setlocal EnableDelayedExpansion
for /F "tokens=3" %%i in ('reg query HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice /v ProgID') do for /F "tokens=2*" %%j in ('reg query HKEY_LOCAL_MACHINE\Software\Classes\%%i\shell\open\command /ve') do set cmd=%%k
start "" !cmd:%%1=file://%cd:\=/%/%1!
To explain, this retrieves the association with the "http" URL schema then looks up the execution command for that entry and stores it in cmd. We use %%k instead of j here because it will likely contain spaces, so 2 (%%j) selects the second entry in the return from reg then collected the rest into %%k.
Then it uses start to call the cmd with the target file (%1 here) is spliced into the %1 in the cmd. We assume the passed command is relative and make it absolute by prefixing it with the %cd% with the \ replaced with / as URLs need, then prefixed with the file schema for the browser.
I don't know how robust this is offhand, for instance the registry addresses my be different per system (I did this on Win10).
To open file from cmd Type:
start "index.html"
ShVerb
Lists or runs an explorer verb (right click menu) on a file or folder
ShVerb <filename> [verb]
Used without a verb it lists the verbs available for the file or folder
The program lists most verbs but only ones above the first separator
of the menu work when used this way
The Properties verb can be used. However the program has to keep running
to hold the properties dialog open. It keeps running by displaying
a message box.
The VBS script is
HelpMsg = vbcrlf & " ShVerb" & vbcrlf & vbcrlf & " David Candy 2014" & vbcrlf & vbcrlf & " Lists or runs an explorer verb (right click menu) on a file or folder" & vbcrlf & vbcrlf & " ShVerb <filename> [verb]" & vbcrlf & vbcrlf & " Used without a verb it lists the verbs available for the file or folder" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The program lists most verbs but only ones above the first separator" & vbcrlf & " of the menu work when used this way" & vbcrlf & vbcrlf
HelpMsg = HelpMsg & " The Properties verb can be used. However the program has to keep running" & vbcrlf & " to hold the properties dialog open. It keeps running by displaying" & vbcrlf & " a message box."
Set objShell = CreateObject("Shell.Application")
Set Ag = WScript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
If Ag.count = 0 then
wscript.echo " ShVerb - No file specified"
wscript.echo HelpMsg
wscript.quit
Else If Ag.count = 1 then
If LCase(Replace(Ag(0),"-", "/")) = "/h" or Replace(Ag(0),"-", "/") = "/?" then
wscript.echo HelpMsg
wscript.quit
End If
ElseIf Ag.count > 2 then
wscript.echo vbcrlf & " ShVerb - To many parameters" & vbcrlf & " Use quotes around filenames and verbs containing spaces" & vbcrlf
wscript.echo HelpMsg
wscript.quit
End If
If fso.DriveExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetFileName(Ag(0)))
' Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Set objFolderItem = objFolder.self
msgbox ag(0)
ElseIf fso.FolderExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
ElseIf fso.fileExists(Ag(0)) = True then
Set objFolder = objShell.Namespace(fso.GetParentFolderName(Ag(0)))
Set objFolderItem = objFolder.ParseName(fso.GetFileName(Ag(0)))
Else
wscript.echo " ShVerb - " & Ag(0) & " not found"
wscript.echo HelpMsg
wscript.quit
End If
Set objVerbs = objFolderItem.Verbs
'If only one argument list verbs for that item
If Ag.count = 1 then
For Each cmd in objFolderItem.Verbs
If len(cmd) <> 0 then CmdList = CmdList & vbcrlf & replace(cmd.name, "&", "")
Next
wscript.echo mid(CmdList, 2)
'If two arguments do verbs for that item
ElseIf Ag.count = 2 then
For Each cmd in objFolderItem.Verbs
If lcase(replace(cmd, "&", "")) = LCase(Ag(1)) then
wscript.echo(Cmd.doit)
Exit For
End If
Next
'Properties is special cased. Script has to stay running for Properties dialog to show.
If Lcase(Ag(1)) = "properties" then
WSHShell.AppActivate(ObjFolderItem.Name & " Properties")
msgbox "This message box has to stay open to keep the " & ObjFolderItem.Name & " Properties dialog open."
End If
End If
End If
It gives output like this when listing available verbs
C:\Windows\system32>cscript //nologo "C:\Users\User\Desktop\ShVerb.vbs" "C:\Users\User\Desktop\Filter.html"
Open
Open in Same Window
Print
Restore previous versions
Cut
Copy
Create shortcut
Delete
Rename
Properties
To use to open an html page.
cscript "C:\Users\User\Desktop\Bat&Vbs\ShVerb.vbs" "C:\Users\User\Desktop\Filter.html" Open
To start any file in the system defaults you need to use the 'start' command on Windows 10 (Not sure about lower versions but I'm guessing it will be about the same) & 'open' for MacOS Terminals.
On Windows,
To open any file use:
*start 'filename.format'
This should open up the files in default applications, like HTML files in browsers, images in albums, etc.
I am trying to run a .bat file as part of my VBScript with the parameter of another file.
I have tried:
param1 = CurrentFolder & "\file.extension"
command = "C:\folder name\compiler.bat"
Set WScript = CreateObject("WScript.Shell")
WScript.run "cmd " & command & " " & param1
But nothing seems to work.
Im trying to achieve the same as if I dragged "file.extension" and dropped it onto "compiler.bat"
Choose a different name for your Shell object. WScript is a built-in, global object in WSH. For example:
Set objShell = CreateObject("WScript.Shell")
Try this for your Run statement:
objShell.Run "cmd /c " & Chr(34) & Chr(34) & command & Chr(34) & " " & Chr(34) & param1 & Chr(34) & Chr(34)
The /c will close the prompt when the command completes. The Chr(34)'s are used to put quotes around your command and your parameter, in case either contains spaces. Note that you also need quotes around the entire statement. For example:
cmd /c ""c:\folder name\compiler.bat" "a param with spaces""
I'm making a utility using QuickTest Professional which calls a batch file with some parameters.
This batch file further calls a vbscript and passes some parameters to this vbs file.
This vbs file perform operations and generate a number.
I want this number to flow back from vbs to batch and then to QTP.
This is what I've figured out so far:
QTP(sending parameters to bat) >> Batch(sending parameters to vbs) >> VBS (generates a number)
now I want this vbs to return the output number back
VBS >> Batch(same bat which called vbs file) >> QTP(same qtp process which called this batch)
Here is my code:
QTP: (calling batch)
Dim BatchRun
Set BatchRun = CreateObject ("WSCript.shell")
invokefile= Chr(34) + "C:/invokebugz.bat" + Chr(34)
BatchRun.Run invokebugzfile & lob & " " & mailto & " " & mailcc & " " & title & " " & subject
Bat: (calling vbs)
cd C:\
cscript abc.vbs "%~1" "%~2" "%~3" "%~4" "%~5"
vbs:
Set args = Wscript.Arguments ' to accept command line arguments
xprod = args(0)
mailto = args(1)
mailcc = args(2)
xtitle = args(3)
xcomment = args(4)
You can get the value back if you just print it to standard output. So just write the result from VBS like this:
Wscript.Echo result
The for command can be used to get the output of a command that you invoke:
for /f %%a in ('cscript abc.vbs "%~1" "%~2" "%~3" "%~4" "%~5"') do (
echo The output is %%a
)
If the output is just a number, you shouldn't need to add any extra options to the for loop. Try running for /? for more help.
I've got this working line of code in Windows Batch
start "" /wait /i "C:\Program Files\Sandboxie\Start.exe" /box:NetBeans /wait "C:\Program Files\NetBeans 7.3\bin\netbeans64.exe"
I would like to run it via VBScript. But I don't know how to pass the path in parameter which has a space inside.
I came up with something like this:
Set objShell = CreateObject("Wscript.Shell")
objShell.Run("C:\Program Files\Sandboxie\Start.exe" /box:NetBeans /wait "C:\Program Files\NetBeans 7.3\bin\netbeans64.exe"), 1, True
But there is an error:
expected: ')'
Within a literal string, a single double-quote character is represented by two double-quote characters. So try the following instead:
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run """C:\Program Files\Sandboxie\Start.exe"" /box:NetBeans /wait ""C:\Program Files\NetBeans 7.3\bin\netbeans64.exe""", 1, True
Set objShell = Nothing
I like to use the following system to embed quotes :
strCommand = Quotes("C:\Program Files\Sandboxie\Start.exe") & _
" /box:NetBeans /wait " & _
Quotes("C:\Program Files\NetBeans 7.3\bin\netbeans64.exe")
Function Quotes(ByVal strValue)
Quotes = Chr(34) & strValue & Chr(34)
End Function
It's a lot easier to read.
I'm new to VBScript. I cannot find a way to copy files from one XP host to another using WMI in a VBS. The usual way of copying files (RPC - Remote Procedure Call, SMB, UNC) are not available to several hosts but WMI is available to all hosts, and I need to copy files from my admin host to a target Windows host. I thought I'd find some sample code out there but I've found no info on it. Haven't found anything telling me it can't be done, either.
The source files are an executable and 'test1.txt' in my admin computer's 'F:\TEMP' folder. I want to put the files on remote host HOST1's 'C:\TEMP' folder. I have full admin rights on both hosts. Here is what I have so far, just for one file (to keep the testing simple):
strComputer = "HOST1"
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colFiles = objWMIService.ExecQuery( _
"Select * from Win32_Directory where Name = 'c:\\temp'")
For Each objFiles in colFiles
errResults = objFolder.Copy("f:\temp\test1.txt")
Wscript.Echo errResults
Next
I learned that WMI cannot create files on a remote host, and it cannot copy files over a network connection:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa389288%28v=vs.85%29.aspx
However, it can run a cmd process. Here's Frank White's code in C sharp, followed by his example:
https://stackoverflow.com/a/8913231/1569434
InputParameters("CommandLine") = "cmd /c echo myFTPCommands > c:\ftpscript.txt"
You will need four things to use all the following scriptlets, which build on each other to use psexec to run a "normal" VBScript or batch script on the remote host:
admin rights on the remote host;
WMI enabled on the remote host
a network share (using RPC, UNC, FTP, etc., but NOT DFS! ("Distributed File System" - see note) that your remote host can access; and
psexec.exe and your "normal" script(s) on the network share.
Important Note: Do NOT use DFS to map the network share! It will fail if you use Distributed File System for your network share. An error code you might get depending on how you try is "System error 1312", no matter which operating system (e.g., XP, Win 7) you use.
When RPC is not available on a remote host but WMI is, then the following method will create a local ASCII file on the remote host's c:\temp folder, containing the text "myTextCommands", without the quotes.
' https://stackoverflow.com/questions/8884728/wmi-remote-process-to-copy-file
strCommand = "cmd /c echo myTextCommands > c:\temp\testscript.txt"
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\cimv2")
Set objProcess = objWMIService.Get("Win32_Process")
errReturn = objProcess.Create(strCommand, null, null, intProcessID)
' See following link for error codes returned by errReturn
' http://msdn.microsoft.com/en-us/library/windows/desktop/aa389388(v=vs.85).aspx
Notice the important limitation in the script above: it can only create ASCII files - not binary.
Let's use that technique to map a drive letter:
strCommand = "cmd /c net use z: " & MyShare & " /user:%USERDOMAIN%\%USERNAME% " _
& strPassword & ">" & strRemoteLog
Set objProcess = objWMIService.Get("Win32_Process")
Call errProcess
where "strRemoteLog" is set to something like "c:\temp\MyLog.txt", "strPassword" is prompted (see full script example and reference at bottom), and "errProcess" is a subroutine that runs the following process using the "cmd /c" trick mentioned above:
Sub errProcess
errReturn = objProcess.Create(strCommand, null, null, intProcessID)
If errReturn = 0 Then
Wscript.Echo "Process was started with a process ID: " & intProcessID
WScript.Sleep 5000
Else
Wscript.Echo "Process could not be started due to error: " & errReturn
End If
End Sub
With a network drive mapped, copy your script to the host:
strCommand="cmd /c xcopy Z:\scripts\SCRIPT1.bat c:\temp\ >>" & strRemoteLog
Call errProcess
SCRIPT1.bat is ready, so start psexec against it on the remote host, passing your script a variable strUserID that would be obtained earlier and is here for example:
strCommand="cmd /c Z:\psexec \\%COMPUTERNAME% /accepteula -s -n 120 " _
& cmd /c c:\temp\SCRIPT1.bat " & strUserID & ">>" & strRemoteLog
Call errProcess
Once psexec finishes, you might want to save the results. So you rename the log file, upload it, unmap your drive, and clean up residual files:
strCommand="cmd /c REN " & strRemoteLog & " SCRIPT1-%COMPUTERNAME%.txt"
Call errProcess
strCommand="cmd /c MOVE /Y c:\temp\SCRIPT1*.txt Z:\scripts\LOGS\"
Call errProcess
strCommand="cmd /c net use * /del /Y"
Call errProcess
strCommand="cmd /c del c:\temp\SCRIPT1*.bat /q"
Call errProcess
You're done. You've successfully mapped a drive, run a routine script against the remote host, and uploaded its output.
Note this method also works on Windows 7 and Windows 2008 with UAC.
Here's the full 'sample' integrated script. Feel free to suggest fixes, improvements, etc.
On Error Resume Next
MyShare="\\SHARE1"
strRemoteLog="c:\temp\MapZ.txt"
' Set remote hostname
strComputer="HOST2"
'strComputer = InputBox("Enter Computer name", _
'"Find PC", strComputer)
' Set remote userid
strUserID="USERID1"
'strComputer = InputBox("Enter userid", _
'"Find User", strComputer)
' Enumerate cimv2 on remote host strComputer
Set objWMIService = GetObject("winmgmts:" & _
"{impersonationLevel=Impersonate}!//" & strComputer & "\root\cimv2")
' Verify remote host exists on domain
If( IsEmpty( objWMIService ) = True ) Then
WScript.Echo( "OBJECT_NOT_INITIALIZED :: " & strComputer )
WScript.Quit( OBJECT_NOT_INITIALIZED )
End If
' Prompt for masked password
strPassword=GetPass
' Build and run command to execute on strComputer
strCommand = "cmd /c net use z: " & MyShare & " /user:%USERDOMAIN%\%USERNAME% " & strPassword & ">" & strRemoteLog
Set objProcess = objWMIService.Get("Win32_Process")
Call errProcess
' Copy script(s) from MyShare to HOST2 since psexec cannot run scripts on shared drives
strCommand="cmd /c xcopy Z:\scripts\cleanpclocal.bat c:\temp\ /V /C /I /Q /H /R /Y>>" & strRemoteLog
Call errProcess
' Change directory to c:\temp
'strCommand="cmd /c cd c:\temp>" & strRemoteLog
'Call errProcess
' Start PSEXEC against script
strCommand="cmd /c Z:\psexec \\%COMPUTERNAME% /accepteula -s -n 120 cmd /c c:\temp\cleanpclocal.bat " & strUserID & ">>" & strRemoteLog
Call errProcess
' Rename logfile to include hostname, upload to share, unmap networked drive, and delete script
strCommand="cmd /c REN " & strRemoteLog & " cleanpc-%COMPUTERNAME%.txt"
Call errProcess
strCommand="cmd /c MOVE /Y c:\temp\clean*.txt Z:\scripts\LOGS\"
Call errProcess
strCommand="cmd /c net use * /del /Y"
Call errProcess
strCommand="cmd /c del c:\temp\clean*.bat /q"
Call errProcess
WScript.Quit
' ***********
' APPENDIX
' Subroutines, functions
' ***********
' **SUBROUTINES**
'strCommand="cmd /c dir z:\scripts\>" & strRemoteLog ' Works to get dir of z:\scripts\
' Function to handle errReturn
Sub errProcess
WScript.Echo "strCommand=" & strCommand
errReturn = objProcess.Create(strCommand, null, null, intProcessID)
If errReturn = 0 Then
Wscript.Echo "Process was started with a process ID: " & intProcessID
WScript.Sleep 5000
Else
Wscript.Echo "Process could not be started due to error: " & errReturn
End If
WScript.Echo
' Error return codes for Create method of the Win32_Process Class
' http://msdn.microsoft.com/en-us/library/windows/desktop/aa389388(v=vs.85).aspx
' 0=Successful Completion
' 2=Access Denied
' 3=Insufficient Privilege
' 8=Unknown failure
' 9=Path Not Found
' 21=Invalid Parameter
End Sub
' **FUNCTIONS**
' Subroutine to get masked password
Function GetPass
' Mask Passwords Using Internet Explorer
' Ensure you follow the technet.com instructions and create file password.htm
' http://blogs.technet.com/b/heyscriptingguy/archive/2005/02/04/how-can-i-mask-passwords-using-an-inputbox.aspx
Set objExplorer = WScript.CreateObject _
("InternetExplorer.Application", "IE_")
objExplorer.Navigate "file:///C:\SCRIPTS\password.htm"
objExplorer.ToolBar = 0
objExplorer.StatusBar = 0
objExplorer.Width = 400
objExplorer.Height = 350
objExplorer.Left = 300
objExplorer.Top = 200
objExplorer.Visible = 1
Do While (objExplorer.Document.Body.All.OKClicked.Value = "")
Wscript.Sleep 250
Loop
strPassword = objExplorer.Document.Body.All.UserPassword.Value
strButton = objExplorer.Document.Body.All.OKClicked.Value
objExplorer.Quit
Wscript.Sleep 250
If strButton = "Cancelled" Then
Wscript.Quit
'Else
' Wscript.Echo strPassword
End If
' Return the password
GetPass = strPassword
End Function
Firstly, I think there's a typo in your code where you've written:
errResults = objFolder.Copy("f:\temp\test1.txt")
I think you meant:
errResults = objFiles.Copy("f:\temp\test1.txt")
Secondly, I don't know if what you're trying to do is possible. I think the code you've got might copy a file from a directory on the remote computer to another directory on the remote computer.
For a solution though, if WMI is available remotely on all the computers, that means that at least one port is open. If that's the case, are there any other ports that are open? If so, maybe you could set up a FTP server on your admin host on port X and then have the other hosts send the file by automating the default XP FTP client.
I know this question is old, but came across is when I was trying to find a solution so figured would direct people to an answer I wrote up and posted here:
.NET - Copying an executable across LAN to another computer, and executing it
In short, it is possible to echo base64 conversion of any file (including an exe) using WMI and then decode it with certutil.
Have you tried the following ?
set fso = CreateObject("Scripting.FileSystemObject")
fso.CopyFile "f:\temp\test1.txt", "\\HOST1\C$\temp\test1.txt", true
WMI is a database of information. You cannot use it to copy files.