ass_launcher 0.6.0 → 0.7.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.
@@ -0,0 +1,235 @@
1
+ [![Code Climate](https://codeclimate.com/github/leoniv/ass_launcher/badges/gpa.svg)](https://codeclimate.com/github/leoniv/ass_launcher)
2
+ [![Gem Version](https://badge.fury.io/rb/ass_launcher.svg)](https://badge.fury.io/rb/ass_launcher)
3
+
4
+ # AssLauncher
5
+
6
+ Ruby wrapper for 1C:Enterprise platform.
7
+
8
+ Goal of this to make easily and friendly writing scripts for development
9
+ and support lifecycle of 1C:Enterprise applications
10
+
11
+ `AssLauncher` is cross platform but **it full tested in `Cygwin` only!**. In `Windows` and `Linux` it works too.
12
+
13
+ In `Linux` don't support `OLE` feature. Don't known why I told it ;)
14
+
15
+
16
+ ## Quick start
17
+
18
+ ### Using `AssLauncher` as a library
19
+
20
+ Add this line to your application's Gemfile:
21
+
22
+ ```ruby
23
+ gem 'ass_launcher'
24
+ ```
25
+
26
+ And then execute:
27
+
28
+ $ bundle
29
+
30
+ Or install it yourself as:
31
+
32
+ $ gem install ass_launcher
33
+
34
+ For example, writing script which dumping 1C:Enterprise application
35
+
36
+ ```ruby
37
+ require 'ass_launcher'
38
+
39
+ include AssLauncher::Api
40
+
41
+ def main(dupm_path)
42
+ # Get wrapper for the thck client
43
+ thick_client = thicks('~> 8.3.8.0').last
44
+
45
+ # Fail if 1C:Enterprise installation not found
46
+ fail '1C:Enterprise not found' if thick_client.nil?
47
+
48
+ # Build designer command
49
+ designer = thick_client.command :designer do
50
+ _S 'enterprse_server/application_name'
51
+ dumpIB dupm_path
52
+ end
53
+
54
+ # Execute command
55
+ designer.run.wait
56
+
57
+ # Verify result
58
+ designer.process_holder.result.verify!
59
+ end
60
+
61
+ main ARGV[0]
62
+ ```
63
+
64
+ ### Command line utility `ass-launcher`
65
+
66
+ From version `0.3.0` `AssLauncher` provides console tool `ass-launcher` wich has
67
+ features:
68
+
69
+ - make new 1C:Enterprise application instance (aka information base)
70
+ - run 1C:Enterprise
71
+ - show help about 1C:Enterprise CLI parameters
72
+ - and some more
73
+
74
+ For more info about `ass-launcher` execute:
75
+
76
+ $ass-launcher --help
77
+
78
+
79
+ ## x86_64 1C:Enterprise for Windows
80
+
81
+ From `v8.3.9` 1C provides x86_64 arch platform for Windows.
82
+
83
+ For choosing which arch of 1C binary you need
84
+ `AssLauncher::Enterprise::BinaryWrapper` has `arch` property and some helpers
85
+ in `AssLauncher::Api` like a `*_i386` and `*_x86_64`.
86
+
87
+ For in-process OLE server `v83.ComConnector` aka `comcntr.dll`, arch of 1C
88
+ binary selects automaticaly in depends of Ruby arch.
89
+
90
+ On default using of `x86_64` 1C OLE server is forbidden (see below trouble).
91
+ For forcing to use `x86_64` OLE server set config flag `use_x86_64_ole`:
92
+
93
+ ```ruby
94
+ AssLauncher.configure do |conf|
95
+ conf.use_x86_64_ole = true
96
+ end
97
+ ```
98
+
99
+ ### Trouble with x86_64 in-process OLE server `v83.ComConnector`
100
+
101
+ `x86_64` in-process OLE server or Ruby `win32ole` is unstable now
102
+ and Ruby usually crashed while handling connect error.
103
+
104
+ Еxample for `x86_64` Ruby and 1C OLE server:
105
+
106
+ ```
107
+ $ruby -v
108
+ ruby 2.3.6p384 (2017-12-14 revision 9808) [x86_64-cygwin]
109
+
110
+ $pry
111
+
112
+ RbConfig::CONFIG['arch'] #=> "x86_64-cygwin"
113
+
114
+ require 'win32ole'
115
+
116
+ inproc = WIN32OLE.new('V83.COMConnector')
117
+
118
+ inproc.connect('invalid connection string')
119
+
120
+ ....*** buffer overflow detected ***: terminated
121
+ Aborted (стек памяти сброшен на диск)
122
+ ```
123
+
124
+ The same example for `i386` Ruby and 1C OLE server working fine:
125
+
126
+ ```
127
+ $ruby -v
128
+ ruby 2.3.6p384 (2017-12-14 revision 9808) [i386-cygwin]
129
+
130
+ $pry
131
+
132
+ RbConfig::CONFIG['arch'] #=> "i386-cygwin"
133
+
134
+ require 'win32ole'
135
+
136
+ inproc = WIN32OLE.new('V83.COMConnector')
137
+
138
+ inproc.connect('invalid connection string')
139
+
140
+ WIN32OLERuntimeError: (in OLE method `connect': )
141
+ OLE error code:80004005 in V83.COMConnector.1
142
+ Неверные или отсутствующие параметры соединения с информационной базой
143
+ HRESULT error code:0x80020009
144
+ Exception occurred.
145
+ from (pry):3:in `method_missing'
146
+ ```
147
+
148
+
149
+ ### Trouble with x86_64 local OLE servers `v83c.Application` and `v83.Application`
150
+
151
+ On theory, architecture of local OLE server isn't important for using them
152
+ in various Ruby architectures.
153
+
154
+ But it only theory. While in the run [exaples](examples/) in the `i386` Ruby
155
+ with `x86_64` local 1C OLE observes the unexpected behavior of 1C OLE
156
+ servers like a errors while to connect to information base:
157
+
158
+ ```
159
+ WIN32OLERuntimeError: (in OLE method `connect': )
160
+ OLE error code:0 in <Unknown>
161
+ <No Description>
162
+ HRESULT error code:0x80010108
163
+ The object invoked has disconnected from its clients.
164
+ /tmp/ass_launcher/lib/ass_launcher/enterprise/ole/win32ole.rb:87:in `method_missing'
165
+ /tmp/ass_launcher/lib/ass_launcher/enterprise/ole/win32ole.rb:87:in `call'
166
+ /tmp/ass_launcher/lib/ass_launcher/enterprise/ole/win32ole.rb:87:in `block in <class:WIN32OLE>'
167
+ /tmp/ass_launcher/lib/ass_launcher/enterprise/ole.rb:142:in `__try_open__'
168
+ /tmp/ass_launcher/lib/ass_launcher/enterprise/ole.rb:136:in `__open__'
169
+ /tmp/ass_launcher/examples/enterprise_ole_example.rb:131:in `block (4 levels) in <module:EnterpriseOle>'
170
+ ```
171
+
172
+ ## Usage
173
+
174
+ ### Examples
175
+
176
+ For more usage examples see [examples](examples/)
177
+
178
+ For beginning look at
179
+ [examples/enterprise_running_example.rb](examples/enterprise_running_example.rb)
180
+
181
+ All [examples](examples/) executable. For run them require
182
+ 1C:Enterprise platform version defined in `Examples::MIN_PLATFORM_VERSION`
183
+
184
+ Run all examples:
185
+
186
+ $rake run_examples
187
+
188
+ Or run specified example:
189
+
190
+ $rake run_examples TEST=examples/enterprise_running_example.rb
191
+
192
+ ### Troubles
193
+
194
+ Directory [examples/troubles](examples/troubles) contains examples
195
+ which describe troubles with executing 1C:Enterprise binary.
196
+
197
+ All [examples/troubles](examples/troubles) are executable too.
198
+
199
+ Run all troubles:
200
+
201
+ $rake run_trouble_examples
202
+
203
+ **Be careful to run [examples/troubles](examples/troubles)! Learn sources before run it.**
204
+
205
+ ## Help
206
+
207
+ If you have any questions open issue with `question` lable
208
+
209
+ ## Development
210
+
211
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
212
+
213
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
214
+
215
+ ### Development helper
216
+
217
+ `AssLauncher` include [bin/dev-helper](bin/dev-helper) utility for contributors.
218
+
219
+ $bin/dev-helper --help
220
+
221
+ ### Testing
222
+
223
+ #### Run unit tests:
224
+
225
+ $export SIMPLECOV=YES && rake test
226
+
227
+ Unit tests is isolated and doesn't require installation of 1C:Enterprise
228
+
229
+ #### Run examples:
230
+
231
+ Examples writed as `Minitest::Spec`. About run examples see above
232
+
233
+ ## Contributing
234
+
235
+ Bug reports and pull requests are welcome on GitHub at https://github.com/leoniv/ass_launcher.
@@ -0,0 +1,35 @@
1
+ # Примеры использования *AssLauncher*
2
+
3
+ В данном каталоге собраны примеры использования *AssLauncher* оформленные как
4
+ исполняемые тесты в формате [Mintest::Spec](https://github.com/seattlerb/minitest).
5
+ Примеры сгруппированы по фичам *AssLauncher*:
6
+
7
+ - файл [binary_wrappers_example.rb](binary_wrappers_example.rb) - примеры для
8
+ работы с различными видами клиентов платформы 1С
9
+ - файл [arguments_builder_example.rb](arguments_builder_example.rb) - примеры
10
+ работы с построителем аргументов для консольного запуска платформы 1С
11
+ - файл [connection_string_example.rb](connection_string_example.rb) - пример
12
+ работы со строкой соединения
13
+ - файл [create_infobase_example.rb](create_infobase_example.rb) - примеры
14
+ запуска платформы в режиме создания информационной базы
15
+ - файл [enterprise_ole_example.rb](enterprise_ole_example.rb) - примеры работы с
16
+ различными видами 1С OLE серверов
17
+ - файл [enterprise_out_example.rb](enterprise_out_example.rb) - пример захвата
18
+ вывода платформы
19
+ - файл [enterprise_running_example.rb](enterprise_running_example.rb) - базовые
20
+ примеры работы с различными клиентами платформы 1С
21
+ - файл [v8i_file_example.rb](v8i_file_example.rb) - пример работы с файлами v8i
22
+ - файл [webclient_example.rb](webclient_example.rb) - более подробный пример
23
+ работы с web клиентом
24
+
25
+ Для запуска примеров требуется установленная платформа 1С версии указанной
26
+ в константе `MIN_PLATFORM_VERSION` объявленной в файле
27
+ [example_helper.rb](example_helper.rb)
28
+
29
+ Запуск примеров:
30
+
31
+ $ bundler exec rake run_examples
32
+
33
+ Запуск с фильтром по имени спеки:
34
+
35
+ $ bundler exec rake run_examples TESTOPTS='--name=/здесь рег. выражение/i'
@@ -38,7 +38,7 @@ module Examples
38
38
  end
39
39
 
40
40
  after do
41
- FileUtils.rm_rf conns.file if File.exists?(conns.file)
41
+ FileUtils.rm_rf conns.file if File.exist?(conns.file)
42
42
  end
43
43
  end
44
44
  end
@@ -8,9 +8,9 @@ module Examples
8
8
  end
9
9
 
10
10
  # 1C:Enterprise provides three OLE servers:
11
- # v8x.Application - thick client standalone OLE server
12
- # v8xC.Application - thin client standalone OLE server
13
- # v8x.ComConnector - inproc ole server for connect to:
11
+ # v8x.Application - thick client local OLE server
12
+ # v8xC.Application - thin client local OLE server
13
+ # v8x.ComConnector - in-process OLE server for connect to:
14
14
  # - 1C:Enterprise application aka infobases
15
15
  # - 1C:Enterprise server agent
16
16
  # - 1C:Enterprise server working process
@@ -72,7 +72,7 @@ module Examples
72
72
  end
73
73
 
74
74
  describe 'Closing connection' do
75
- describe 'For standalone server it working perfect' do
75
+ describe 'For local server it working perfect' do
76
76
  extend AssLauncher::Api
77
77
  thick_app = ole(:thick, PLATFORM_VER)
78
78
 
@@ -97,16 +97,16 @@ module Examples
97
97
  end
98
98
  end
99
99
 
100
- describe 'For inproc server close connection working with restrictions' do
101
- # 1C inproc OLE servers haven't method for closing connection!
100
+ describe 'For in-process server close connection working with restrictions' do
101
+ # 1C in-process OLE servers haven't method for closing connection!
102
102
  # Connection keep alive while live ruby process.
103
103
  #
104
- # If in one ruby script we want to use inproc connection for some work
104
+ # If in one ruby script we want to use in-process connection for some work
105
105
  # do in the infobase and after them we want run other connection
106
106
  # or application or designer with flag of exclusive mode, in this case
107
- # opened inproc connection doesn't give us to do it
107
+ # opened in-process connection doesn't give us to do it
108
108
  #
109
- # AssLauncher provide feature for closing inproc connection but
109
+ # AssLauncher provide feature for closing in-process connection but
110
110
  # it working with restrictions.
111
111
  #
112
112
  # AssLauncher patching WIN32OLE and collect all ole objects which
@@ -116,14 +116,14 @@ module Examples
116
116
  # But it works not always. Connection keep alive while have any alive
117
117
  # WIN32OLE refs generated this connection
118
118
 
119
- describe 'Case when inproc server connection realy closed' do
119
+ describe 'Case when in-process server connection realy closed' do
120
120
  extend AssLauncher::Api
121
121
 
122
- # Get standalone ole server wrapper
122
+ # Get local ole server wrapper
123
123
  # It is service connector
124
124
  thick_app = ole(:thick, PLATFORM_VER)
125
125
 
126
- # Get inproc ole server wrapper
126
+ # Get in-process ole server wrapper
127
127
  # It object under test
128
128
  external = ole(:external, PLATFORM_VER)
129
129
 
@@ -164,10 +164,10 @@ module Examples
164
164
  # AssLauncher automatically register needed server version
165
165
  # and returns suitable wrapper.
166
166
  #
167
- # Registration version of ole server working correct only for standalone
167
+ # Registration version of ole server working correct only for local
168
168
  # servers such as Thin and Thick applications.
169
169
  #
170
- # We don't get new version of inproc ole server until old version
170
+ # We don't get new version of in-process ole server until old version
171
171
  # is loaded in memory
172
172
 
173
173
  it "Fail if 1C:Enterprise version doesn't instaled" do
@@ -179,7 +179,7 @@ module Examples
179
179
  e.message.must_match %r{Platform version `~> 999' not instaled}
180
180
  end
181
181
 
182
- describe 'Choosing version of standalone ole server working perfect' do
182
+ describe 'Choosing version of local ole server working perfect' do
183
183
  extend AssLauncher::Api
184
184
 
185
185
  thick_app = ole(:thick, PLATFORM_VER)
@@ -49,7 +49,7 @@ module Examples
49
49
  # will be passed to arguments builder instance
50
50
  connection_string "File=\"#{TMP::EMPTY_IB}\";"
51
51
  _L 'en'
52
- _Debug
52
+ _Debug :'-tcp'
53
53
  _DebuggerUrl 'tcp://localhost'
54
54
  end
55
55
 
@@ -53,7 +53,7 @@ module Examples
53
53
  end
54
54
 
55
55
  def exists?(name)
56
- File.exists? ib_file_path(name)
56
+ File.exist? ib_file_path(name)
57
57
  end
58
58
 
59
59
  def ib_file_path(name)
@@ -103,7 +103,7 @@ module Examples
103
103
  module TmpIb
104
104
  extend IbMaker
105
105
  def self.rm(name)
106
- FileUtils.rm_rf ibases[name] if File.exists? ibases[name]
106
+ FileUtils.rm_rf ibases[name] if File.exist? ibases[name]
107
107
  end
108
108
 
109
109
  def self.ibases_root
@@ -0,0 +1,20 @@
1
+ # Примеры проблем консольного запуска платформы 1С
2
+
3
+ Об общих проблемах скриптинга на платформе 1С можно прочесть
4
+ [здесь](https://github.com/leoniv/v8_circles_of_hell/blob/master/articles/круг_первый_скриптинг.md)
5
+
6
+ Некоторые проблемы консольного запуска платформы проиллюстрированы в форме
7
+ исполняемых тестов расположенных в этом каталоге. Тесты написаны в формате
8
+ [Mintest::Spec](https://github.com/seattlerb/minitest)
9
+
10
+ Для запуска примеров требуется установленная платформа 1С версии указанной
11
+ в константе `MIN_PLATFORM_VERSION` объявленной в файле
12
+ [../example_helper.rb](../example_helper.rb)
13
+
14
+ Но прежде чем запустить их изучите исходники.
15
+
16
+ Запуск используйте команду:
17
+
18
+ $bundler exec rake run_trouble_examples SHOW_STUPID_GUI=YES
19
+
20
+ И не забывайте закрывать окна 1С которые будут появляться в процессе тестов.
@@ -28,7 +28,7 @@ module Examples
28
28
  command.run.wait
29
29
 
30
30
  # Infobase which we want not exists
31
- File.exists?(conns.file).must_equal false
31
+ File.exist?(conns.file).must_equal false
32
32
 
33
33
  # But created infobase which we don't want
34
34
  skip 'It fixed from 1C:Enterprise 8.3.10'
@@ -38,7 +38,7 @@ module Examples
38
38
  created = Regexp.last_match[1]
39
39
  created.must_match(/InfoBase\D?/i)
40
40
 
41
- File.exists?(created).must_equal true
41
+ File.exist?(created).must_equal true
42
42
  end
43
43
 
44
44
  it 'Creates infobase which we want' do
@@ -62,11 +62,11 @@ module Examples
62
62
  /Creation of infobase \("File\s?=\s?'([^']+)/i
63
63
  created = Regexp.last_match[1]
64
64
  command.args[1].must_include created
65
- File.exists?(conns.file).must_equal true
65
+ File.exist?(conns.file).must_equal true
66
66
  end
67
67
 
68
68
  after do
69
- FileUtils.rm_rf conns.file if File.exists? conns.file
69
+ FileUtils.rm_rf conns.file if File.exist? conns.file
70
70
  end
71
71
 
72
72
  describe 'Solution with AssLauncher' do
@@ -88,7 +88,7 @@ module Examples
88
88
  .path(infobasedir).win_string
89
89
 
90
90
  before do
91
- FileUtils.rm_rf infobasedir if File.exists? infobasedir
91
+ FileUtils.rm_rf infobasedir if File.exist? infobasedir
92
92
  end
93
93
 
94
94
  it "Fails if connection string double quoted" do
@@ -132,11 +132,11 @@ module Examples
132
132
  created = Regexp.last_match[1]
133
133
 
134
134
  conns.file.must_equal created
135
- File.exists?(conns.file).must_equal true
135
+ File.exist?(conns.file).must_equal true
136
136
  end
137
137
 
138
138
  after do
139
- FileUtils.rm_rf infobasedir if File.exists? infobasedir
139
+ FileUtils.rm_rf infobasedir if File.exist? infobasedir
140
140
  end
141
141
  end
142
142
 
@@ -147,7 +147,7 @@ module Examples
147
147
  'example_create_infobase_with_right_slashes.ib')
148
148
 
149
149
  before do
150
- FileUtils.rm_rf infobasedir if File.exists? infobasedir
150
+ FileUtils.rm_rf infobasedir if File.exist? infobasedir
151
151
  end
152
152
 
153
153
  describe 'Using single quote in connection string' do
@@ -199,12 +199,12 @@ module Examples
199
199
  end
200
200
 
201
201
  # Realy infobase not exists
202
- File.exists?(infobasedir).must_equal false
202
+ File.exist?(infobasedir).must_equal false
203
203
  end
204
204
  end
205
205
 
206
206
  after do
207
- FileUtils.rm_rf infobasedir if File.exists? infobasedir
207
+ FileUtils.rm_rf infobasedir if File.exist? infobasedir
208
208
  end
209
209
  end
210
210
 
@@ -242,9 +242,9 @@ module Examples
242
242
  end
243
243
 
244
244
  # Realy infobase not exists
245
- File.exists?(infobasedir).must_equal false
245
+ File.exist?(infobasedir).must_equal false
246
246
  # Infobase created in the current directory created
247
- File.exists?(infobasedir.gsub('..','.')).must_equal true
247
+ File.exist?(infobasedir.gsub('..','.')).must_equal true
248
248
 
249
249
  end
250
250
  end
@@ -282,7 +282,7 @@ module Examples
282
282
  end
283
283
 
284
284
  after do
285
- FileUtils.rm_rf infobasedir if File.exists? infobasedir
285
+ FileUtils.rm_rf infobasedir if File.exist? infobasedir
286
286
  end
287
287
  end
288
288
 
@@ -300,7 +300,7 @@ module Examples
300
300
 
301
301
  extend AssLauncher::Api
302
302
 
303
- File.exists?(root).must_equal true
303
+ File.exist?(root).must_equal true
304
304
  conns = cs_file file: infobasedir
305
305
 
306
306
  command = CLIENTS::THICK.command :createinfobase,
@@ -316,7 +316,7 @@ module Examples
316
316
 
317
317
  describe 'Using double quoted connection string' do
318
318
  it 'Infobase is created not where you need' do
319
- File.exists?(root).must_equal true
319
+ File.exist?(root).must_equal true
320
320
  conns = "File=\"#{infobasedir}\""
321
321
 
322
322
  command = CLIENTS::THICK.command :createinfobase,
@@ -342,16 +342,16 @@ module Examples
342
342
  end
343
343
 
344
344
  # Realy infobase not exists
345
- File.exists?(infobasedir).must_equal false
345
+ File.exist?(infobasedir).must_equal false
346
346
  end
347
347
  end
348
348
 
349
349
  before do
350
- FileUtils.rm_rf infobasedir if File.exists? infobasedir
350
+ FileUtils.rm_rf infobasedir if File.exist? infobasedir
351
351
  end
352
352
 
353
353
  after do
354
- FileUtils.rm_rf infobasedir if File.exists? infobasedir
354
+ FileUtils.rm_rf infobasedir if File.exist? infobasedir
355
355
  end
356
356
  end
357
357
 
@@ -366,7 +366,7 @@ module Examples
366
366
  it 'Solution with ConnectionString::File' do
367
367
  extend AssLauncher::Api
368
368
 
369
- File.exists?(root).must_equal true
369
+ File.exist?(root).must_equal true
370
370
  # ConnectionString::File converts connection string
371
371
  # for CREATEINFOBASE mode from double quoted:
372
372
  # 'File="pat";' to single quoted: "File='path';" string
@@ -384,12 +384,12 @@ module Examples
384
384
  created = Regexp.last_match[1]
385
385
 
386
386
  conns.file.must_equal created
387
- File.exists?(conns.file).must_equal true
387
+ File.exist?(conns.file).must_equal true
388
388
  end
389
389
 
390
390
  describe 'Using double quoted connection string' do
391
391
  it 'Fails CREATEINFOBASE' do
392
- File.exists?(root).must_equal true
392
+ File.exist?(root).must_equal true
393
393
  conns = "File=\"#{infobasedir}\""
394
394
 
395
395
  command = CLIENTS::THICK.command :createinfobase,
@@ -408,11 +408,11 @@ module Examples
408
408
  end
409
409
 
410
410
  before do
411
- FileUtils.rm_rf infobasedir if File.exists? infobasedir
411
+ FileUtils.rm_rf infobasedir if File.exist? infobasedir
412
412
  end
413
413
 
414
414
  after do
415
- FileUtils.rm_rf infobasedir if File.exists? infobasedir
415
+ FileUtils.rm_rf infobasedir if File.exist? infobasedir
416
416
  end
417
417
  end
418
418
  end