wixgem 0.47.0 → 0.48.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.
- checksums.yaml +4 -4
- data/lib/WindowsInstaller.rb +2 -3
- data/lib/command.rb +0 -1
- data/lib/wixgem.rb +143 -30
- metadata +13 -14
- data/lib/WindowsInstaller_hold.rb +0 -156
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cc49605457da97d26245c8d8d141bae95d2ea6f
|
4
|
+
data.tar.gz: a486cfdb2dfe6f9e7434328ad11c0d587db481b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f64e9cb3bb1d1092914d3f701889df6cafed615b5aa12d9fed383e23ea0f7881f3574d7ee0c5f159f54614d54b3689d443287751ffcc62bf7bfea0b82e2e062a
|
7
|
+
data.tar.gz: 243e5b1b0526550ba457c63b3228ed236bbde014dd33b0396cd979b57f167be81b090a13ee5df7187f82b20815d4f32058b66bbb411c345c57c8ed27dc0b957f
|
data/lib/WindowsInstaller.rb
CHANGED
@@ -69,7 +69,6 @@ class WindowsInstaller
|
|
69
69
|
raise "Failed to find product code for product: #{product_name}"
|
70
70
|
end
|
71
71
|
|
72
|
-
private
|
73
72
|
def self.product_info(installer, code)
|
74
73
|
raise 'Windows installer cannot be nil' if(installer.nil?)
|
75
74
|
hash = Hash.new
|
@@ -96,13 +95,13 @@ class WindowsInstaller
|
|
96
95
|
return hash
|
97
96
|
end
|
98
97
|
|
99
|
-
public
|
100
98
|
def self.dump_info(product_name)
|
101
99
|
installer = WIN32OLE.new('WindowsInstaller.Installer')
|
102
100
|
properties = product_info(installer, product_code_from_product_name(product_name, installer))
|
103
101
|
properties.each { |id, value| puts "#{id}: #{value}" }
|
104
102
|
end
|
105
103
|
|
104
|
+
private
|
106
105
|
def self.msi_records(msi_file)
|
107
106
|
records = {}
|
108
107
|
|
@@ -164,7 +163,7 @@ class WindowsInstaller
|
|
164
163
|
end
|
165
164
|
|
166
165
|
def self.execute(cmd)
|
167
|
-
command = Wixgem::Command.new(cmd)
|
166
|
+
command = Wixgem::Command.new(cmd, { quiet: true } )
|
168
167
|
#command[:debug] = true
|
169
168
|
command.execute
|
170
169
|
end
|
data/lib/command.rb
CHANGED
data/lib/wixgem.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
require 'SecureRandom'
|
3
2
|
require 'tmpdir.rb'
|
4
3
|
require 'rexml/document'
|
5
4
|
require "#{File.dirname(__FILE__)}/command.rb"
|
5
|
+
require 'SecureRandom'
|
6
6
|
|
7
7
|
module Wixgem
|
8
8
|
|
@@ -29,12 +29,12 @@ class Wix
|
|
29
29
|
|
30
30
|
def self.make_mergemodule(output_file, input)
|
31
31
|
gem_dir = File.dirname(__FILE__)
|
32
|
-
|
32
|
+
create_package(output_file, input)
|
33
33
|
end
|
34
34
|
|
35
35
|
def self.make_installation(output_file, input)
|
36
36
|
gem_dir = File.dirname(__FILE__)
|
37
|
-
|
37
|
+
create_package(output_file, input)
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
@@ -127,8 +127,33 @@ class Wix
|
|
127
127
|
return xml_doc
|
128
128
|
end
|
129
129
|
|
130
|
+
def self.modify_file_path(input, file)
|
131
|
+
return file unless(input.kind_of?(Hash) && input.has_key?(:modify_file_paths))
|
132
|
+
|
133
|
+
modify_paths = input[:modify_file_paths]
|
134
|
+
modify_paths.each { |regex, replacement_string| file = file.gsub(regex, replacement_string) }
|
135
|
+
|
136
|
+
return file
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.files(input)
|
140
|
+
files = input
|
141
|
+
files = input[:files] if(input.kind_of?(Hash))
|
142
|
+
|
143
|
+
files.each { |file| files.delete(file) if(File.directory?(file)) }
|
144
|
+
|
145
|
+
return files
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.ignore_files(input)
|
149
|
+
files = []
|
150
|
+
files = input[:ignore_files] if(input.kind_of?(Hash) && input.has_key?(:ignore_files))
|
151
|
+
|
152
|
+
return files
|
153
|
+
end
|
154
|
+
|
130
155
|
def self.copy_install_files(directory, input)
|
131
|
-
files = input
|
156
|
+
files = files(input)
|
132
157
|
raise 'No files were given to wixgem' if(files.length == 0)
|
133
158
|
|
134
159
|
missing_files = []
|
@@ -179,24 +204,119 @@ class Wix
|
|
179
204
|
end
|
180
205
|
end
|
181
206
|
|
182
|
-
def self.
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
207
|
+
def self.log_wix_output(cmd)
|
208
|
+
return unless(@debug && !@logger.nil?)
|
209
|
+
|
210
|
+
@logger << "----------------------------------------------------------------------------"
|
211
|
+
@logger << cmd
|
212
|
+
|
213
|
+
if(!cmd[:output].empty?)
|
214
|
+
@logger << "--------------------------- std output -----------------------------------"
|
215
|
+
@logger << cmd[:output]
|
216
|
+
end
|
217
|
+
|
218
|
+
if(!cmd[:error].empty?)
|
219
|
+
@logger << "--------------------------- std error ------------------------------------"
|
220
|
+
@logger << cmd[:error]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def self.modify_heat_commandline(input, cmd)
|
225
|
+
cmd = cmd.gsub(/-srd/, '-svb6 -srd') if(input.has_key?(:has_vb6_files) && input[:has_vb6_files])
|
188
226
|
cmd = cmd.gsub(/-srd/, '-sreg -srd') if(input.has_key?(:suppress_registry_harvesting) && input[:suppress_registry_harvesting])
|
189
227
|
cmd = cmd.gsub(/-srd/, '-scom -srd') if(input.has_key?(:suppress_COM_elements) && input[:suppress_COM_elements])
|
190
|
-
|
191
|
-
|
192
|
-
@logger << "command: #{heat_cmd[:command]}" if(@debug && !@logger.nil?)
|
228
|
+
return cmd
|
229
|
+
end
|
193
230
|
|
231
|
+
def self.execute_heat(input, cmd_line_options)
|
232
|
+
heat_cmd = Command.new("\"#{install_path}/bin/heat.exe\" #{modify_heat_commandline(input, cmd_line_options)}", { quiet: true })
|
194
233
|
heat_cmd.execute
|
195
|
-
|
196
|
-
|
197
|
-
|
234
|
+
log_wix_output(heat_cmd)
|
235
|
+
end
|
236
|
+
|
237
|
+
def self.execute_heat_file(wxs_file, input, template_option)
|
238
|
+
install_files = files(input)
|
239
|
+
modified_paths = []
|
240
|
+
install_files.each { |file| modified_paths << modify_file_path(input, file) }
|
241
|
+
install_files = modified_paths
|
242
|
+
|
243
|
+
install_ignore_files = ignore_files(input)
|
244
|
+
modified_paths = []
|
245
|
+
install_ignore_files.each { |file| modified_paths << modify_file_path(input, file) }
|
246
|
+
install_ignore_files = modified_paths
|
247
|
+
|
248
|
+
install_files.reject! { |f| install_ignore_files.include?(f) }
|
249
|
+
|
250
|
+
directory_fragments = {}
|
251
|
+
wxs_files = {}
|
252
|
+
install_files.each do |file|
|
253
|
+
windows_path = file.gsub(/\//, '\\')
|
254
|
+
|
255
|
+
filename = wxs_file
|
256
|
+
if(install_files.index(file) == 0)
|
257
|
+
execute_heat(input, "file \"#{windows_path}\" #{template_option} -cg InstallionFiles -gg -nologo -srd -o \"#{filename}\"")
|
258
|
+
else
|
259
|
+
filename = File.basename(wxs_file).gsub('.wxs', "-#{wxs_files.length}.wxs")
|
260
|
+
execute_heat(input, "file \"#{windows_path}\" -template fragment -gg -nologo -srd -o \"#{filename}\"")
|
261
|
+
wxs_files[file] = filename
|
262
|
+
end
|
263
|
+
|
264
|
+
directory_fragments[File.dirname(file)] = "dir#{SecureRandom.uuid.gsub(/-/,'')}"
|
265
|
+
xml_doc = REXML::Document.new(File.read(filename))
|
266
|
+
file_elements = REXML::XPath.match(xml_doc, '//Wix/Fragment/DirectoryRef/Component/File')
|
267
|
+
file_elements[0].attributes['Source'] = "SourceDir\\#{file.gsub(/\//,'\\')}" if(file_elements.length == 1)
|
268
|
+
file_elements[0].attributes['Id'] = "fil#{SecureRandom.uuid.gsub(/-/,'')}" if(file_elements.length == 1) # Assigning new Id, because the id is somehow generated from the filename. So it is possible for heat to generate duplicate id's
|
269
|
+
File.open(filename, 'w') { |f| f.puts(xml_doc.to_s) }
|
270
|
+
end
|
271
|
+
directory_fragments['.'] = 'TARGETDIR'
|
272
|
+
|
273
|
+
xml_doc = REXML::Document.new(File.read(wxs_file))
|
274
|
+
|
275
|
+
wix_elements = REXML::XPath.match(xml_doc, '//Wix')
|
276
|
+
raise "Invalid wxs file: #{wxs_file}" unless(wix_elements.length == 1)
|
277
|
+
|
278
|
+
directory_fragments.each do |key, id|
|
279
|
+
if(key != '.')
|
280
|
+
fragment_element = wix_elements[0].add_element 'Fragment'
|
281
|
+
directory_ref_element = fragment_element.add_element 'DirectoryRef', { 'Id' => directory_fragments[File.dirname(key)] }
|
282
|
+
directory_ref_element.add_element 'Directory', { 'Id' => id, 'Name' => File.basename(key) }
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
component_group_element = REXML::XPath.match(xml_doc, '//Wix/Fragment/ComponentGroup')
|
287
|
+
raise "Failed to create installation package for file: #{wxs_file}" unless(component_group_element.length == 1)
|
288
|
+
|
289
|
+
wxs_files.each do |file, filename|
|
290
|
+
xml_fragment_doc = REXML::Document.new(File.read(filename))
|
291
|
+
component_elements = REXML::XPath.match(xml_fragment_doc, '//Wix/Fragment/DirectoryRef/Component')
|
292
|
+
|
293
|
+
component_elements.each do |component_element|
|
294
|
+
component_element.attributes['Id'] = "cmp#{SecureRandom.uuid.gsub(/-/,'')}" # Assigning new Id, because the id is somehow generated from the filename. So it is possible for heat to generate duplicate id's
|
295
|
+
component_element = component_group_element[0].add_element component_element, { 'Directory' => directory_fragments[File.dirname(file)] }
|
296
|
+
end
|
198
297
|
end
|
199
|
-
|
298
|
+
|
299
|
+
formatter = REXML::Formatters::Pretty.new(2)
|
300
|
+
formatter.compact = true # This is the magic line that does what you need!
|
301
|
+
xml_text=''
|
302
|
+
formatter.write(xml_doc, xml_text)
|
303
|
+
File.open(wxs_file, 'w') { |f| f.puts xml_text }
|
304
|
+
end
|
305
|
+
|
306
|
+
def self.execute_heat_dir(wxs_file, input, template_option)
|
307
|
+
execute_heat(input,"dir . #{template_option} -cg InstallionFiles -gg -nologo -srd -o \"#{wxs_file}\"")
|
308
|
+
end
|
309
|
+
|
310
|
+
def self.create_wxs_file(wxs_file, input, ext)
|
311
|
+
template_option = "-template product"
|
312
|
+
template_option = "-template module" unless(ext == ".msi")
|
313
|
+
|
314
|
+
if(input.has_key?(:ignore_files))
|
315
|
+
execute_heat_file(wxs_file, input, template_option)
|
316
|
+
else
|
317
|
+
execute_heat_dir(wxs_file, input, template_option)
|
318
|
+
end
|
319
|
+
|
200
320
|
product_name = File.basename(wxs_file, '.wxs')
|
201
321
|
product_name = input[:product_name] if(input.has_key?(:product_name))
|
202
322
|
|
@@ -248,25 +368,15 @@ class Wix
|
|
248
368
|
wixobj_file = "#{File.basename(wxs_file,'.wxs')}.wixobj"
|
249
369
|
|
250
370
|
candle_cmd = Command.new("\"#{install_path}/bin/candle.exe\" -out \"#{wixobj_file}\" \"#{wxs_file}\"", { quiet: true })
|
251
|
-
@logger << "command: #{candle_cmd[:command]}" if(@debug && !@logger.nil?)
|
252
|
-
|
253
371
|
candle_cmd.execute
|
254
|
-
|
255
|
-
@logger << "--------------------------- Candle output -----------------------------------" unless(@logger.nil?)
|
256
|
-
@logger << candle_cmd[:output] unless(@logger.nil?)
|
257
|
-
end
|
372
|
+
log_wix_output(candle_cmd)
|
258
373
|
|
259
374
|
light_cmd = Command.new("\"#{install_path}/bin/light.exe\" -nologo -out \"#{output}\" \"#{wixobj_file}\"", { quiet: true })
|
260
|
-
@logger << "command: #{light_cmd[:command]}" if(@debug && !@logger.nil?)
|
261
|
-
|
262
375
|
light_cmd.execute
|
263
|
-
|
264
|
-
@logger << "--------------------------- Light output -----------------------------------" unless(@logger.nil?)
|
265
|
-
@logger << light_cmd[:output] unless(@logger.nil?)
|
266
|
-
end
|
376
|
+
log_wix_output(light_cmd)
|
267
377
|
end
|
268
378
|
|
269
|
-
def self.
|
379
|
+
def self.create_package(output, input)
|
270
380
|
raise 'WIX path is not set!' if(install_path.nil?)
|
271
381
|
input = { files: input } unless(input.kind_of?(Hash))
|
272
382
|
@debug = input[:debug] if(!@debug && input.has_key?(:debug))
|
@@ -281,6 +391,9 @@ class Wix
|
|
281
391
|
|
282
392
|
output_absolute_path = File.absolute_path(output)
|
283
393
|
|
394
|
+
#dir = './tmp_dir'
|
395
|
+
#FileUtils.rm_rf(dir) if(Dir.exists?(dir))
|
396
|
+
#FileUtils.mkdir(dir)
|
284
397
|
Dir.mktmpdir do |dir|
|
285
398
|
copy_install_files(dir, input)
|
286
399
|
|
metadata
CHANGED
@@ -1,69 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wixgem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.48.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Marshall
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01
|
11
|
+
date: 2015-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: dev
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
description: Simple Ruby interface to facilitate creating and compiling windows installation
|
@@ -81,7 +81,6 @@ files:
|
|
81
81
|
- example/install_files/file1.txt
|
82
82
|
- example/rakefile.rb
|
83
83
|
- lib/WindowsInstaller.rb
|
84
|
-
- lib/WindowsInstaller_hold.rb
|
85
84
|
- lib/command.rb
|
86
85
|
- lib/wixgem.rb
|
87
86
|
homepage: http://rubygems.org/gems/wixgem
|
@@ -94,17 +93,17 @@ require_paths:
|
|
94
93
|
- lib
|
95
94
|
required_ruby_version: !ruby/object:Gem::Requirement
|
96
95
|
requirements:
|
97
|
-
- -
|
96
|
+
- - '>='
|
98
97
|
- !ruby/object:Gem::Version
|
99
98
|
version: 1.9.1
|
100
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
100
|
requirements:
|
102
|
-
- -
|
101
|
+
- - '>='
|
103
102
|
- !ruby/object:Gem::Version
|
104
103
|
version: '0'
|
105
104
|
requirements: []
|
106
105
|
rubyforge_project:
|
107
|
-
rubygems_version: 2.2.
|
106
|
+
rubygems_version: 2.2.0
|
108
107
|
signing_key:
|
109
108
|
specification_version: 4
|
110
109
|
summary: Simple Ruby interface to facilitate working with Wix Toolset
|
@@ -1,156 +0,0 @@
|
|
1
|
-
require 'win32ole'
|
2
|
-
require 'dev_tasks'
|
3
|
-
|
4
|
-
module Wixgem
|
5
|
-
|
6
|
-
class WindowsInstaller
|
7
|
-
def self.install(msi_file)
|
8
|
-
msi_file = msi_file.gsub(/\//, '\\')
|
9
|
-
raise "#{msi_file} is already installed" if(WindowsInstaller.installed?(msi_file))
|
10
|
-
execute("msiexec.exe /i #{msi_file}")
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.uninstall(msi_file)
|
14
|
-
raise "#{msi_file} does not exist!" unless(File.exists?(msi_file))
|
15
|
-
|
16
|
-
info = msi_properties(installer, msi_file)
|
17
|
-
uninstall_product_code(info['ProductCode'])
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.uninstall_product_name(product_name)
|
21
|
-
raise "#{product_name} is not installed" unless(product_name_installed?(product_name))
|
22
|
-
uninstall_product_code(product_code_from_product_name(product_name))
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.uninstall_product_code(product_code)
|
26
|
-
raise "#{product_code} is not installed" unless(product_code_installed?(product_code))
|
27
|
-
execute("msiexec.exe /quiet /x #{product_code}")
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.msi_installed?(msi_file)
|
31
|
-
info = msi_properties(msi_file)
|
32
|
-
return product_code_installed?(info['ProductCode'])
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.product_name_installed?(product_name)
|
36
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer')
|
37
|
-
installer.Products.each { |prod_code|
|
38
|
-
name = installer.ProductInfo(prod_code, "ProductName")
|
39
|
-
return true if (product_name == name)
|
40
|
-
}
|
41
|
-
return false
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.product_code_installed?(product_code)
|
45
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer')
|
46
|
-
installer.Products.each { |installed_product_code| return true if (product_code == installed_product_code) }
|
47
|
-
return false
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.product_name_installed_version(product_name)
|
51
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer')
|
52
|
-
info = product_info(installer, product_code_from_product_name(product_name, installer))
|
53
|
-
return info['VersionString']
|
54
|
-
end
|
55
|
-
|
56
|
-
private
|
57
|
-
def self.product_code_from_msi(msi_file, installer = nil)
|
58
|
-
msi_info = msi_properties(msi_file)
|
59
|
-
return msi_info['ProductCode']
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.product_code_from_product_name(product_name, installer = nil)
|
63
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer') if(installer.nil?)
|
64
|
-
installer.Products.each { |prod_code|
|
65
|
-
name = installer.ProductInfo(prod_code, "ProductName")
|
66
|
-
return prod_code if (product_name == name)
|
67
|
-
}
|
68
|
-
raise "Failed to find product code for product: #{product_name}"
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.product_code_properties(product_code, installer = nil)
|
72
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer') if(installer.nil?)
|
73
|
-
hash = Hash.new
|
74
|
-
# known product keywords found on internet. Would be nice to generate.
|
75
|
-
%w[Language PackageCode Transforms AssignmentType PackageName InstalledProductName VersionString RegCompany
|
76
|
-
RegOwner ProductID ProductIcon InstallLocation InstallSource InstallDate Publisher LocalPackage HelpLink
|
77
|
-
HelpTelephone URLInfoAbout URLUpdateInfo InstanceType].sort.each do |prop|
|
78
|
-
value = installer.ProductInfo(product_code, prop)
|
79
|
-
hash[prop] = value unless(value.nil? || value == '')
|
80
|
-
end
|
81
|
-
return hash
|
82
|
-
end
|
83
|
-
|
84
|
-
def self.print_properties(product_name)
|
85
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer')
|
86
|
-
properties = product_info(installer, product_code(product_name, installer))
|
87
|
-
properties.each { |id, value| puts "#{id}: #{value}" }
|
88
|
-
end
|
89
|
-
|
90
|
-
def self.msi_records(msi_file)
|
91
|
-
records = {}
|
92
|
-
|
93
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer')
|
94
|
-
sql_query = "SELECT * FROM `Property`"
|
95
|
-
|
96
|
-
db = installer.OpenDatabase(msi_file, 0)
|
97
|
-
|
98
|
-
view = db.OpenView(sql_query)
|
99
|
-
view.Execute(nil)
|
100
|
-
|
101
|
-
record = view.Fetch()
|
102
|
-
return '' if(record == nil)
|
103
|
-
|
104
|
-
while(!record.nil?)
|
105
|
-
records[record.StringData(1)] = record.StringData(2)
|
106
|
-
record = view.Fetch()
|
107
|
-
end
|
108
|
-
db.ole_free
|
109
|
-
db = nil
|
110
|
-
installer.ole_free
|
111
|
-
installer = nil
|
112
|
-
|
113
|
-
return records
|
114
|
-
end
|
115
|
-
|
116
|
-
def self.print_msi_records(msi_file)
|
117
|
-
records = msi_records(msi_file)
|
118
|
-
|
119
|
-
puts "#{msi_file} Properties:"
|
120
|
-
records.each do |key,value|
|
121
|
-
puts "#{key}: #{value}"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def self.print_product_name(product_name)
|
126
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer')
|
127
|
-
# only one session per process!
|
128
|
-
session = installer.OpenProduct(product_code_from_product_name?(product_name, installer))
|
129
|
-
db = session.Database
|
130
|
-
|
131
|
-
sql_query = "SELECT * FROM `Property`"
|
132
|
-
view = db.OpenView(sql_query)
|
133
|
-
view.Execute(nil)
|
134
|
-
|
135
|
-
record = view.Fetch()
|
136
|
-
return '' if(record == nil)
|
137
|
-
|
138
|
-
puts "Session Properties:"
|
139
|
-
while(!record.nil?)
|
140
|
-
puts "#{record.StringData(1)}: #{record.StringData(2)}"
|
141
|
-
record = view.Fetch()
|
142
|
-
end
|
143
|
-
db.ole_free
|
144
|
-
db = nil
|
145
|
-
installer.ole_free
|
146
|
-
installer = nil
|
147
|
-
puts ''
|
148
|
-
end
|
149
|
-
|
150
|
-
def self.execute(cmd)
|
151
|
-
command = Wixgem::Command.new(cmd)
|
152
|
-
command.execute
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
end
|