Use of SAPI Speech Recognition in a VBS Script? - vbscript

I found this one-line example that allows to use the Windows SAPI Text-to-Speech feature in VBScript:
CreateObject("SAPI.SpVoice").Speak("This is a test")
I wonder if the SAPI Speech Recognition could be used in a VBScript program in the same easy way. When I seek for such information the tons of SAPI information that appear are related to C++, like the Microsoft SAPI site, or to Text-to-Speech in VBS. I tried to find documentation about the SAPI COM object Speech Recognition part that could be used in a VBScript, but found none.
Do you know if such a documentation exists? TIA
EDIT: Additional request added after the first answer was recevied
Although the first answer below provide a link to the SAPI COM object documentation, I want to attract your attention to a point in my question: "I wonder if the SAPI Speech Recognition could be used in a VBScript program IN THE SAME EASY WAY". The SAPI documentation is huge! I read several pages of it and I am completely lost... My goal is to recognize just a few single words, say 8 or 10, and show a different message in the screen each time that one of they was recognized; that is it! (The program should be a console application started via cscript). Is there a simple example of VBS code that achieve such thing? If the required code to program this solution needs to have several pages, then it is not the answer I am looking for...

Here is a working example of vbscript listening a wav file:
scriptRunning = true
Sub rc_Recognition(StreamNumber, StreamPosition, RecognitionType, Result)
Wscript.Echo "Reco: ", Result.PhraseInfo.GetText, ".", RecognitionType
End Sub
Sub rc_StartStream(StreamNumber, StreamPosition)
Wscript.Echo "Start: ", StreamNumber, StreamPosition
End Sub
Sub rc_EndStream(StreamNumber, StreamPosition, StreamReleased)
Wscript.Echo "End: ", StreamNumber, StreamPosition, StreamReleased
scriptRunning = false
End Sub
outwav = "C:\SOFT\projects\af2t\t.wav"
Const SAFT22kHz16BitMono = 22
Const SSFMOpenForRead = 0
set sapiFStream = CreateObject("SAPI.SpFileStream")
sapiFStream.Format.Type = SAFT16kHz16BitMono
sapiFStream.Open outwav, SSFMOpenForRead
MsgBox "A SpeechLib::ISpRecoContext object will be created"
Const SGDSActive = 1
Set rct = WScript.CreateObject("SAPI.SpInProcRecoContext", "rc_")
Set rgnz = rct.Recognizer
Set rgnz.AudioInputStream = sapiFStream
Set rcGrammar = rct.CreateGrammar
'rcGrammar.DictationLoad
rcGrammar.DictationSetState SGDSActive
i = 0
while scriptRunning and i < 100
WScript.Sleep(50)
i = i + 1
wend
MsgBox "A SpeechLib::ISpRecoContext object has been created"
The magical part of the code is this line (the "rc_" prefix param allows events to be caught by the subs):
Set rct = WScript.CreateObject("SAPI.SpInProcRecoContext", "rc_")
The recorded text in the t.wav file I used for testing has been generated with SAPI.SpVoice::Speak and MS-David voice ;-)
I spent 10 days figuring out how to write this script. Microsoft is removing documentation about automation, COM, old style scripts, etc. A shame.
So, this works in dictation mode reading a wav file. But I couldn't correct it to make it work in live dictation mode (i.e. using the microphone as direct input). Any help appreciated for this. Thanks.
EDIT: direct/live dictation mode solved. If interested I share the vbscript code.
EDIT2: text sample spoken in the wav: Hello world. This is a talk about gear tooth profile using a circle involute.
Console output from the vbscript
C:\SOFT\projects\af2t>cscript r.vbs
Microsoft (R) Windows Script Host Version 5.812
Copyright (C) Microsoft Corporation. Tous droits réservés.
Start: 1 0
Reco: Hello world . 0
Reco: this is a talk about gear to the profile using a circle invalid . 0
End: 1 195040 -1
C:\SOFT\projects\af2t>

