- Aug
- 2,056
- 83
Working with COM Objects in Powershell is a great way to interface with programs from the command line such as;
*) Microsoft Excel
*) Microsoft Word
*) Microsoft Visual FoxPro
*) Microsoft Outlook
...and many other COM Objects.
The TCC PSHELL Command and @PSHELL Function have many quirks which make them an un-reliable method of working with COM objects via PowerShell.
VBScript is also a great way to interface with COM Objects, but not from the command line.
A while back, I found code for a Simple VB Shell, that allows me to have a command line interface for VBScript.
I have ammended the code, so that I can work with COM Objects, and with TCC, from the VBI command line.
I am using the Microsoft (R) Windows Script Host Version 5.8 on my Windows 7 64-bit system.
Examples:
First off, to exit from VBI:
This is how I start VBI from the TCC command line:
To launch the Microsoft Windows calculator:
To use TCC to display the ISO Date:
To use TCC to store the ISO Date into a VBScript variable called result:
Normally, one cannot set an environment variable in VBScript. This can now be done with help from TCC:
What is VBIPID? This is a function I borrowed to obtain the VBI Process ID:
To retrieve an environment variable from VBI:
...or, to store the result into a VBScript variable called result:
While you may not have Microsoft Visual FoxPro on your system, here is how I can now interface with it:
It's quite easy to add commands and functions to VBI. For example, VBScript does not have a command to clear the screen, but TCC does have a command to clear the screen:
...so now, from the VBI command line, I can just type cls to clear the screen.
If you want to use cmd.exe instead of tcc.exe, there is the ExecCmd() function. Example:
The original author has made comments throughout the source code, and I have made numerous comments throughout the source code for my ammendments, so please review in detail for more info.
There are limitations to VBI, but if others are interested in enhancing it, please do so, and please share your enhancements.
Joe
*) Microsoft Excel
*) Microsoft Word
*) Microsoft Visual FoxPro
*) Microsoft Outlook
...and many other COM Objects.
The TCC PSHELL Command and @PSHELL Function have many quirks which make them an un-reliable method of working with COM objects via PowerShell.
VBScript is also a great way to interface with COM Objects, but not from the command line.
A while back, I found code for a Simple VB Shell, that allows me to have a command line interface for VBScript.
I have ammended the code, so that I can work with COM Objects, and with TCC, from the VBI command line.
I am using the Microsoft (R) Windows Script Host Version 5.8 on my Windows 7 64-bit system.
Examples:
First off, to exit from VBI:
Code:
.quit
This is how I start VBI from the TCC command line:
Code:
cscript //nologo c:\utils\vbi.vbs
To launch the Microsoft Windows calculator:
Code:
.echo tcc("detach calc.exe")
To use TCC to display the ISO Date:
Code:
.echo tcc("echo %_isodate")
To use TCC to store the ISO Date into a VBScript variable called result:
Code:
result = tcc("echo %_isodate")
Normally, one cannot set an environment variable in VBScript. This can now be done with help from TCC:
Code:
.echo tcc("setp " & VBIPID & " bdate=1995")
.echo GetVar("%bdate%")
1995
What is VBIPID? This is a function I borrowed to obtain the VBI Process ID:
Code:
.echo VBIPID
25380
To retrieve an environment variable from VBI:
Code:
.echo GetVar("%comspec%")
...or, to store the result into a VBScript variable called result:
Code:
result = GetVar("%comspec%")
.echo result
While you may not have Microsoft Visual FoxPro on your system, here is how I can now interface with it:
Code:
vfp.docmd("use c:\utils\orders.dbf shared")
.echo vfp.Eval("reccount()")
16
vfp.docmd("use")
It's quite easy to add commands and functions to VBI. For example, VBScript does not have a command to clear the screen, but TCC does have a command to clear the screen:
Code:
Sub Cls
TCC("cls")
End Sub
...so now, from the VBI command line, I can just type cls to clear the screen.
If you want to use cmd.exe instead of tcc.exe, there is the ExecCmd() function. Example:
Code:
.echo ExecCmd("cmd.exe /c date /t")
Tue 04/23/2019
The original author has made comments throughout the source code, and I have made numerous comments throughout the source code for my ammendments, so please review in detail for more info.
There are limitations to VBI, but if others are interested in enhancing it, please do so, and please share your enhancements.
Joe
Code:
' VBI.vbs -- simple VB shell
' Miles Willmek 2007-02-25
' https://gallery.technet.microsoft.com/scriptcenter/5808b0d2-f16f-4aa9-90df-c849371f1e61
'
' Amended to work with TCC and COM Objects by Joe Caverly
'
On Error Resume Next 'Turn on Error Handline
Const BQ = "`" 'Default Dos Command Delimiter
Dim sh, ox, st
Set sh = CreateObject("WScript.Shell") 'Init WshShell Object
'
' I can use Visual FoxPro from the VBI Command line
'
' Remove the comment from the following line if you
' have Visual FoxPro on your system.
' Set vfp = CreateObject("visualfoxpro.application")
'
' .echo vfp.Version
' 9.0
'
' .echo vfp.DoCmd("use c:\utils\orders.dbf shared")
' .echo vfp.Eval("reccount()")
' 16
'
' .echo vfp.DoCmd("use")
'
' If you have them installed, you can use;
' Microsoft Excel
' Microsoft Word
' Microsoft Outlook
' ...or any other COM object
' Main Shell Loop
' Exit with ^C or Wscript.Quit
'
Do While vbTrue 'Forever
Wscript.StdOut.Write "VB> " 'Prompt
st = Wscript.StdIn.ReadLine
With Wscript 'Handy Access to .Echo and .Quit
If Left(st, 1) = BQ Then 'If first char is BQ then echo results of DOS cmd
Execute "Wscript.Stdout.Write " & ReplaceBQ(st)
Else
Execute ReplaceBQ(st) 'Otherwise just execute
End If
End With
If Err.number <> 0 Then 'Check for Error from Execute
Wscript.Stdout.WriteLine _
"*** " & Err.Source & vbCrLf & _
"*** " & Chr(34) & st & Chr(34) & vbCrLf & _
"*** Error " & Err.Number & ": " & Err.Description & vbCrLf 'Display Error Information
Err.Clear 'Reset Error Object
End If
Loop
' Send command to WshShell.Exec and return output
'
Function ExecCmd(cmd)
Set ox = sh.Exec(cmd) 'Exec object is returned from Exec call
ExecCmd = ox.StdOut.ReadAll & ox.StdErr.ReadAll 'Read StdOut/StdErr streams from Exec object
Set ox = Nothing
End Function
Function TCC(cmd)
'You can hard-code the location of TCC.EXE
'
'comspec = "C:\Program Files\JPSoft\TCMD24\TCC.EXE"
comspec = "C:\Program Files\JPSoft\TCC_RT_24\tcc.exe"
'
'...then use that in the function
TCC = ExecCmd(comspec & " /c " & cmd)
'
'...or you can use the %comspec% environment variable
'TCC = ExecCmd(getvar("%comspec%") & " /c " & cmd)
End Function
Function GetVar(theVar)
Set wshShell = CreateObject( "WScript.Shell" )
GetVar = wshShell.ExpandEnvironmentStrings( theVar )
End Function
' Scan VB text line and replace BQ delimited commands
' with proper VB call sequences for shell commands
'
Function ReplaceBQ(vb)
out = ""
i = 0
Do While i <= Len(vb) 'Scan each char
i = i + 1
ch = Mid(vb, i, 1)
If ch = BQ Then 'Found opening BQ
p = InStr(i + 1, vb, BQ) 'Position of closing BQ
If p = 0 Then
vb = vb & BQ 'Add BQ if no closing BQ
p = Len(vb) 'and mark its position
End If
cmd = Mid(vb, i + 1, p - i - 1) 'command is substring between i and p
If Left(cmd, 1) = "@" Then cmd = "%comspec% /c " & Mid(cmd, 2) 'cmd.exe used for DOS builtins
out = out & "ExecCmd(" & Chr(34) & cmd & Chr(34) & ")" 'substitute WshShell.Exec wrapper call
i = p 'and skip past closing BQ
Else
out = out & ch 'if not BQ command just pass through to out
End If
Loop
ReplaceBQ = out 'set the function return value
End Function
Function VBIPID
' Ref: https://stackoverflow.com/questions/8296037/find-my-own-process-id-in-vbscript/13212628
Set com = CreateObject("Wscript.Shell")
Set objSWbemServices = GetObject ("WinMgmts:Root\Cimv2")
Set colProcess = objSWbemServices.ExecQuery ("Select * From Win32_Process")
Dim toto, thisPid
thisPid=""
toto=200 ' just a high value like 200sec
For Each objProcess In colProcess
If InStr (objProcess.CommandLine, WScript.ScriptName) <> 0 Then
Ptime=((Cdbl(objProcess.UserModeTime)+Cdbl(objProcess.KernelModeTime))/10000000)
if toto > Ptime then
toto = Ptime
thisPid = objProcess.ProcessId
End If
End If
Next
If thisPid="" then
'WScript.Echo "unable to get the PID"
VBIPID = 0
Else
'WScript.Echo "PID of this script : "&thisPid
VBIPID = thisPid
End If
End Function
Sub Help
WScript.echo "GetVar - Obtain an environment variable"
WScript.echo "USAGE: .echo GetVar(" & Chr(34) & "%comspec%" & Chr(34) & ")"
WScript.Echo " result = GetVar(" & Chr(34) & "%comspec%" & Chr(34) & ")"
WScript.Echo " .echo result"
WScript.Echo ""
WScript.Echo "VBIPID - Obtain the Process ID for this VBI Session"
WScript.Echo "USAGE: .echo VBIPID"
WScript.Echo " thePID = VBIPID"
WScript.Echo ""
WScript.Echo "TCC - Run a TCC command or .BTM"
WScript.Echo "USAGE: .echo tcc(" & Chr(34) & "detach calc.exe" & Chr(34) & ")"
WScript.Echo " .echo tcc(" & Chr(34) & "echo %_isodate" & Chr(34) & ")"
WScript.Echo " result = tcc(" & Chr(34) & "echo %_isodate" & Chr(34) & ")"
WScript.Echo ""
WScript.Echo "Set Environment Variable in VBI"
WScript.Echo "Example: You can set an environment variable in VBScript via TCC"
WScript.Echo ""
WScript.Echo " .echo tcc(" & Chr(34) & "setp " & Chr(34) & " & " & " VBIPID" & " & " & Chr(34) & " bdate=1995" & Chr(34) & ")"
WScript.Echo " .echo GetVar(" & Chr(34) & "%bdate%" & Chr(34) & ")"
WScript.Echo ""
WScript.Echo ".quit - Exit this VBI session"
End Sub
Sub Cls
TCC("cls")
End Sub
Sub Dir
WScript.echo TCC("dir")
End Sub