jruby-win32ole 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +4 -0
  3. data/README +0 -0
  4. data/Rakefile +8 -0
  5. data/VERSION +1 -0
  6. data/bin/make_data.rb +12 -0
  7. data/bin/sample +11 -0
  8. data/build.xml +74 -0
  9. data/jruby-win32ole.gemspec +21 -0
  10. data/lib/jruby-win32ole.rb +39 -0
  11. data/lib/jruby-win32ole/version.rb +5 -0
  12. data/lib/racob-x64.dll +0 -0
  13. data/lib/racob-x86.dll +0 -0
  14. data/lib/racob.jar +0 -0
  15. data/lib/win32ole/utils.rb +230 -0
  16. data/lib/win32ole/win32ole.jar +0 -0
  17. data/lib/win32ole/win32ole_error.rb +13 -0
  18. data/lib/win32ole/win32ole_event.rb +38 -0
  19. data/lib/win32ole/win32ole_method.rb +135 -0
  20. data/lib/win32ole/win32ole_param.rb +45 -0
  21. data/lib/win32ole/win32ole_ruby.rb +115 -0
  22. data/lib/win32ole/win32ole_type.rb +148 -0
  23. data/lib/win32ole/win32ole_typelib.rb +76 -0
  24. data/lib/win32ole/win32ole_variable.rb +41 -0
  25. data/lib/win32ole/win32ole_variant.rb +52 -0
  26. data/nbproject/build-impl.xml +800 -0
  27. data/nbproject/genfiles.properties +8 -0
  28. data/nbproject/private/config.properties +0 -0
  29. data/nbproject/private/private.properties +8 -0
  30. data/nbproject/private/private.xml +4 -0
  31. data/nbproject/project.properties +71 -0
  32. data/nbproject/project.xml +14 -0
  33. data/samples/browser_connect.rb +10 -0
  34. data/samples/const_load.rb +10 -0
  35. data/samples/dir_enum_bench.rb +24 -0
  36. data/samples/dispatch_bench.rb +44 -0
  37. data/samples/file_system_object.rb +7 -0
  38. data/samples/fs.rb +50 -0
  39. data/samples/ie_plus_events.rb +45 -0
  40. data/samples/ie_simple.rb +20 -0
  41. data/samples/ie_simple_clsid.rb +13 -0
  42. data/samples/sbem.rb +11 -0
  43. data/samples/small_enum_bench.rb +126 -0
  44. data/src/org/jruby/ext/win32ole/RubyInvocationProxy.java +34 -0
  45. data/src/org/jruby/ext/win32ole/RubyWIN32OLE.java +278 -0
  46. data/src/win32ole/Win32oleService.java +29 -0
  47. metadata +113 -0
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *~
2
+ output
3
+ pkg/*
4
+ build/*
5
+ dist/*
6
+ *.gem
7
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in jruby-win32ole.gemspec
4
+ gemspec
data/README ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ task :compile do
5
+ require 'ant'
6
+ ant ['-f', 'build.xml']
7
+ cp 'dist/win32ole.jar', 'lib/win32ole/win32ole.jar'
8
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.8.0
data/bin/make_data.rb ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'fileutils'
4
+
5
+ number_of_files = 1_000
6
+ directory = "c:/opt/test_data"
7
+
8
+ Dir.mkdir directory unless File.exists? directory
9
+ number_of_files.times do |i|
10
+ file = directory + "/" + i.to_s
11
+ FileUtils.touch file
12
+ end
data/bin/sample ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/sh
2
+
3
+ #jruby --server -J-Xdebug -J-Xrunjdwp:transport=dt_socket,address=8001,server=y,suspend=y -J-Djava.library.path=lib -Ilib samples/$1.rb
4
+ #jruby --server -J-Dcom.jacob.debug=true -J-Djava.library.path=lib -Ilib samples/$1.rb
5
+ #jruby --server -J-agentlib:hprof=heap=dump -J-Djava.library.path=lib -Ilib samples/$1.rb
6
+ #jruby --server -J-verbose:gc -J-Djava.library.path=lib -Ilib samples/$1.rb
7
+ #jruby --server -J-agentpath:"C:\Program Files\NetBeans 6.8\profiler3\lib\deployed\jdk15\windows\profilerinterface.dll=\"C:\Program Files\NetBeans 6.8\profiler3\lib\"",5140 -J-Djava.library.path=lib -Ilib samples/$1.rb
8
+
9
+ jruby -J-verbose:gc -J-Dcom.jacob.autogc=true -J-Dcom.jacob.gc_count=50000 -J-Dcom.jacob.debug=true -J-Djruby.backtrace.style=raw --server -J-Djava.library.path=lib -Ilib samples/$1.rb $2 $3
10
+
11
+ #jruby -J-Dcom.jacob.autogc=false -J-Dcom.jacob.debug=true -J-Djruby.backtrace.style=raw -J-Dcom.jacob.autogc=true -J-Djruby.ji.objectProxyCache=false --server -J-Djava.library.path=. -Idist samples/$1.rb $2 $3
data/build.xml ADDED
@@ -0,0 +1,74 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!-- You may freely edit this file. See commented blocks below for -->
3
+ <!-- some examples of how to customize the build. -->
4
+ <!-- (If you delete it and reopen the project it will be recreated.) -->
5
+ <!-- By default, only the Clean and Build commands use this build script. -->
6
+ <!-- Commands such as Run, Debug, and Test only use this build script if -->
7
+ <!-- the Compile on Save feature is turned off for the project. -->
8
+ <!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
9
+ <!-- in the project's Project Properties dialog box.-->
10
+ <project name="win32ole" default="default" basedir=".">
11
+ <description>Builds, tests, and runs the project win32ole.</description>
12
+ <import file="nbproject/build-impl.xml"/>
13
+ <!--
14
+
15
+ There exist several targets which are by default empty and which can be
16
+ used for execution of your tasks. These targets are usually executed
17
+ before and after some main targets. They are:
18
+
19
+ -pre-init: called before initialization of project properties
20
+ -post-init: called after initialization of project properties
21
+ -pre-compile: called before javac compilation
22
+ -post-compile: called after javac compilation
23
+ -pre-compile-single: called before javac compilation of single file
24
+ -post-compile-single: called after javac compilation of single file
25
+ -pre-compile-test: called before javac compilation of JUnit tests
26
+ -post-compile-test: called after javac compilation of JUnit tests
27
+ -pre-compile-test-single: called before javac compilation of single JUnit test
28
+ -post-compile-test-single: called after javac compilation of single JUunit test
29
+ -pre-jar: called before JAR building
30
+ -post-jar: called after JAR building
31
+ -post-clean: called after cleaning build products
32
+
33
+ (Targets beginning with '-' are not intended to be called on their own.)
34
+
35
+ Example of inserting an obfuscator after compilation could look like this:
36
+
37
+ <target name="-post-compile">
38
+ <obfuscate>
39
+ <fileset dir="${build.classes.dir}"/>
40
+ </obfuscate>
41
+ </target>
42
+
43
+ For list of available properties check the imported
44
+ nbproject/build-impl.xml file.
45
+
46
+
47
+ Another way to customize the build is by overriding existing main targets.
48
+ The targets of interest are:
49
+
50
+ -init-macrodef-javac: defines macro for javac compilation
51
+ -init-macrodef-junit: defines macro for junit execution
52
+ -init-macrodef-debug: defines macro for class debugging
53
+ -init-macrodef-java: defines macro for class execution
54
+ -do-jar-with-manifest: JAR building (if you are using a manifest)
55
+ -do-jar-without-manifest: JAR building (if you are not using a manifest)
56
+ run: execution of project
57
+ -javadoc-build: Javadoc generation
58
+ test-report: JUnit report generation
59
+
60
+ An example of overriding the target for project execution could look like this:
61
+
62
+ <target name="run" depends="win32ole-impl.jar">
63
+ <exec dir="bin" executable="launcher.exe">
64
+ <arg file="${dist.jar}"/>
65
+ </exec>
66
+ </target>
67
+
68
+ Notice that the overridden target depends on the jar target and not only on
69
+ the compile target as the regular run target does. Again, for a list of available
70
+ properties which you can use, check the target you are overriding in the
71
+ nbproject/build-impl.xml file.
72
+
73
+ -->
74
+ </project>
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "jruby-win32ole/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'jruby-win32ole'
7
+ s.version = JRuby::WIN32OLE::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = 'Thomas E. Enebo'
10
+ s.email = 'tom.enebo@gmail.com'
11
+ s.homepage = 'http://github.com/enebo/jruby-win32ole'
12
+ s.summary = %q{A Gem for win32ole support on JRuby}
13
+ s.description = %q{A Gem for win32ole support on JRuby}
14
+
15
+ s.rubyforge_project = "jruby-win32ole"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,39 @@
1
+ require 'java'
2
+
3
+ # Set location so the loader can find the native dll it needs
4
+ arch = ENV_JAVA['sun.arch.data.model'] == '32' ? 'x86' : 'x64'
5
+ java.lang.System.set_property 'racob.dll.path',
6
+ File.dirname(__FILE__) + "/racob-#{arch}.dll"
7
+
8
+ require 'racob.jar'
9
+
10
+ require 'win32ole/win32ole' # <- java native impl of WIN32OLE
11
+ require 'win32ole/win32ole_ruby' # <- ruby impl of WIN32OLE
12
+
13
+ java_import java.util.Calendar
14
+
15
+ java_import org.racob.com.Variant
16
+ java_import org.racob.com.Automation
17
+ java_import org.racob.com.ComFailException
18
+ java_import org.racob.com.ComThread
19
+ java_import org.racob.com.Dispatch
20
+ java_import org.racob.com.DispatchEvents
21
+ java_import org.racob.com.EnumVariant
22
+ java_import org.racob.com.FuncDesc
23
+ java_import org.racob.com.TypeInfo
24
+ java_import org.racob.com.TypeLib
25
+ java_import org.racob.com.VarDesc
26
+ java_import org.racob.com.VariantUtilities
27
+
28
+ java_import org.jruby.ext.win32ole.RubyWIN32OLE
29
+ java_import org.jruby.ext.win32ole.RubyInvocationProxy
30
+
31
+
32
+ require 'win32ole/win32ole_error'
33
+ require 'win32ole/win32ole_method'
34
+ require 'win32ole/win32ole_variant'
35
+ require 'win32ole/win32ole_variable'
36
+ require 'win32ole/win32ole_event'
37
+ require 'win32ole/win32ole_param'
38
+ require 'win32ole/win32ole_type'
39
+ require 'win32ole/win32ole_typelib'
@@ -0,0 +1,5 @@
1
+ module JRuby
2
+ module WIN32OLE
3
+ VERSION = "0.8.0"
4
+ end
5
+ end
data/lib/racob-x64.dll ADDED
Binary file
data/lib/racob-x86.dll ADDED
Binary file
data/lib/racob.jar ADDED
Binary file
@@ -0,0 +1,230 @@
1
+ require 'win32ole/win32ole_variant'
2
+
3
+ class WIN32OLE
4
+ module Utils
5
+ # FIXME: I don't know specifically if this is a GMT or local date?
6
+ OUT_OF_RANGE_DATE = Time.local(1899, 12, 30)
7
+
8
+ def SafeStringValue(str)
9
+ return str if str.kind_of?(::String)
10
+ if str.respond_to?(:to_str)
11
+ str = str.to_str
12
+ return str if str.kind_of?(::String)
13
+ end
14
+ raise TypeError
15
+ end
16
+
17
+ def WIN32OLE_TYPEValue(value)
18
+ raise TypeError.new("1st argument should be WIN32OLE_TYPE object") unless value.kind_of? WIN32OLE_TYPE
19
+ value
20
+ end
21
+
22
+ # Convert the supplied variant value to an equivalent Ruby value.
23
+ # If dispose is true then also dispose the variant itself.
24
+ def from_variant(value)
25
+ object = VariantUtilities.variant_to_object(value)
26
+ case object
27
+ when Dispatch then
28
+ object = WIN32OLE.new(object)
29
+ when java.util.Date then
30
+ object = java_date2ruby_time(object)
31
+ end
32
+
33
+ # Jacob will return null on out of bound dates whereas MRI returns
34
+ # some date windows normally returns. We will match this.
35
+ if object.nil? && !value.nil?
36
+ case value.getvt
37
+ when Variant::VariantDate, (Variant::VariantDate|Variant::VariantByref) then
38
+ object = OUT_OF_RANGE_DATE
39
+
40
+ end
41
+ end
42
+
43
+ object
44
+ end
45
+
46
+ # Simliar to MRI:vtdate2rbtime but we work with Java date instead of
47
+ # raw variant type
48
+ def java_date2ruby_time(date)
49
+ calendar = Calendar.get_instance
50
+ calendar.time = date
51
+
52
+ Time.local(calendar.get(Calendar::YEAR),
53
+ calendar.get(Calendar::MONTH),
54
+ calendar.get(Calendar::DAY_OF_MONTH),
55
+ calendar.get(Calendar::HOUR_OF_DAY),
56
+ calendar.get(Calendar::MINUTE),
57
+ calendar.get(Calendar::SECOND))
58
+ end
59
+
60
+ def methods_with_flag(flag)
61
+ members = []
62
+ all_methods(typeinfo_from_ole) do |typeinfo, old_typeinfo, desc, docs, i|
63
+ if desc.invkind & flag
64
+ members << WIN32OLE_METHOD.new(nil, typeinfo, old_typeinfo, desc, docs, i)
65
+ end
66
+ nil
67
+ end
68
+ members
69
+ end
70
+
71
+ def all_methods(typeinfo, &block) # MRI: olemethod_from_typeinfo
72
+ return unless typeinfo # Not all ole servers have this info
73
+
74
+ # Find method in this type.
75
+ ret = find_all_methods_in(nil, typeinfo, &block)
76
+ return ret if ret
77
+
78
+ # Now check all other type impls
79
+ typeinfo.impl_types_count.times do |i|
80
+ begin
81
+ href = typeinfo.get_ref_type_of_impl_type(i)
82
+ ref_typeinfo = typeinfo.get_ref_type_info(href)
83
+ ret = find_all_methods_in(typeinfo, ref_typeinfo, &block)
84
+ return ret if ret
85
+ rescue ComFailException => e
86
+ puts "Error getting impl types #{e}"
87
+ end
88
+ end
89
+ nil
90
+ end
91
+
92
+ # MRI: ole_method_sub
93
+ def find_all_methods_in(old_typeinfo, typeinfo, &block)
94
+ typeinfo.funcs_count.times do |i|
95
+ begin
96
+ desc = typeinfo.get_func_desc(i)
97
+ docs = typeinfo.get_documentation(desc.memid)
98
+ ret = yield typeinfo, old_typeinfo, desc, docs, i
99
+ return ret if ret
100
+ rescue ComFailException => e
101
+ puts "Error getting method info #{e}"
102
+ end
103
+ end
104
+ nil
105
+ end
106
+
107
+ def typeinfo_from_ole # MRI: typeinfo_from_ole
108
+ typeinfo = type_info
109
+ docs = typeinfo.get_documentation(-1)
110
+ type_lib = typeinfo.get_containing_type_lib
111
+ type_lib.get_type_info_count.times do |i|
112
+ begin
113
+ tdocs = type_lib.get_documentation(i)
114
+ return type_lib.get_type_info(i) if tdocs.name == docs.name
115
+ rescue ComFailException => e
116
+ # We continue on failure.
117
+ end
118
+ end
119
+ type_info # Actually MRI seems like it could fail in weird case
120
+ end
121
+
122
+ def load_typelib(path_reg, arch)
123
+ path = path_reg.open(arch) { |r| r.read(nil) }[1]
124
+ # puts "PATH = #{path}"
125
+ begin
126
+ Automation.loadTypeLib(path)
127
+ rescue ComFailException => e
128
+ # puts "Failed to load #{name} fom #{path} because: #{e}"
129
+ nil
130
+ end
131
+ end
132
+
133
+ def find_all_typeinfo(typelib)
134
+ typelib.type_info_count.times do |i|
135
+ docs = typelib.get_documentation(i)
136
+ next unless docs
137
+ info = typelib.get_type_info(i)
138
+ next unless info
139
+ yield info, docs
140
+ end
141
+ end
142
+
143
+ def all_vars(typeinfo)
144
+ typeinfo.vars_count.times do |i|
145
+ desc = typeinfo.get_var_desc(i)
146
+ next unless desc
147
+ names = typeinfo.get_names(desc.memid)
148
+ next if !names || names.length == 0
149
+ name = names[0]
150
+ next unless name
151
+ yield desc, name
152
+ end
153
+ end
154
+
155
+ def reg_each_key_for(reg, subkey, &block)
156
+ reg.open(subkey) do |subkey_reg|
157
+ subkey_reg.each_key { |key, wtime| block.call(subkey_reg, key) }
158
+ end
159
+ end
160
+
161
+ # Walks all guid/clsid entries and yields every single version
162
+ # of those entries to the supplied block. See search_registry as
163
+ # an example of its usage.
164
+ def typelib_registry_each_guid_version
165
+ Win32::Registry::HKEY_CLASSES_ROOT.open('TypeLib') do |reg|
166
+ reg.each_key do |guid, wtime|
167
+ reg.open(guid) do |guid_reg|
168
+ guid_reg.each_key do |version_string, wtime|
169
+ version = version_string.to_f
170
+ begin
171
+ guid_reg.open(version_string) do |version_reg|
172
+ yield guid, version, version_reg
173
+ end
174
+ rescue Win32::Registry::Error => e
175
+ # Version Entry may not contain anything. Skip.
176
+ end
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ def registry_subkey(reg, *valid_subkeys)
184
+ reg.each_key do |inner, wtime|
185
+ reg_each_key_for(reg, inner) do |subkey_reg, subkey|
186
+ yield subkey_reg, subkey if valid_subkeys.include? subkey
187
+ end
188
+ end
189
+ end
190
+
191
+ def search_registry(typelib_name) # MRI: oletypelib_search_registry
192
+ typelib_registry_each_guid_version do |guid, version, reg|
193
+ name = reg.read(nil)[1] || ''
194
+ registry_subkey(reg, 'win32', 'win64') do |arch_reg, arch|
195
+ type_lib = load_typelib(arch_reg, arch)
196
+ # puts "GUID #{guid} #{version} #{arch} #{type_lib}"
197
+ return type_lib if type_lib && name == typelib_name
198
+ end
199
+ end
200
+ nil
201
+ end
202
+
203
+ def typedesc_value(vt, type_details=nil)
204
+ type_string = WIN32OLE::VARIANT.variant_to_string(vt) || "Unknown Type #{vt}"
205
+
206
+ type_details << type_string if type_details
207
+
208
+ if vt == WIN32OLE::VARIANT::VT_PTR && type_details
209
+ # TODO: Add detail logic
210
+ end
211
+
212
+ type_details ? type_details : type_string
213
+ end
214
+
215
+ def variable_kind_string(varkind)
216
+ case varkind
217
+ when VarDesc::VAR_PERINSTANCE then
218
+ "PERINSTANCE"
219
+ when VarDesc::VAR_STATIC then
220
+ "STATIC"
221
+ when VarDesc::VAR_CONST then
222
+ "CONSTANT"
223
+ when VarDesc::VAR_DISPATCH then
224
+ "DISPATCH"
225
+ else
226
+ "UNKNOWN"
227
+ end
228
+ end
229
+ end
230
+ end
Binary file
@@ -0,0 +1,13 @@
1
+ class WIN32OLERuntimeError < RuntimeError
2
+ def initialize(cause=nil)
3
+ @cause = cause
4
+ end
5
+
6
+ def backtrace
7
+ @cause ? @cause.backtrace : super
8
+ end
9
+
10
+ def to_s
11
+ @cause ? @cause.to_s : super
12
+ end
13
+ end