Yes. Look at the SAPI Automation Overview; it will tell you all about the late-bound COM interfaces and objects available to VBScript.

Related

Checking out data models in power designer with VBScript

Through a VBS code I need to check out some data models from the power designer.
The requirements are: Connect to the power designer repository, check out some data models. can anybody help me?
I found this code in SAP documentation, but when i execute it the following error appears.
Dim rc : Set rc = RepositoryConnection
'Check out model
Dim TargetModel
Set TargetModel = rc.FindChildByPath("MyFolder/MyPDM", PdRMG.Cls_RepositoryModel)
TargetModel.CheckOut()
Output "Checked"
The error messege:
Microsoft VBScript Runtime Error
Required object (0x800A01A8)
on line 5
As mentioned by the first comment, at least, verify the FindChildByPath return value:
Set TargetModel = rc.FindChildByPath("MyFolder/MyPDM", PdRMG.Cls_RepositoryModel)
if targetmodel is nothing then
output "nothing"
else
TargetModel.CheckOut()
Output "Checked out"
end if
Apart from that, the sample works for me, and opens the PDM I have checked in.

Need Assistance with VBSCRIPT to capture screenshots of user's desktop

I am a novice when it comes to object oriented program. That said, I have been trying to construct a vbscript that will capture a screenshot of the desktop and immediately save it to a folder I specify. Here is the code I have so far:
' START
Dim screenSize
screenSize = New screenSize.Size(Screen.PrimaryScreen.Bounds.X,Screen.PrimaryScreen.Bounds.Y)
Dim screenGrab
screenGrab = New screenGrab.Bitmap(My.Computer.Screen.Bounds.Width, my.Computer.Screen.Bounds.Height)
Dim g
g = g.System.Drawing.Graphics.FromImage(screenGrab)
dim copyS
copyS = Graphics.CopyPixels4.PaintEventArgs
dim copyS2
copyS2 = copyS.Graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation)
dim saveTo
saveTo = screenGrab.Save("C:\temp\screenGrab.bmp")
' END
I prefer to keep this in VBSCRIPT as this script will be incorporated into an existing vbscript I created. I currently get an error at line 3 stating "class not defined 'screensize". I am also concerned that even if I fix the error at line 3 I may run into other syntax issues afterward. The overall intent of the script is to 1) get the screen dimensons ; 2) perform the screenshot ; 3) and save the file to a destination. I am open to any suggestions to make this work.
I appreciate any help I can get at this point. Thank you.
It seems like you have messed VB.NET with VBScript.
screenSize, screenGrab, System.Drawing.Graphics - there are no such classes in VBScript by default.
What I'd suggest is to use some screen capture ActiveX (google it).
Or create your own ActiveX with VB6 by using code like this. Create new ActiveX project in VB6, add that module and compile.
And remember to run regsvr32.exe youractivex.ocx before using it in your script.

Change iTunes Track Comment on MacOS

