com 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +225 -0
- data/Rakefile +10 -0
- data/lib/com.rb +73 -0
- data/lib/com/error.rb +44 -0
- data/lib/com/events.rb +68 -0
- data/lib/com/instantiable.rb +135 -0
- data/lib/com/methodinvocationerror.rb +38 -0
- data/lib/com/object.rb +79 -0
- data/lib/com/pathname.rb +10 -0
- data/lib/com/patternerror.rb +20 -0
- data/lib/com/standarderror.rb +61 -0
- data/lib/com/version.rb +5 -0
- data/lib/com/win32ole.rb +19 -0
- data/lib/com/wrapper.rb +96 -0
- data/test/unit/com.rb +23 -0
- data/test/unit/com/error.rb +11 -0
- data/test/unit/com/events.rb +28 -0
- data/test/unit/com/instantiable.rb +94 -0
- data/test/unit/com/methodinvocationerror.rb +67 -0
- data/test/unit/com/object.rb +33 -0
- data/test/unit/com/pathname.rb +21 -0
- data/test/unit/com/standarderror.rb +27 -0
- metadata +178 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
Expectations do
|
4
|
+
expect COM::MethodInvocationError do
|
5
|
+
COM::Error.from(stub(:message => %{method
|
6
|
+
OLE error code:123abcDE in server
|
7
|
+
message
|
8
|
+
HRESULT error code:0x123abcDE
|
9
|
+
hresult message}))
|
10
|
+
end
|
11
|
+
|
12
|
+
expect 'method' do
|
13
|
+
COM::Error.from(stub(:message => %{method
|
14
|
+
OLE error code:123abcDE in server
|
15
|
+
message
|
16
|
+
HRESULT error code:0x123abcDE
|
17
|
+
hresult message})).method
|
18
|
+
end
|
19
|
+
|
20
|
+
expect 'server' do
|
21
|
+
COM::Error.from(stub(:message => %{method
|
22
|
+
OLE error code:123abcDE in server
|
23
|
+
message
|
24
|
+
HRESULT error code:0x123abcDE
|
25
|
+
hresult message})).server
|
26
|
+
end
|
27
|
+
|
28
|
+
expect 0x123abcDE do
|
29
|
+
COM::Error.from(stub(:message => %{method
|
30
|
+
OLE error code:123abcDE in server
|
31
|
+
message
|
32
|
+
HRESULT error code:0x123abcDE
|
33
|
+
hresult message})).code
|
34
|
+
end
|
35
|
+
|
36
|
+
expect 0x123abcDE do
|
37
|
+
COM::Error.from(stub(:message => %{method
|
38
|
+
OLE error code:123abcDE in server
|
39
|
+
message
|
40
|
+
HRESULT error code:0x123abcDE
|
41
|
+
hresult message})).hresult_code
|
42
|
+
end
|
43
|
+
|
44
|
+
expect 'hresult message' do
|
45
|
+
COM::Error.from(stub(:message => %{method
|
46
|
+
OLE error code:123abcDE in server
|
47
|
+
message
|
48
|
+
HRESULT error code:0x123abcDE
|
49
|
+
hresult message})).hresult_message
|
50
|
+
end
|
51
|
+
|
52
|
+
expect 'message' do
|
53
|
+
COM::Error.from(stub(:message => %{method
|
54
|
+
OLE error code:123abcDE in server
|
55
|
+
message
|
56
|
+
HRESULT error code:0x123abcDE
|
57
|
+
hresult message})).message
|
58
|
+
end
|
59
|
+
|
60
|
+
expect 'message' do
|
61
|
+
COM::Error.from(stub(:message => %{method
|
62
|
+
OLE error code:123abcDE in server
|
63
|
+
message
|
64
|
+
HRESULT error code:0x123abcDE
|
65
|
+
hresult message})).to_s
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
Expectations do
|
4
|
+
=begin
|
5
|
+
expect :result do
|
6
|
+
COM::Object.new(stub).with_properties({}){ :result }
|
7
|
+
end
|
8
|
+
|
9
|
+
expect 1 do
|
10
|
+
o = {:a => 1}
|
11
|
+
COM::Object.new(o).with_properties(:a => 2){ }
|
12
|
+
o[:a]
|
13
|
+
end
|
14
|
+
|
15
|
+
expect 1 do
|
16
|
+
o = {:a => 1}
|
17
|
+
COM::Object.new(o).with_properties(:a => 2){ raise } rescue nil
|
18
|
+
o[:a]
|
19
|
+
end
|
20
|
+
|
21
|
+
expect 2 do
|
22
|
+
o = {:a => 1}
|
23
|
+
v = nil
|
24
|
+
COM::Object.new(o).with_properties(:a => 2){ v = o[:a] } rescue nil
|
25
|
+
o[:a]
|
26
|
+
v
|
27
|
+
end
|
28
|
+
=end
|
29
|
+
|
30
|
+
expect StandardError do
|
31
|
+
COM::Object.new(stub).with_properties({}){ raise StandardError }
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'pathname'
|
4
|
+
|
5
|
+
Expectations do
|
6
|
+
expect 'c:/a' do
|
7
|
+
stub(COM).charset{ 'UTF-8' }
|
8
|
+
Pathname('c:/a').to_com
|
9
|
+
end
|
10
|
+
|
11
|
+
expect 'c:/å' do
|
12
|
+
stub(COM).charset{ 'UTF-8' }
|
13
|
+
Pathname('c:/å').to_com
|
14
|
+
end
|
15
|
+
|
16
|
+
# ANSI and ISO-8859-1 å
|
17
|
+
expect 'c:/å' do
|
18
|
+
stub(COM).charset{ 'UTF-8' }
|
19
|
+
Pathname("c:/\xe5".force_encoding('Windows-1252')).to_com
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
Expectations do
|
4
|
+
expect NotImplementedError do
|
5
|
+
COM::Error.from(stub(:message => "\nHRESULT error code:0x80004001\n"))
|
6
|
+
end
|
7
|
+
|
8
|
+
expect NoMethodError do
|
9
|
+
COM::Error.from(stub(:message => "\nHRESULT error code:0x80020006\n"))
|
10
|
+
end
|
11
|
+
|
12
|
+
expect ArgumentError do
|
13
|
+
COM::Error.from(stub(:message => "\nHRESULT error code:0x8002000e\n"))
|
14
|
+
end
|
15
|
+
|
16
|
+
expect ArgumentError do
|
17
|
+
COM::Error.from(stub(:message => "\nHRESULT error code:0x800401e4\n"))
|
18
|
+
end
|
19
|
+
|
20
|
+
expect COM::OperationUnavailableError do
|
21
|
+
COM::Error.from(stub(:message => "\nHRESULT error code:0x800401e3\n"))
|
22
|
+
end
|
23
|
+
|
24
|
+
expect NameError.new('unknown COM server: A.B') do
|
25
|
+
COM::Error.from(stub(:message => "unknown OLE server: `A.B'\n HRESULT error code:0x800401f3\n"))
|
26
|
+
end
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: com
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nikolai Weibull
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-10-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: lookout
|
16
|
+
requirement: &14503188 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *14503188
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: yard
|
27
|
+
requirement: &14502792 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 0.6.0
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *14502792
|
36
|
+
description: ! "# COM #\n\nCOM is an object-oriented wrapper around WIN32OLE. COM
|
37
|
+
makes it easy to add\nbehavior to WIN32OLE objects, making them easier to work with
|
38
|
+
from Ruby.\n\n\n## Usage ##\n\nUsing COM is rather straightforward. There’s basically
|
39
|
+
four concepts to keep\ntrack of:\n\n 1. COM objects\n 2. Instantiable COM objects\n
|
40
|
+
\ 3. COM events\n 4. COM errors\n\nLet’s look at each concept separately, using
|
41
|
+
the following example as a base.\n\n module Word end\n\n class Word::Application
|
42
|
+
< COM::Instantiable\n def without_interaction\n with_properties('displayalerts'
|
43
|
+
=> Word::WdAlertsNone){ yield }\n end\n\n def documents\n Word::Documents.new(com.documents)\n
|
44
|
+
\ end\n\n def quit(saving = Word::WdDoNotSaveChanges, *args)\n com.quit
|
45
|
+
saving, *args\n end\n end\n\n### COM Objects ###\n\nA COM::Object is a wrapper
|
46
|
+
around a COM object. It provides error\nspecialization, which is discussed later
|
47
|
+
and a few utility methods. You\ntypically use it to wrap COM objects that are returned
|
48
|
+
by COM methods. If we\ntake the example given in the introduction, Word::Documents
|
49
|
+
is a good\ncandidate:\n\n class Word::Documents < COM::Object\n DefaultOpenOptions
|
50
|
+
= {\n 'confirmconversions' => false,\n 'readonly' => true,\n 'addtorecentfiles'
|
51
|
+
=> false,\n 'visible' => false\n }.freeze\n def open(path, options
|
52
|
+
= {})\n options = DefaultOpenOptions.merge(options)\n options['filename']
|
53
|
+
= Pathname(path).to_com\n Word::Document.new(com.open(options))\n end\n
|
54
|
+
\ end\n\nHere we override the #open method to be a bit easier to use, providing
|
55
|
+
sane\ndefaults for COM interaction. Worth noting is the use of the #com method
|
56
|
+
to\naccess the actual COM object to invoke the #open method on it. Also note that\nWord::Document
|
57
|
+
is also a COM::Object.\n\nCOM::Object provides a convenience method called #with_properties,
|
58
|
+
which is\nused in the #without_interaction method above. It lets you set properties
|
59
|
+
on\nthe COM::Object during the duration of a block, restoring them after it exits\n(successfully
|
60
|
+
or with an error).\n\n\n### Instantiable COM Objects ###\n\nInstantiable COM objects
|
61
|
+
are COM objects that we can connect to and that can be\ncreated. The Word::Application
|
62
|
+
object can, for example, be created.\nInstantiable COM objects should inherit from
|
63
|
+
COM::Instantiable. Instantiable\nCOM objects can be told what program ID to use,
|
64
|
+
whether or not to allow\nconnecting to an already running object, and to load its
|
65
|
+
associated constants\nupon creation.\n\nThe program ID is used to determine what
|
66
|
+
instantiable COM object to connect to.\nBy default the name of the COM::Instantiable
|
67
|
+
class’ name is used, taking the\nlast two double-colon-separated components and
|
68
|
+
joining them with a dot. For\nWord::Application, the program ID is “Word.Application”.
|
69
|
+
\ The program ID can be\nset by using the .program_id method:\n\n class IDontCare::ForConventions
|
70
|
+
< COM::Instantiable\n program_id 'Word.Application'\n end\n\nThe program
|
71
|
+
ID can be accessed with the same method:\n\n Word::Application.program_id # ⇒
|
72
|
+
'Word.Application'\n\nConnecting to an already running COM object is not done by
|
73
|
+
default, but is\nsometimes desirable: the COM object might take a long time to create,
|
74
|
+
or some\ncommon state needs to be accessed. If the default for a certain instantiable\nCOM
|
75
|
+
object should be to connect, this can be done using the .connect method:\n\n class
|
76
|
+
Word::Application < COM::Instantiable\n connect\n end\n\nIf no running COM
|
77
|
+
object is available, then a new COM object will be created in\nits stead. Whether
|
78
|
+
or not a class uses the connection method can be queried\nwith the .connect? method:\n\n
|
79
|
+
\ Word::Application.connect? # ⇒ true\n\nWhether or not to load constants associated
|
80
|
+
with an instantiable COM object is\nset with the .constants method:\n\n class
|
81
|
+
Word::Application < COM::Instantiable\n constants true\n end\n\nand can
|
82
|
+
similarly be checked:\n\n Word::Application.constants? # ⇒ true\n\nConstants
|
83
|
+
are loaded by default.\n\nWhen an instance of the instantiable COM object is created,
|
84
|
+
a check is run to\nsee if constants should be loaded and whether or not they already
|
85
|
+
have been\nloaded. If they should be loaded and they haven’t already been loaded,\nthey’re,
|
86
|
+
you guessed it, loaded. The constants are added to the module\ncontaining the COM::Instantiable.
|
87
|
+
\ Thus, for Word::Application, the Word module\nwill contain all the constants.
|
88
|
+
\ Whether or not the constants have already been\nloaded can be checked with .constants_loaded?:\n\n
|
89
|
+
\ Word::Application.constants_loaded # ⇒ false\n\nThat concludes the class-level
|
90
|
+
methods.\n\nLet’s begin with the #connected? method among the instance-level methods.
|
91
|
+
\ This\nmethod queries whether or not this instance connected to an already running
|
92
|
+
COM\nobject:\n\n Word::Application.new.connected? # ⇒ false\n\nThis can be very
|
93
|
+
important in determining how shutdown of a COM object should\nbe done. If you connected
|
94
|
+
to an already COM object it might be foolish to shut\nit down if someone else is
|
95
|
+
using it.\n\nThe #initialize method takes a couple of options:\n\n * connect: whether
|
96
|
+
or not to connect to a running instance\n * constants: whether or not to load constants\n\nThese
|
97
|
+
options will, when given, override the class-level defaults.\n\n### Events ###\n\nCOM
|
98
|
+
events are easily dealt with:\n\n class Word::Application < COM::Instantiable\n
|
99
|
+
\ def initialize(options = {})\n super\n @events = COM::Events.new(com,
|
100
|
+
'ApplicationEvents',\n 'OnQuit')\n end\n\n
|
101
|
+
\ def quit(saving = Word::WdDoNotSaveChanges, *args)\n @events.observe('OnQuit',
|
102
|
+
proc{ com.quit saving, *args }) do\n yield if block_given?\n end\n
|
103
|
+
\ end\n end\n\nTo tell you the truth this API sucks and will most likely
|
104
|
+
be rewritten. The\nreason that it is the way it is is that WIN32OLE, which COM
|
105
|
+
wraps, sucks. It’s\nevent API is horrid and the implementation is buggy. It will
|
106
|
+
keep every\nregistered event block in memory for ever, freeing neither the blocks
|
107
|
+
nor the\nCOM objects that yield the events.\n\n### Errors ###\n\nAll errors generated
|
108
|
+
by COM methods descend from COM::Error, except for those\ncases where a Ruby error
|
109
|
+
already exists. The following HRESULT error codes are\nturned into Ruby errors:\n\n
|
110
|
+
\ HRESULT Error Code | Error Class\n -------------------|------------\n 0x80004001
|
111
|
+
\ | NotImplementedError\n 0x80020005 | TypeError\n 0x80020006 |
|
112
|
+
NoMethodError\n 0x8002000e | ArgumentError\n 0x800401e4 | ArgumentError\n\nThere
|
113
|
+
are also a couple of other HRESULT error codes that are turned into more\nspecific
|
114
|
+
errors than COM::Error:\n\n HRESULT Error Code | Error Class\n -------------------|------------\n
|
115
|
+
\ 0x80020003 | MemberNotFoundError\n 0x800401e3 | OperationUnavailableError\n\nFinally,
|
116
|
+
when a method results in any other error, a COM::MethodInvocationError\nwill be
|
117
|
+
raised, which can be queried for the specifics, specifically #message,\n #method,
|
118
|
+
#server, #code, #hresult_code, and #hresult_message.\n\n### Pathname ###\n\nThe
|
119
|
+
Pathname object receives an additional method, #to_com. This method is\nuseful
|
120
|
+
for when you want to pass a Pathname object to a COM method. Simply\ncall #to_com
|
121
|
+
to turn it into a String of the right encoding for COM:\n\n Word::Application.new.documents.open(Pathname('a.docx').to_com)\n
|
122
|
+
\ # ⇒ Word::Document\n\n\n## Installation ##\n\nInstall COM with\n\n % gem
|
123
|
+
install com\n\n\n## License ##\n\nYou may use, copy and redistribute this library
|
124
|
+
under the same [terms][1] as\nRuby itself.\n\n[1]: http://www.ruby-lang.org/en/LICENSE.txt\n\n\n##
|
125
|
+
Contributors ##\n\n * Nikolai Weibull\n"
|
126
|
+
email: now@bitwi.se
|
127
|
+
executables: []
|
128
|
+
extensions: []
|
129
|
+
extra_rdoc_files: []
|
130
|
+
files:
|
131
|
+
- lib/com/error.rb
|
132
|
+
- lib/com/events.rb
|
133
|
+
- lib/com/instantiable.rb
|
134
|
+
- lib/com/methodinvocationerror.rb
|
135
|
+
- lib/com/object.rb
|
136
|
+
- lib/com/pathname.rb
|
137
|
+
- lib/com/patternerror.rb
|
138
|
+
- lib/com/standarderror.rb
|
139
|
+
- lib/com/version.rb
|
140
|
+
- lib/com/win32ole.rb
|
141
|
+
- lib/com/wrapper.rb
|
142
|
+
- lib/com.rb
|
143
|
+
- test/unit/com/error.rb
|
144
|
+
- test/unit/com/events.rb
|
145
|
+
- test/unit/com/instantiable.rb
|
146
|
+
- test/unit/com/methodinvocationerror.rb
|
147
|
+
- test/unit/com/object.rb
|
148
|
+
- test/unit/com/pathname.rb
|
149
|
+
- test/unit/com/standarderror.rb
|
150
|
+
- test/unit/com.rb
|
151
|
+
- README
|
152
|
+
- Rakefile
|
153
|
+
homepage: http://github.com/now/com
|
154
|
+
licenses: []
|
155
|
+
metadata: {}
|
156
|
+
post_install_message:
|
157
|
+
rdoc_options: []
|
158
|
+
require_paths:
|
159
|
+
- lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
none: false
|
168
|
+
requirements:
|
169
|
+
- - ! '>='
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 1.8.10
|
175
|
+
signing_key:
|
176
|
+
specification_version: 4
|
177
|
+
summary: COM is an object-oriented wrapper around WIN32OLE.
|
178
|
+
test_files: []
|