Invoke a COM Method from a dll - dll

The question is this: i've been inspecting kaspersky gadget and found out it uses a COM object as i can see declared in the gadget's main html file, so i looked in the registry by the CLSID and got to the "gadget.dll" located in the kaspersky instalation folder.
Mi interest is to invoke specific kaspersky's app tab just the same way they do. Examining the .js files on the gadget's folder i could see the syntax of the method i would need to use which is "OpenWindow(WindowID)" and the WindowID's are also specified in another file.
I've been trying this from a simple VisualBasic Script:
Set kavCOM = WScript.CreateObject("KISGadgetCOM.COMClass.1")
kavCOM.OpenWindow(1)
that should invoke the Main Window, also tried a AutoHotKey Script:
^!k::
{
kavCOM := ComObjCreate("{ED6E691B-E662-4aae-AECC-705C9B014C75}")
kavCOM.OpenWindow(1)
}
they both result in the error: 80004004 (Operation aborted) at the line with "kavCOM.OpenWindow(1)
what's wrong?

Ok, the problem was the Object instantiation delay, i solved it by adding
WScript.Sleep 1000
just before calling the "OpenWindow" method.
My final(finer) solution so that it doesn't wait more than needed:
Dim kavCOM, Cnt
Cnt = 0
Set kavCOM = CreateObject("KISGadgetCOM.COMClass.1")
On Error Resume Next
Do
Cnt = Cnt + 1
kavCOM.OpenWindow(1)
If Err = 0 Then
Exit Do
Else
Err.Clear
End If
WScript.Sleep 10
Loop
On Error Goto 0
MsgBox "It took " & 10*Cnt & " miliseconds."
Set kavCOM = Nothing

Related

How to Link a VBA code with opened ETABS OAPI?

a project on ETABS 2015 is open on my PC. I want to do some change and process on it by a VBA code automatically. but all the sample code that I found was like this:
Public Sub Example()
Dim SapModel As cSapModel
Dim EtabsObject As cOAPI
Dim FileName as String
Dim ret As Integer = -1
'create ETABS object
EtabsObject = CreateObject("CSI.ETABS.API.ETABSObject")
'start ETABS application
ret = EtabsObject.ApplicationStart()
'create SapModel object
SapModel = EtabsObject.SapModel
'initialize model
ret = SapModel.InitializeNewModel()
'open an existing file - If no file exists, run the Save example first.
FileName = "c:\CSI_API_temp\example.edb"
ret = SapModel.File.OpenFile(FileName)
This code just open a new ETABS in my PC. but my ETABS project is already running and I want to connect to it but I don't know how!
please help me.
Your sample code is basically and typically the one needed to open ETABS ITSELF and to initialize a new model,
ETABSObject = CreateObject("CSI.ETABS.API.ETABSObject") followed by the invocation of ApplicationStart method are the direct means for that.
If you refer to the ETABS API documentation file in the installation destination (e.g "C:\Program Files\Computers and Structures\ETABS 2015\CSi API ETABS 2015.chm" ) Under the section "Release Notes>Attaching to a manually started instance of ETABS", or if you see the same section from the link
http://docs.csiamerica.com/help-files/etabs-api-2015/html/3ceb8889-9028-4de3-9c87-69a12055ade7.htm
you'll find code (in VB.Net) close to what you aim to, but it will not work with vba, so, what you will simply do is this
'The ret variable, just for method invocation convenience
Dim ret As Integer
'Create an instance of the currently opened Program
Dim myETABSObject As ETABS2015.cOAPI
Set myETABSObject = GetObject(, "CSI.ETABS.API.ETABSObject")
'Create an instance to the model
Dim myETABSModel As ETABS2015.cSapModel
Set myETABSModel = myETABSObject.SapModel
'Now, after the "reference instances" are obtained
'Initialize the model (using the model's instance of course)
ret = myETABSModel.InitializeNewModel() 'default units in kip_in_F
'Set the model templete, which is "Blank"
ret = myETABSModel.File.NewBlank()
And You can normally proceed in your coding.
Note: 1- GetObject(CSI.ETABS.API.ETABSObject) method will raise an error if ETABS is not opened.
2- you still can use GetObject even if ETABS is not opened and if you want to open it from windows shell (like using command prompt to open programs instead of double clicking on their respective icons), but this of course needs some Error Handling and the use of "Windows Script Host Object Model".
3- The examples in the documentation (under the documented methods and properties) may not be complete in terms of initiating input data, in cases like this they are just to create an impression of how to use their respective methods and properties.
The code below does as you asked. It uses VBA to connect to a currently running instance of ETABS. Please note if you're running multiple instances of ETABS it may not attach to the one you want.
You'll need to add a reference to 'ETABSv1.tlb' to your VBA project. If you're using VBA Editor for Excel, on the Tools menu select References, then click Browse then add C:\Program Files\Computers and Structures\ETABS 19\ETABSv1.tlb
Sub Main()
'create API helper object
Dim myHelper As ETABSv1.cHelper
Set myHelper = New ETABSv1.Helper
'dimension the ETABS Object as cOAPI type
Dim myETABSObject As ETABSv1.cOAPI
Set myETABSObject = Nothing
'attach to a running instance of ETABS
'get the active ETABS object
Set myETABSObject = myHelper.GetObject("CSI.ETABS.API.ETABSObject")
'get a reference to cSapModel to access all API classes and functions
Dim mySapModel As ETABSv1.cSapModel
Set mySapModel = myETABSObject.SapModel
' DO YOUR WORK BELOW.
MsgBox "Do your work here."
' DO YOUR WORK ABOVE.
'clean up variables
Set mySapModel = Nothing
Set myETABSObject = Nothing
Exit Sub
ErrHandler:
MsgBox "Cannot run API script: " & Err.Description
End Sub
ETABS comes with API documentation that you can find in the installation folder. On my machine it is here: C:\Program Files\Computers and Structures\ETABS 19\CSA API ETABS v1.chm