I've written the below code in vba to change comments in iTunes tracks in a Windows environment:
Dim iTunes As New iTunesApp
Dim library As IITLibraryPlaylist
Dim tracksByArtist As IITTrackCollection
Dim xSearch As String, xComment As String
Dim track As IITFileOrCDTrack
Dim i As Long, j As Integer
Set library = iTunes.LibraryPlaylist
xComment = "myComment"
For i = 1 To NumberOfSongInItunes 'Number of songs in library
If xArray(9, i) = "Target" Then 'xArray holds information that i've previously read from the library or xml file
xSearch = "Artist Name " & "Album " & "Track Name"
Set tracksByArtist = library.Search(xSearch, 0)
For Each track In tracksByArtist
track.Comment = xComment
Next
End If
Next
Set iTunes = Nothing
I've been playing around in Xcode with ITLibrary, ITLibAlbum, ITLibArtist, etc. but with no success. Any ideas? Preferably not using applescript as it would be slow.
I'm not sure how well this fits in with what you're looking for, but the Scripting Bridge framework is always and option. The example below just changes the comment on which ever track is currently playing, but you can use iTunes.h and Scripting Bridge to do basically what ever you want with iTunes and its tracks.
#import <ScriptingBridge/ScriptingBridge.h>
#import "iTunes.h"
iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:#"com.apple.iTunes"];
[[iTunes currentTrack] setComment:#"I just added this cool comment to the current track!"];
There are recently generated copies of some of the Scripting Bridge headers on github, but I recommend that you compile your own to make sure everything is up to date. Instructions can be found here https://developer.apple.com/library/mac/DOCUMENTATION/Cocoa/Conceptual/ScriptingBridgeConcepts/Introduction/Introduction.html
Basically, to generate iTunes.h you'll need to run the following command.
sdef /Applications/iTunes.app | sdp -fh --basename iTunes
there is no public API for that. you would have to open the XML file and edit it. It is prone to break though

Visio to image command line conversion

At work we make pretty extensive use of Visio drawing as support for documentation. Unfortunately vsd files don't play nicely with our wiki or documentation extraction tools like javadoc, doxygen or naturaldocs. While it is possible to convert Visio files to images manually, it's just a hassle to keep the image current and the image files are bound to get out of date. And let's face it: Having generated files in revision control feels so wrong.
So I'm looking for a command line tool that can convert a vsd file to jpeg, png, gif or any image that can be converted to an image that a browser can display. Preferably it will run under unix, but windows only is also fine. I can handle the rest of the automation chain, cron job, image to image conversion and ssh, scp, multiple files, etc.
And that's why I'm turning to you: I can't find such a tool. I don't think I can even pay for such a tool. Is my Google-fu completely off? Can you help me?
I mean, it has got to be possible. There has to be a way to hook into Visio with COM and get it to save as image. I'm using Visio 2007 by the way.
Thanks in advance.
I slapped something together quickly using VB6, and you can download it at:
http://fournier.jonathan.googlepages.com/Vis2Img.exe
You just pass in the input visio file path, then the output file path (visio exports based on file extension) and optionally the page number to export.
Also here is the source code I used, if you want to mess with it or turn it into a VBScript or something, it should work, though you'd need to finish converting it to late-bound code.
hope that helps,
Jon
Dim TheCmd As String
Const visOpenRO = 2
Const visOpenMinimized = 16
Const visOpenHidden = 64
Const visOpenMacrosDisabled = 128
Const visOpenNoWorkspace = 256
Sub Main()
' interpret command line arguments - separated by spaces outside of double quotes
TheCmd = Command
Dim TheCmds() As String
If SplitCommandArg(TheCmds) Then
If UBound(TheCmds) > 1 Then
Dim PageNum As Long
If UBound(TheCmds) >= 3 Then
PageNum = Val(TheCmds(3))
Else
PageNum = 1
End If
' if the input or output file doesn't contain a file path, then assume the same
If InStr(1, TheCmds(1), "\") = 0 Then
TheCmds(1) = App.Path & "\" & TheCmds(1)
End If
If InStr(1, TheCmds(2), "\") = 0 Then
TheCmds(2) = App.Path & "\" & TheCmds(2)
End If
ConvertVisToImg TheCmds(1), TheCmds(2), PageNum
Else
' no good - need an in and out file
End If
End If
End Sub
Function ConvertVisToImg(ByVal InVisPath As String, ByVal OutImgPath As String, PageNum As Long) As Boolean
ConvertVisToImg = True
On Error GoTo PROC_ERR
' create a new visio instance
Dim VisApp As Visio.Application
Set VisApp = CreateObject("Visio.Application")
' open invispath
Dim ConvDoc As Visio.Document
Set ConvDoc = VisApp.Documents.OpenEx(InVisPath, visOpenRO + visOpenMinimized + visOpenHidden + visOpenMacrosDisabled + visOpenNoWorkspace)
' export to outimgpath
If Not ConvDoc.Pages(PageNum) Is Nothing Then
ConvDoc.Pages(PageNum).Export OutImgPath
Else
MsgBox "Invalid export page"
ConvertVisToImg = False
GoTo PROC_END
End If
' close it off
PROC_END:
On Error Resume Next
VisApp.Quit
Set VisApp = Nothing
Exit Function
PROC_ERR:
MsgBox Err.Description & vbCr & "Num:" & Err.Number
GoTo PROC_END
End Function
Function SplitCommandArg(ByRef Commands() As String) As Boolean
SplitCommandArg = True
'read through command and break it into an array delimited by space characters only when we're not inside double quotes
Dim InDblQts As Boolean
Dim CmdToSplit As String
CmdToSplit = TheCmd 'for debugging command line parser
'CmdToSplit = Command
Dim CharIdx As Integer
ReDim Commands(1 To 1)
For CharIdx = 1 To Len(CmdToSplit)
Dim CurrChar As String
CurrChar = Mid(CmdToSplit, CharIdx, 1)
If CurrChar = " " And Not InDblQts Then
'add another element to the commands array if InDblQts is false
If Commands(UBound(Commands)) <> "" Then ReDim Preserve Commands(LBound(Commands) To UBound(Commands) + 1)
ElseIf CurrChar = Chr(34) Then
'set InDblQts = true
If Not InDblQts Then InDblQts = True Else InDblQts = False
Else
Commands(UBound(Commands)) = Commands(UBound(Commands)) & CurrChar
End If
Next CharIdx
End Function
F# 2.0 script:
//Description:
// Generates images for all Visio diagrams in folder were run according to pages names
//Tools:
// Visio 2010 32bit is needed to open diagrams (I also installed VisioSDK32bit.exe on my Windows 7 64bit)
#r "C:/Program Files (x86)/Microsoft Visual Studio 10.0/Visual Studio Tools for Office/PIA/Office14/Microsoft.Office.Interop.Visio.dll"
open System
open System.IO
open Microsoft.Office.Interop.Visio
let visOpenRO = 2
let visOpenMinimized = 16
let visOpenHidden = 64
let visOpenMacrosDisabled = 128
let visOpenNoWorkspace = 256
let baseDir = Environment.CurrentDirectory;
let getAllDiagramFiles = Directory.GetFiles(baseDir,"*.vsd")
let drawImage fullPathToDiagramFile =
let diagrammingApplication = new ApplicationClass()
let flags = Convert.ToInt16(visOpenRO + visOpenMinimized + visOpenHidden + visOpenMacrosDisabled + visOpenNoWorkspace)
let document = diagrammingApplication.Documents.OpenEx(fullPathToDiagramFile,flags)
for page in document.Pages do
let imagePath = Path.Combine(baseDir, page.Name + ".png")
page.Export (imagePath)
document.Close()
diagrammingApplication.Quit()
let doItAll =
Array.iter drawImage getAllDiagramFiles
doItAll
You can try "Visio to image" converter
http://soft.postpdm.com/visio2image.html
Tested with MS Visio 2007 and 2010
There has to be a way to hook into Visio with COM and get it to save as image.
Why not try writing something yourself, then, if you know how to use COM stuff? After all, if you can't find anything already made to do it, and you know you can figure out how to do it yourself, why not write something to do it yourself?
EDIT: Elaborating a bit on what I stated in my comment: writing a script of some sort does seem to be your best option in this situation, and Python, at least, would be quite useful for that, using the comtypes library found here: http://starship.python.net/crew/theller/comtypes/ Of course, as I said, if you prefer to use a different scripting language, then you could try using that; the thing is, I've only really used COM with VBA and Python at this point (As an aside, Microsoft tends to refer to "Automation" these days rather than specifically referencing COM, I believe.) The nice thing about Python is that it's an interpreted language, and thus you just need a version of the interpreter for the different OSes you're using, with versions for Windows, OSX, Linux, Unix, etc. On the other hand, I doubt you can use COM on non-Windows systems without some sort of hack, so you may very well have to parse the data in the source files directly (and even though Visio's default formats appear to use some form of XML, it's probably one of those proprietary formats Microsoft seems to love).
If you haven't used Python before, the Python documentation has a good tutorial to get people started: http://docs.python.org/3.1/tutorial/index.html
And, of course, you'll want the Python interpreter itself: http://python.org/download/releases/3.1/ (Note that you may have to manually add the Python directory to the PATH environment variable after installation.)
When you write the script, you could probably have the syntax for running the script be something like "python visioexport.py <source/original file[ with path]>[ <new file[ with path]>]" (assuming the script file is in your Python directory), with the new file defaulting to a file of the same name and in the same folder/directory as the original (albeit with a different extension; in fact, if you wish, you could set it up to export to multiple formats, with the format defaulting to that of whatever default extension you choose and being specified by an alternate extension of you specify one in the file name. As well, you could likely set it up so that if you only have the new file name after the source file, no path specified, it'll save with that new file name to the source file's directory. And, of course, if you don't specify a path for the source file, just a file name, you could set it up to get the file from the current directory).
On the topic of file formats: it seems to me that converting to SVG might be the best thing to do, as it would be more space-efficient and would better reflect the original images' status as vectored images. On the other hand, the conversion from a Visio format to SVG is not perfect (or, at least, it wasn't in Visio 2003; I can't find a source of info similar to this one for Visio 2007), and as seen here, you may have to modify the resultant XML file (though that could be done using the script, after the file is exported, via parts of the Python standard library). If you don't mind the additional file size of bitmaps, and you'd rather not have to include additional code to fix resultant SVG files, then you probably should just go with a bitmap format such as PNG.

Detect if the contents of a folder have changed?

Conditions:
Windows 98 SE
WMI not available
I have code that looks like this, written using my steroidal wrapping of VBScript using MSScript.
do
a = files.collectfiles( "c:\userver", "" )
for i = 0 to ubound( a )
f = a(i)
if strings.endswith( f, ".usv" ) then
d = files.readfilee( f )
on error resume next
executeglobal d
nErr = err.number
sErr = err.description
on error goto 0
if nErr <> 0 then
trace "*** Error " & nErr & ", " & sErr
end if
files.deletefile f
end if
next
system.sleep 10
system.cooperate
loop
There's a lot of disk activity with that call to files.collectfiles. Is there some way of detecting a change in the contents of a folder without actually scanning the folder for files?
There is a sample which claims to work on all versions from Win95 up to at leas WinXP. Developed under Win98 with VB5. Using the (then? provided links to the docu below) undocumented SHChangeNotify* Functions.
SHChangeNotifyRegister: Receive Shell Change Notifications
SHChangeNotifyRegister Function
SHChangeNotifyDeregister Function
There is another solution using ReadDirectoryChangesW here:
VB6 WinAPI ReadDirectoryChangesW (check the 5th post from Yang Kok Wah)
Define "change in the contents of a folder".
If it means that a file was added, deleted, or renamed, then the modified timestamp of the folder is updated whenever such an event occurs.
If you're instead wanting to know when files are modified, then you'll need to read them.
That said, looking at what you're trying to do (scan a folder for new .usv files, and process them and delete them), then just keeping track of the timestamp on the folder and updating it right before you call collectfiles is best (note that the correct time to log is just BEFORE calling collectfiles, otherwise you run the risk of not waking up if a file gets added during the collectfiles call or immediately afterward).
You specifically asked for something in VB and running on win98 and I have no answer for this, but MS has a c/win32 example on how to achieve this on Windows2000+ with FindFirstChangeNotification. Another thing is that apparently "FileSystemWatcher" in .NET is not working/supported on Win98. What is my point? There maybe is no easy solution for this and you have to come up with something on your own.

Resources