jruby-win32ole 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/Gemfile +4 -0
- data/README +0 -0
- data/Rakefile +8 -0
- data/VERSION +1 -0
- data/bin/make_data.rb +12 -0
- data/bin/sample +11 -0
- data/build.xml +74 -0
- data/jruby-win32ole.gemspec +21 -0
- data/lib/jruby-win32ole.rb +39 -0
- data/lib/jruby-win32ole/version.rb +5 -0
- data/lib/racob-x64.dll +0 -0
- data/lib/racob-x86.dll +0 -0
- data/lib/racob.jar +0 -0
- data/lib/win32ole/utils.rb +230 -0
- data/lib/win32ole/win32ole.jar +0 -0
- data/lib/win32ole/win32ole_error.rb +13 -0
- data/lib/win32ole/win32ole_event.rb +38 -0
- data/lib/win32ole/win32ole_method.rb +135 -0
- data/lib/win32ole/win32ole_param.rb +45 -0
- data/lib/win32ole/win32ole_ruby.rb +115 -0
- data/lib/win32ole/win32ole_type.rb +148 -0
- data/lib/win32ole/win32ole_typelib.rb +76 -0
- data/lib/win32ole/win32ole_variable.rb +41 -0
- data/lib/win32ole/win32ole_variant.rb +52 -0
- data/nbproject/build-impl.xml +800 -0
- data/nbproject/genfiles.properties +8 -0
- data/nbproject/private/config.properties +0 -0
- data/nbproject/private/private.properties +8 -0
- data/nbproject/private/private.xml +4 -0
- data/nbproject/project.properties +71 -0
- data/nbproject/project.xml +14 -0
- data/samples/browser_connect.rb +10 -0
- data/samples/const_load.rb +10 -0
- data/samples/dir_enum_bench.rb +24 -0
- data/samples/dispatch_bench.rb +44 -0
- data/samples/file_system_object.rb +7 -0
- data/samples/fs.rb +50 -0
- data/samples/ie_plus_events.rb +45 -0
- data/samples/ie_simple.rb +20 -0
- data/samples/ie_simple_clsid.rb +13 -0
- data/samples/sbem.rb +11 -0
- data/samples/small_enum_bench.rb +126 -0
- data/src/org/jruby/ext/win32ole/RubyInvocationProxy.java +34 -0
- data/src/org/jruby/ext/win32ole/RubyWIN32OLE.java +278 -0
- data/src/win32ole/Win32oleService.java +29 -0
- metadata +113 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
class WIN32OLE_EVENT
|
2
|
+
def initialize(ole, event_name=nil)
|
3
|
+
@event_handlers = {}
|
4
|
+
|
5
|
+
raise TypeError.new("1st parameter must be WIN32OLE object") if !ole.kind_of? WIN32OLE
|
6
|
+
|
7
|
+
if event_name.nil? # Default event name
|
8
|
+
# TODO: get default event
|
9
|
+
end
|
10
|
+
|
11
|
+
dispatch = ole.dispatch
|
12
|
+
DispatchEvents.new dispatch, RubyInvocationProxy.new(self), dispatch.program_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def on_event(name=nil, &block)
|
16
|
+
if name
|
17
|
+
@event_handlers[name.to_s] = block
|
18
|
+
else
|
19
|
+
@default_handler = block
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def method_missing(name, *args)
|
24
|
+
name = name.to_s
|
25
|
+
handler = @event_handlers[name]
|
26
|
+
if handler
|
27
|
+
handler.call *args
|
28
|
+
elsif @default_handler
|
29
|
+
@default_handler.call name, *args
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Almost noop this. We don't because it get CPU hot when people put this
|
34
|
+
# in a hot loop!
|
35
|
+
def self.message_loop
|
36
|
+
DispatchEvents.message_loop
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
class WIN32OLE_METHOD
|
2
|
+
attr_accessor :oletype, :typeinfo
|
3
|
+
|
4
|
+
def initialize(*args)
|
5
|
+
# TODO: 2-arg missing currently unuised oletype ivar
|
6
|
+
if args.length == 6 # Internal initializer
|
7
|
+
@oletype, @typeinfo, @owner_typeinfo, @desc, @docs, @index = *args
|
8
|
+
elsif args.length == 2 # Normal constructor
|
9
|
+
@oletype, name = WIN32OLE_TYPEValue(args[0]), SafeStringValue(args[1])
|
10
|
+
all_methods(@oletype.typeinfo) do |ti, oti, desc, docs, index|
|
11
|
+
if docs.name.downcase == name.downcase
|
12
|
+
@typeinfo, @owner_typeinfo, @desc, @docs, @index = ti, oti, desc, docs, index
|
13
|
+
break;
|
14
|
+
end
|
15
|
+
end
|
16
|
+
raise WIN32OLERuntimeError.new "not found: #{name}" if !@typeinfo
|
17
|
+
else # Error
|
18
|
+
raise ArgumentError.new("2 for #{args.length}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def dispid
|
23
|
+
@desc.memid
|
24
|
+
end
|
25
|
+
|
26
|
+
def event?
|
27
|
+
return false if @owner_typeinfo.typekind != TypeInfo::TYPEKIND_COCLASS
|
28
|
+
|
29
|
+
@owner_typeinfo.impl_types_count.times do |i|
|
30
|
+
begin
|
31
|
+
flags = @owner_typeinfo.get_impl_type_flags(i)
|
32
|
+
|
33
|
+
if flags & TypeInfo::IMPLTYPEFLAG_FSOURCE
|
34
|
+
href = @owner_typeinfo.get_ref_type_of_impl_type(i)
|
35
|
+
ref_typeinfo = @owner_typeinfo.get_ref_type_info(href)
|
36
|
+
func_desc = ref_typeinfo.func_desc(@index)
|
37
|
+
documentation = ref_typeinfo.documentation(func_desc.memid)
|
38
|
+
|
39
|
+
return true if documentation.name == name
|
40
|
+
end
|
41
|
+
rescue ComFailException => e
|
42
|
+
end
|
43
|
+
end
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
def event_interface
|
48
|
+
return nil unless event?
|
49
|
+
|
50
|
+
typelib = @typeinfo.containing_type_lib
|
51
|
+
documentation = typelib.documentation(typelib.index)
|
52
|
+
documentation.name
|
53
|
+
end
|
54
|
+
|
55
|
+
def helpcontext
|
56
|
+
@docs.help_context
|
57
|
+
end
|
58
|
+
|
59
|
+
def helpstring
|
60
|
+
@docs.doc_string
|
61
|
+
end
|
62
|
+
|
63
|
+
def helpfile
|
64
|
+
@docs.help_file
|
65
|
+
end
|
66
|
+
|
67
|
+
def invkind
|
68
|
+
@desc.invkind
|
69
|
+
end
|
70
|
+
|
71
|
+
def invoke_kind
|
72
|
+
invkind = @desc.invkind
|
73
|
+
if invkind & Dispatch::Get && invkind & Dispatch::Put
|
74
|
+
return "PROPERTY"
|
75
|
+
elsif invkind & Dispatch::Get
|
76
|
+
return "PROPERTYGET"
|
77
|
+
elsif invkind & Dispatch::Put
|
78
|
+
return "PROPERTYPUT"
|
79
|
+
elsif invkind & Dispatch::PutRef
|
80
|
+
return "PROPERTYPUTREF"
|
81
|
+
elsif invkind & Dispatch::Method
|
82
|
+
return "FUNC"
|
83
|
+
else
|
84
|
+
return "UNKOWN"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def name
|
89
|
+
@docs.name
|
90
|
+
end
|
91
|
+
alias :to_s :name
|
92
|
+
|
93
|
+
def offset_vtbl
|
94
|
+
@desc.vtable_offset
|
95
|
+
end
|
96
|
+
|
97
|
+
def params
|
98
|
+
arr = []
|
99
|
+
@desc.parameters.to_a.each_with_index do |param, i|
|
100
|
+
arr << WIN32OLE_PARAM.new(self, i, param)
|
101
|
+
end
|
102
|
+
arr
|
103
|
+
end
|
104
|
+
|
105
|
+
def return_type
|
106
|
+
typedesc_value(@desc.return_type.vt)
|
107
|
+
end
|
108
|
+
|
109
|
+
def return_type_detail
|
110
|
+
typedesc_value(@desc.return_type.vt, [])
|
111
|
+
end
|
112
|
+
|
113
|
+
def return_vtype
|
114
|
+
@desc.return_type.vt
|
115
|
+
end
|
116
|
+
|
117
|
+
def size_opt_params
|
118
|
+
@desc.opt_params_count
|
119
|
+
end
|
120
|
+
|
121
|
+
def size_params
|
122
|
+
@desc.params_count
|
123
|
+
end
|
124
|
+
|
125
|
+
def visible?
|
126
|
+
(@desc.flags & (FuncDesc::FUNCFLAG_FRESTRICTED | FuncDesc::FUNCFLAG_FHIDDEN |
|
127
|
+
FuncDesc::FUNCFLAG_FNONBROWSABLE)) == 0
|
128
|
+
end
|
129
|
+
|
130
|
+
def inspect
|
131
|
+
name
|
132
|
+
end
|
133
|
+
|
134
|
+
include WIN32OLE::Utils
|
135
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class WIN32OLE_PARAM
|
2
|
+
attr_accessor :name
|
3
|
+
|
4
|
+
def initialize(method, index, param_info=nil)
|
5
|
+
raise TypeError.new("1st parameter must be WIN32OLE object") if !method.kind_of? WIN32OLE_METHOD
|
6
|
+
|
7
|
+
@method, @index, @param = method, index, param_info
|
8
|
+
end
|
9
|
+
|
10
|
+
def default
|
11
|
+
@param.is_default_value ? RubyWIN32OLE.from_variant(JRuby.runtime, @param.get_default_value) : nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def input?
|
15
|
+
@param.is_in
|
16
|
+
end
|
17
|
+
|
18
|
+
def name
|
19
|
+
@param.name
|
20
|
+
end
|
21
|
+
alias :to_s :name
|
22
|
+
alias :inspect :name
|
23
|
+
|
24
|
+
def ole_type
|
25
|
+
typedesc_value(@param.vt)
|
26
|
+
end
|
27
|
+
|
28
|
+
def ole_type_detail
|
29
|
+
typedesc_value(@param.vt, [])
|
30
|
+
end
|
31
|
+
|
32
|
+
def output?
|
33
|
+
@param.is_out
|
34
|
+
end
|
35
|
+
|
36
|
+
def optional?
|
37
|
+
@param.is_optional
|
38
|
+
end
|
39
|
+
|
40
|
+
def retval?
|
41
|
+
@param.is_return_value
|
42
|
+
end
|
43
|
+
|
44
|
+
include WIN32OLE::Utils
|
45
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'win32ole/utils'
|
2
|
+
require 'jruby'
|
3
|
+
|
4
|
+
# Shorthand vocabulary:
|
5
|
+
# ti, oti - typeinfo or owner_typeinfo
|
6
|
+
|
7
|
+
class WIN32OLE
|
8
|
+
CP_ACP = 0
|
9
|
+
CP_OEMCP = 1
|
10
|
+
CP_MACCP = 2
|
11
|
+
CP_THREAD_ACP = 3
|
12
|
+
CP_SYMBOL = 42
|
13
|
+
CP_UTF7 = 65000
|
14
|
+
CP_UTF8 = 65001
|
15
|
+
|
16
|
+
def ole_method(name)
|
17
|
+
all_methods(typeinfo_from_ole) do |*args|
|
18
|
+
return WIN32OLE_METHOD.new(nil, *args) if name == args[3].name
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
alias :ole_method_help :ole_method
|
23
|
+
|
24
|
+
def ole_methods
|
25
|
+
members = []
|
26
|
+
all_methods(typeinfo_from_ole) do |*args|
|
27
|
+
members << WIN32OLE_METHOD.new(nil, *args)
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
members
|
31
|
+
end
|
32
|
+
|
33
|
+
def ole_func_methods
|
34
|
+
methods_with_flag(Dispatch::Method)
|
35
|
+
end
|
36
|
+
|
37
|
+
def ole_get_methods
|
38
|
+
methods_with_flag(Dispatch::Get)
|
39
|
+
end
|
40
|
+
|
41
|
+
def ole_put_methods
|
42
|
+
methods_with_flag(Dispatch::Put|Dispatch::PutRef)
|
43
|
+
end
|
44
|
+
|
45
|
+
def ole_type
|
46
|
+
typelib = type_info.containing_type_lib
|
47
|
+
docs = typelib.documentation(typelib.index)
|
48
|
+
WIN32OLE_TYPE.new typelib, type_info, docs
|
49
|
+
end
|
50
|
+
alias :ole_obj_help :ole_type
|
51
|
+
|
52
|
+
def ole_typelib
|
53
|
+
typelib = type_info.containing_type_lib
|
54
|
+
WIN32OLE_TYPELIB.new typelib, nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def type_info
|
58
|
+
dispatch.type_info
|
59
|
+
end
|
60
|
+
|
61
|
+
class << self
|
62
|
+
def codepage
|
63
|
+
@@codepage ||= CP_ACP
|
64
|
+
end
|
65
|
+
|
66
|
+
def codepage=(new_codepage)
|
67
|
+
@@codepage = new_codepage
|
68
|
+
end
|
69
|
+
|
70
|
+
def connect(id)
|
71
|
+
WIN32OLE.new to_progid(id)
|
72
|
+
end
|
73
|
+
|
74
|
+
def const_load(ole, a_class=WIN32OLE)
|
75
|
+
constants = {}
|
76
|
+
ole.type_info.containing_type_lib.type_info.to_a.each do |info|
|
77
|
+
info.vars_count.times do |i|
|
78
|
+
var_desc = info.get_var_desc(i)
|
79
|
+
# TODO: Missing some additional flag checks to limit no. of constants
|
80
|
+
if var_desc.constant
|
81
|
+
name = first_var_name(info, var_desc)
|
82
|
+
name = name[0].chr.upcase + name[1..-1] if name
|
83
|
+
if constant?(name)
|
84
|
+
a_class.const_set name, RubyWIN32OLE.from_variant(JRuby.runtime, var_desc.constant)
|
85
|
+
else # vars which don't start [A-Z]?
|
86
|
+
constants[name] = var_desc.constant
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
a_class.const_set 'CONSTANTS', constants
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_progid(id)
|
96
|
+
id =~ /^{(.*)}/ ? "clsid:#{$1}" : id
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def constant?(name)
|
102
|
+
name =~ /^[A-Z]/
|
103
|
+
end
|
104
|
+
|
105
|
+
def first_var_name(type_info, var_desc)
|
106
|
+
type_info.get_names(var_desc.memid)[0]
|
107
|
+
rescue
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
include WIN32OLE::Utils
|
115
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
class WIN32OLE_TYPE
|
2
|
+
attr_reader :typeinfo
|
3
|
+
|
4
|
+
def initialize(*args)
|
5
|
+
case args.length
|
6
|
+
when 2 then
|
7
|
+
typelib_name, olename = SafeStringValue(args[0]), SafeStringValue(args[1])
|
8
|
+
@typelib = WIN32OLE_TYPELIB.new(typelib_name) # Internal call
|
9
|
+
find_all_typeinfo(@typelib.typelib) do |info, docs|
|
10
|
+
if (docs.name == olename)
|
11
|
+
@typeinfo, @docs = info, docs
|
12
|
+
break
|
13
|
+
end
|
14
|
+
end
|
15
|
+
raise WIN32OLERuntimeError.new("not found `#{olename}` in `#{typelib_name}") unless @typeinfo
|
16
|
+
when 3 then
|
17
|
+
@typelib, @typeinfo, @docs = *args
|
18
|
+
else
|
19
|
+
raise ArgumentError.new("wrong number of arguments (#{args.length} for 2)")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def guid
|
24
|
+
@typeinfo.guid
|
25
|
+
end
|
26
|
+
|
27
|
+
def helpcontext
|
28
|
+
@docs.help_context
|
29
|
+
end
|
30
|
+
|
31
|
+
def helpstring
|
32
|
+
@docs.doc_string
|
33
|
+
end
|
34
|
+
|
35
|
+
def helpfile
|
36
|
+
@docs.help_file
|
37
|
+
end
|
38
|
+
|
39
|
+
def name
|
40
|
+
@docs.name
|
41
|
+
end
|
42
|
+
|
43
|
+
def major_version
|
44
|
+
@typeinfo.major_version
|
45
|
+
end
|
46
|
+
|
47
|
+
def minor_version
|
48
|
+
@typeinfo.minor_version
|
49
|
+
end
|
50
|
+
|
51
|
+
def ole_methods
|
52
|
+
members = []
|
53
|
+
all_methods(@typeinfo) do |ti, oti, desc, docs, index|
|
54
|
+
members << WIN32OLE_METHOD.new(self, ti, oti, desc, docs, index)
|
55
|
+
nil
|
56
|
+
end
|
57
|
+
members
|
58
|
+
end
|
59
|
+
|
60
|
+
def ole_type
|
61
|
+
case typekind
|
62
|
+
when TypeInfo::TYPEKIND_ENUM then
|
63
|
+
"Enum"
|
64
|
+
when TypeInfo::TYPEKIND_RECORD then
|
65
|
+
"Record"
|
66
|
+
when TypeInfo::TYPEKIND_MODULE then
|
67
|
+
"Module"
|
68
|
+
when TypeInfo::TYPEKIND_INTERFACE then
|
69
|
+
"Interface"
|
70
|
+
when TypeInfo::TYPEKIND_DISPATCH then
|
71
|
+
"Dispatch"
|
72
|
+
when TypeInfo::TYPEKIND_COCLASS then
|
73
|
+
"Class"
|
74
|
+
when TypeInfo::TYPEKIND_ALIAS then
|
75
|
+
"Alias"
|
76
|
+
when TypeInfo::TYPEKIND_UNION then
|
77
|
+
"Union"
|
78
|
+
when TypeInfo::TYPEKIND_MAX then
|
79
|
+
"Max"
|
80
|
+
else
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def progid
|
86
|
+
@typeinfo.progid
|
87
|
+
end
|
88
|
+
|
89
|
+
def src_type
|
90
|
+
return nil if @typeinfo.typekind != TypeInfo::TYPEKIND_ALIAS
|
91
|
+
|
92
|
+
typedesc_value @typeinfo.alias_vt
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_s
|
96
|
+
name
|
97
|
+
end
|
98
|
+
|
99
|
+
def variables
|
100
|
+
variables = []
|
101
|
+
all_vars(@typeinfo) do |desc, name|
|
102
|
+
variables << WIN32OLE_VARIABLE.new(self, desc, name)
|
103
|
+
end
|
104
|
+
variables
|
105
|
+
end
|
106
|
+
|
107
|
+
def visible?
|
108
|
+
@typeinfo.flags & (TypeInfo::TYPEFLAG_FHIDDEN | TypeInfo::TYPEFLAG_FRESTRICTED) == 0
|
109
|
+
end
|
110
|
+
|
111
|
+
def typekind
|
112
|
+
@typeinfo.typekind
|
113
|
+
end
|
114
|
+
|
115
|
+
class << self
|
116
|
+
# This is obsolete, but easy to emulate
|
117
|
+
def typelibs
|
118
|
+
WIN32OLE_TYPELIB.typelibs.collect {|t| t.name }
|
119
|
+
end
|
120
|
+
|
121
|
+
def progids
|
122
|
+
array = []
|
123
|
+
Win32::Registry::HKEY_CLASSES_ROOT.open('CLSID') do |reg|
|
124
|
+
reg.each_key do |clsid, wtime|
|
125
|
+
reg.open(clsid) do |clsid_reg|
|
126
|
+
clsid_reg.each_key do |key, wtime|
|
127
|
+
name = nil
|
128
|
+
if key == "ProgID"
|
129
|
+
clsid_reg.open(key) {|key_reg| name = key_reg.read(nil)[1] }
|
130
|
+
end
|
131
|
+
if !name && key == "VersionIndependentProgID"
|
132
|
+
clsid_reg.open(key) {|key_reg| name = key_reg.read(nil)[1] }
|
133
|
+
end
|
134
|
+
array << name if name
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
array
|
140
|
+
end
|
141
|
+
|
142
|
+
def ole_classes(tlib)
|
143
|
+
WIN32OLE_TYPELIB.ole_classes(tlib)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
include WIN32OLE::Utils
|
148
|
+
end
|