I'm trying to make calls to an OCX we developed in house. The OCX is an interface to a FireWire network. Currently we use this OCX mostly for C# programs. It's several years old and fairly stable.
I have been able to access this OCX from VBScript, so I think the OCX is script ready.
I've tried the win32ole test scripts on Excel files and they work as described, so I'm confident Ruby and win32ole are operational.
I can see the class, the methods, and the arguments when I run soleb.rb.
I ran olegen and it created a proper looking class with all the methods.
It seems the object is created properly when I call it (at least no errors are reported).
When I call any of the methods using .invoke or ._invoke I get the same error message. This error is also the same if the method requires arguments or not.
test.rb:6:in 'invoke':method_name (or '_invoke':_invoke) (WIN32OLERuntimeError) OLE error code:0 in <Unknown> <No Description> HRESULT error code:0x8000ffff Catastrophic failure from test.rb:6
On Feb 28, 6:28 pm, Barry Walker <barr...@gmail.com> wrote:
> When I call any of the methods using .invoke or ._invoke I get the same > error message. This error is also the same if the method requires > arguments or not.
> test.rb:6:in 'invoke':method_name (or '_invoke':_invoke) > (WIN32OLERuntimeError) > OLE error code:0 in <Unknown> > <No Description> > HRESULT error code:0x8000ffff > Catastrophic failure from test.rb:6
> Can anyone point me toward the problem?
I'm pretty sure that HRESULT indicates a null pointer error. My guess is it's expecting an argument that you're not passing, or something like that. What is on line 6 of your script?
Jeff Cohen wrote: > What is on line 6 of your script?
Line 6 is the method call on the object after the object is created.
I noticed one other thing when browsing the differences between the class olegen created for my OCX and the class it created for excel.
There are no [IN,OUT,OPTION] tags in the comments of my class. Soleb doesn't show [IN,OUT,OPTION] tags either when I browse my OLE object. Are these tags necessary for proper operation?
If this approach is fail, try to use olegen and _invoke like as the following.
require 'win32ole' include WIN32OLE::VARIANT obj = WIN32OLE.new("Your.OCX")
# The second parameter is optional. obj._invoke(1, [10, nil], [VT_I2, VT_VARIANT])
And, I need more detail information to advise more effectively. Could you show me the test.rb and the result of the following script? (Before running script, please change "Your.OCX" and "your_method" to fit your OCX.)
require 'win32ole' obj = WIN32OLE.new("Your.OCX") m = obj.ole_method_help("your_method") p m.dispid m.params.each do |param| puts "-----" p param.ole_type p param.ole_type_detail p param.optional? end
Masaki Suketa wrote: > Hello, this may not be the answer your question...,
I'm just trying to make it work. Any method is fine.
require 'win32ole' qp = WIN32OLE.new("QPTnt.ocx")
gives the error qptest.rb:2:in `initialize': unknown OLE server: `QPTnt.ocx' (WIN32OLERuntimeError) HRESULT error code:0x800401f3 Invalid class string from qptest.rb:2:in `new' from qptest.rb:2
Soleb shows the PROGID of my QPTnt class is QPTNT.QPTntCtrl.1 So I try:
gives the error qptest.rb:3:in `method_missing': Version (WIN32OLERuntimeError) OLE error code:0 in <Unknown> <No Description> HRESULT error code:0x8000ffff Catastrophic failure from qptest.rb:3
But Version is a method shown in soleb.
> If this approach is fail, try to use olegen and _invoke like > as the following.
> require 'win32ole' > include WIN32OLE::VARIANT > obj = WIN32OLE.new("Your.OCX")
I tried, require 'win32ole' include WIN32OLE::VARIANT qp = WIN32OLE.new("QPTnt.OCX") s= qp.Version
gives ptest.rb:3:in `initialize': unknown OLE server: `QPTnt.OCX' (WIN32OLERuntimeError) HRESULT error code:0x800401f3 Invalid class string from qptest.rb:3:in `new' from qptest.rb:3
and require 'win32ole' include WIN32OLE::VARIANT qp = WIN32OLE.new("QPTNT.QPTntCtrl.1") s= qp.Version
gives qptest.rb:4:in `method_missing': Version (WIN32OLERuntimeError) OLE error code:0 in <Unknown> <No Description> HRESULT error code:0x8000ffff Catastrophic failure from qptest.rb:4
I tried another method, Activate2 with the same results.
When I run
require 'win32ole' obj = WIN32OLE.new("QPTNT.QPTntCtrl.1") m = obj.ole_method_help("Version") p m.dispid m.params.each do |param| puts "-----" p param.ole_type p param.ole_type_detail p param.optional? end
I only get one number on one line.
36
When I run it for the Activate2 (which requires one arguement) method I get:
55 ----- "I4" ["I4"] false
It was a year ago I ran the OCX with VBSript and I can't find the code. I just remember that it worked and that it was very cumbersome so I abandon it. As I recall I invoked QPTnt.ocx not QPTNT.QPTntCtrl.1.
> gives > qptest.rb:4:in `method_missing': Version (WIN32OLERuntimeError) > OLE error code:0 in <Unknown> > <No Description> > HRESULT error code:0x8000ffff > Catastrophic failure from qptest.rb:4
> I tried another method, Activate2 with the same results.
Sorry, I'm not sure, but this might be Win32OLE's limit.
> I only get one number on one line.
> 36
Thank you. I guess olegen worked fine, and created the expected script code. Perphaps the olegen created the script code like as the following. Is that right?
require 'win32ole' obj = WIN32OLE.new("QPTNT.QPTntCtrl.1") include WIN32OLE::VARIANT obj._invoke(36, [], []) # this invokes Version.
But unfortunately, I think you would get the same result even if you try above script.
> When I run it for the Activate2 (which requires one arguement) method I > get:
> 55 > ----- > "I4" > ["I4"] > false
Perphaps, I guess olegen created as the following code.
obj._invoke(55, [arg], [VT_I4])
And [IN, OUT, OPTION] tags are not needed in this case.
> It was a year ago I ran the OCX with VBSript and I can't find the code. > I just remember that it worked and that it was very cumbersome so I > abandon it. As I recall I invoked QPTnt.ocx not QPTNT.QPTntCtrl.1.
BTW, Does the following VBScript work? Set obj = CreateObject("QPTnt.ocx") obj.Version or Set obj = CreateObject("QPTNT.QPTntCtrl.1") obj.Version
If it would not work, Win32OLE script does not work.
Masaki Suketa wrote: > BTW, Does the following VBScript work? > Set obj = CreateObject("QPTnt.ocx") > obj.Version > or > Set obj = CreateObject("QPTNT.QPTntCtrl.1") > obj.Version
> If it would not work, Win32OLE script does not work.
You're leading me toward the problem. That VBScript code does not work. It actually gives the same error statement that win32ole gives!
I went back and tried to re-create my VBScript code. I remembered I used "ActiveX Control Pad" to test the VBScript method last year.
This is code (embeded in and html doc and mostly generated by ActiveX control pad) that works with my ocx.
<HTML><HEAD><TITLE>OCX test</TITLE> <SCRIPT LANGUAGE="VBScript"> Sub window_onLoad() document.frmEx.out1.value=QPTnt1.Version End Sub </SCRIPT> </HEAD><BODY>
Any chance that the CLSID that works (884BD6BB-E4BA-4EEA-A632- D7A92541602F) is not registered correctly? Maybe QPTNT.QPTntCtrl.1 is not the right ProgID for that particular CLSID? I think you'll have to check the registry to be sure.
> "First, a little background: ActiveX controls are normally persisted to/from > some type of permanent storage, and they do this by implementing one or more > IPersist* interfaces. Containers are supposed to call one of the IPersist > methods to initialize or load the control upon creation.
He was able to make a patch to our .ocx and it seems to work well now.
It also seems possible that this issue could be fixed inside Win32OLE.
> > "First, a little background: ActiveX controls are normally persisted to/from > > some type of permanent storage, and they do this by implementing one or more > > IPersist* interfaces. Containers are supposed to call one of the IPersist > > methods to initialize or load the control upon creation.
> He was able to make a patch to our .ocx and it seems to work well now.
> It also seems possible that this issue could be fixed inside Win32OLE.
Thank you for your information. I have addedWIN32OLE#ole_activex_initialize to ruby trunk. The method invokes InitNew method of IPersistMemory interface. I have checked that the method works fine with very small simple MFC ActiveX control which has only AboutBox method.