while trying to read a particular text from notepad am facing Run Error :- Object doesnt support this property or method

set objFileToRead = CreatObject("Scripting.FileSystemObject")
Set strReadline=objFileToRead.OpenTextFile(strpath,1)
Do While strReadline.AtEndofStream<>True
strRecordName = Trim(Mid(strReadLine,52,15)
AT 4th LINE FACING ERROR in hp-UFT Run Error :- Object doesn't support this property or method
Please paste the code without syntax error .Your code should be like this
strpath="C:\Users\561320\Documents\Saikrishna\caffeine\readme.txt"
set objFileToRead = CreateObject("Scripting.FileSystemObject")
Set strReadline=objFileToRead.OpenTextFile(strpath,1)
Do While strReadline.AtEndofStream<>True
strRecordName = Trim(Mid(strReadLine.Readline,52,15))
Wscript.echo strRecordName
Loop

Object Reference Error VB.NET

I keep getting an error:
System.NullReferenceException: Object reference not set to an instance
of an object.
Everytime I run the application outside the IDE, but for some magical reason, it works fine inside the IDE. I am definitely sure the error is caused by this code as the app ran smoothly when I removed it:
Public Function GetCommonFolder() As String
On Error GoTo ErrH
Dim winPath As String = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
Dim commonfolderpath As String
commonfolderpath = Replace(winPath & "\MyApp Data", "\\", "\")
If My.Computer.FileSystem.DirectoryExists(commonfolderpath) = False Then
System.IO.Directory.CreateDirectory(commonfolderpath)
End If
GetCommonFolder = commonfolderpath
Exit Function
ErrH:
GetCommonFolder = ""
Msgbox("Error retrieving common folder")
End Function
Does anyone here know what is causing this annoying problem?
It seems like the user that you run the program on outside the IDE doesn't have access to the common application data folder. Try executing it by "Run as administrator". Are you running on Windows Vista or newer? Maybe you have to require UAC elevation?

COM Call Fails with Member Not Found

I have an application (for which I don't have control of the source), and it exposes a COM interface that works fine from VBA, for example:
Sub test()
Set myApp = CreateObject("MyApp.Application")
val1 = myApp.SubPart.Size
MsgBox CStr(val1)
myApp.SubPart.IncreaseSize
End Sub
This works perfectly. When I do the equivalent in AutoHotkey-L:
myApp := ComObjCreate("V6.Application")
val1 := myApp.SubPart.Size
MsgBox %val1%
myApp.SubPart.IncreaseSize
The message box fires, and gives me the correct value. The last line halts with an error:
0x80020003 - Member not found
Specifically: IncreaseSize
What can I do to get this to function the same in AHK?
For anyone else stuck with this, I solved it by first changing to use the 32-bit ANSI AutoHotkey executable. For me, this is at:
C:\Program Files\AutoHotkey\AutoHotkeyA32.exe
I then changed any COM method calls to be embedded into a ScriptControl call:
myApp := ComObjCreate("MyApp.Application")
val1 := myApp.SubPart.Size
MsgBox %val1%
SC := ComObjCreate("ScriptControl")
SC.Language := "VBScript"
SC.Timeout := -1
code =
(
Set MyApp = CreateObject("MyApp.Application")
MyApp.SubPart.IncreaseSize
)
sc.ExecuteStatement(code)
Of course, the Size read could be moved into the VB code block too.

Is it possible the Serialization in .vbs script?

I have combined some of my codes into the below:
Option Explicit
Dim oShell : Set oShell = WScript.CreateObject ("WScript.Shell")
Dim FSO : set FSO = CreateObject("Scripting.FileSystemObject")
Dim StartTime,Elapsed
'msgBox(oShell.CurrentDirectory)
'MsgBox(FSO.GetFile(Wscript.ScriptFullName).ParentFolder )
oShell.CurrentDirectory = FSO.GetFile(Wscript.ScriptFullName).ParentFolder
StartTime = Timer
oShell.run "ParentChildLinkFinal.vbs", 1, True
oShell.run "Parent_Child_Merge_final.vbs", 1, True
oShell.run "CycleTime.vbs", 1, True
oShell.run "Baddata.vbs", 1, True
oShell.run "Matrixrefresh.vbs", 1, True
Elapsed = Timer - StartTime
MsgBox("Total time taken to finish this task:" & Elapsed & "in Seconds")
Now one concern here is- Suppose an error occurs in the any of the CycleTime.vbs file,but the control then going to the next Baddata.vbs file,without killing the Main.vbs file.So how to handle this,If error occurs stop the main.vbs there itself or let the execution to continue.
As Per Daniel
"IF NOT oShell.run( "CycleTime.vbs", 1, True) = 0 then Wscript.Quit would replace the line you are currently using to call "CycleTime.vbs" within Main.vbs
IF oShell.run( "CycleTime.vbs", 1, True) = 99 then Wscript.Quit Would also replace the line you are currently using to call "CycleTime.vbs".
The difference is that you didn't specify how CycleTime.vbs could error out.
If it could fail in such a way that it has a run-time error and simply stops executing, you would want to use the 1st option.
If an error occurs, that you trap with error trapping, you can quit with a code. Like WScript.Quit 99. Then you could check to see if the script ended with that code via the 2nd version that I provided to you.
It really comes down to how you want to handle the failure of your script that you are calling."
WHY SUCH APPROACH
#Daniel True helps the script to suspend its execution until the current .vbs finished. But I am looking for any special value if I can return a special value from each of the .vbs by which main.vbs will get to know that its current .vbs completed successfuly,let's start the next .vbs . But yes iff only success then the next would start. Currently I am seing that suppose an error occurs from any of the .vbs,then as soon as i closed the error window next script started to run. So I am trying atleast thinking iff any success full communication can be sent to the main.vbs. So is it possible?
To expand on what Hiten indicated, you would need to do some checking in your Main.vbs for the return value from your called .vbs files. You do this by utilizing the return value of Run.
For example:
Instead of doing oShell.run "CycleTime.vbs", 1, True do
IF NOT oShell.run( "CycleTime.vbs", 1, True) = 0 then Wscript.Quit
This will exit your current thread of execution if CycleTime.vbs halted due to a run-time error (the call to run the script will return false).
Now if you are able to handle errors gracefully within CycleTime.vbs, you can send a message when you close it by using Wscript.Quit code as explained in the other answer.
So if you want to handle errors gracefully in CycleTime.vbs, you can still indicate an error occurred. Simply check for the return code in your main script with something like this:
IF oShell.run( "CycleTime.vbs", 1, True) = 99 then Wscript.Quit
This way your script will end if CycleTime.vbs ends with code 99. This would happen if within CycleTime.vbs it had code like this:
If err then
'Exit script with code 99 to indicate an error occurred.
Wscript.Quit 99
End if
Use vbscript error handling in main.vbs to stop the code and exit the main.vbs
for more detial click this link:
VBScript -- Using error handling
Sample:
On Error Resume myErrCatch
'Do step 1
'Do step 2
'Do step 3
myErrCatch:
'log error
Resume Next
Create an Exist code from .VBS then exit Main.vbs
DIM returnValue
returnValue = 99
WScript.Quit(returnValue)