wixgem 0.51.0 → 0.52.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/file.rb +12 -0
- data/lib/wixgem.rb +28 -11
- metadata +14 -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: 376a8d999276896e4a22446302a584e87df03512
|
4
|
+
data.tar.gz: 0155ff161195f3fda15d0d9afbbdd3a334c22b4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 781dc60e500e721ea9d095cb3b5684ba29d25fd35ef0545fe975a7e198198c0146baa5d62a032095358feb3b315d2e733b2fab955a471aedd53bec7a1dfb1bc9
|
7
|
+
data.tar.gz: 59b2d7426b082f5f9e85276298ba749902653a63858cdc594604836bad8fa4a315a42b2551c9401205923d263518d637856425eeb066504cc1104878684d759c
|
data/lib/file.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'fiddle'
|
2
|
+
|
3
|
+
class File
|
4
|
+
FILE_ATTRIBUTE_READONLY="0x1".hex
|
5
|
+
def self.read_only?(path)
|
6
|
+
return false unless(File.exists?(path))
|
7
|
+
kernel32 = Fiddle::Handle.new("kernel32")
|
8
|
+
get_file_attributes = Fiddle::Function.new(kernel32['GetFileAttributesA'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_LONG)
|
9
|
+
|
10
|
+
return ((get_file_attributes.call(path) & FILE_ATTRIBUTE_READONLY) == 1) ? true : false;
|
11
|
+
end
|
12
|
+
end
|
data/lib/wixgem.rb
CHANGED
@@ -3,6 +3,8 @@ require 'tmpdir.rb'
|
|
3
3
|
require 'rexml/document'
|
4
4
|
require "#{File.dirname(__FILE__)}/command.rb"
|
5
5
|
require 'SecureRandom'
|
6
|
+
require 'fiddle'
|
7
|
+
require_relative('file.rb')
|
6
8
|
|
7
9
|
module Wixgem
|
8
10
|
|
@@ -126,6 +128,23 @@ class Wix
|
|
126
128
|
|
127
129
|
return xml_doc
|
128
130
|
end
|
131
|
+
|
132
|
+
def self.manage_read_only_files(xml_doc,input)
|
133
|
+
install_files = files(input)
|
134
|
+
|
135
|
+
install_files.each do |file|
|
136
|
+
absolute_path = file
|
137
|
+
absolute_path = "#{input[:files_root_dir]}/#{file}" unless(File.exists?(file))
|
138
|
+
|
139
|
+
if(File.read_only?(absolute_path))
|
140
|
+
install_path = ".\\#{self.modify_file_path(input, file)}"
|
141
|
+
file_elements = REXML::XPath.match(xml_doc, "//File[@Source='#{install_path}']")
|
142
|
+
file_elements[0].attributes['ReadOnly'] = 'yes' if(file_elements.length == 1)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
return xml_doc
|
147
|
+
end
|
129
148
|
|
130
149
|
def self.modify_file_path(input, file)
|
131
150
|
return file unless(input.kind_of?(Hash) && input.has_key?(:modify_file_paths))
|
@@ -139,9 +158,6 @@ class Wix
|
|
139
158
|
def self.files(input)
|
140
159
|
files = input
|
141
160
|
files = input[:files] if(input.kind_of?(Hash))
|
142
|
-
|
143
|
-
files.each { |file| files.delete(file) if(File.directory?(file)) }
|
144
|
-
|
145
161
|
return files
|
146
162
|
end
|
147
163
|
|
@@ -166,7 +182,7 @@ class Wix
|
|
166
182
|
|
167
183
|
install_path = "#{directory}/#{install_path}"
|
168
184
|
FileUtils.mkpath(File.dirname(install_path)) unless(Dir.exists?(File.dirname(install_path)))
|
169
|
-
FileUtils.cp(file, install_path)
|
185
|
+
FileUtils.cp(file, install_path, { preserve: true })
|
170
186
|
elsif(!File.exists?(file))
|
171
187
|
missing_files.insert(missing_files.length, file)
|
172
188
|
end
|
@@ -368,6 +384,7 @@ class Wix
|
|
368
384
|
xml_doc = manage_custom_actions(xml_doc, input)
|
369
385
|
xml_doc = manage_upgrade(xml_doc,input)
|
370
386
|
xml_doc = manage_msm_files(xml_doc)
|
387
|
+
xml_doc = manage_read_only_files(xml_doc,input)
|
371
388
|
|
372
389
|
File.open(wxs_file, 'w') { |f| f.puts(xml_doc.to_s) }
|
373
390
|
#formatter = REXML::Formatters::Pretty.new(2)
|
@@ -390,18 +407,17 @@ class Wix
|
|
390
407
|
end
|
391
408
|
|
392
409
|
def self.verify_input_keys(input)
|
393
|
-
|
394
|
-
|
395
|
-
|
410
|
+
input[:files].reject! { |f| File.directory?(f) }
|
411
|
+
|
412
|
+
[:files,:ignore_files].each { |key| raise "Hash key #{key} cannot be nil" if(input.has_key?(key) && input[key].nil?)}
|
396
413
|
end
|
397
414
|
|
398
415
|
def self.create_package(output, input)
|
399
416
|
raise 'WIX path is not set!' if(install_path.nil?)
|
400
|
-
|
401
|
-
verify_input_keys(input)
|
402
|
-
|
403
417
|
input = { files: input } unless(input.kind_of?(Hash))
|
404
|
-
|
418
|
+
verify_input_keys(input)
|
419
|
+
|
420
|
+
@debug = input[:debug] if(!@debug && input.has_key?(:debug))
|
405
421
|
|
406
422
|
start_logger if(@debug)
|
407
423
|
|
@@ -412,6 +428,7 @@ class Wix
|
|
412
428
|
FileUtils.rm(output) if(File.exists?(output))
|
413
429
|
|
414
430
|
output_absolute_path = File.absolute_path(output)
|
431
|
+
input[:files_root_dir] = Dir.pwd
|
415
432
|
|
416
433
|
#dir = './tmp_dir'
|
417
434
|
#FileUtils.rm_rf(dir) if(Dir.exists?(dir))
|
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.52.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-
|
11
|
+
date: 2015-03-22 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,8 +81,8 @@ 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
|
85
|
+
- lib/file.rb
|
86
86
|
- lib/wixgem.rb
|
87
87
|
homepage: http://rubygems.org/gems/wixgem
|
88
88
|
licenses:
|
@@ -94,17 +94,17 @@ require_paths:
|
|
94
94
|
- lib
|
95
95
|
required_ruby_version: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
|
-
- -
|
97
|
+
- - '>='
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: 1.9.1
|
100
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- -
|
102
|
+
- - '>='
|
103
103
|
- !ruby/object:Gem::Version
|
104
104
|
version: '0'
|
105
105
|
requirements: []
|
106
106
|
rubyforge_project:
|
107
|
-
rubygems_version: 2.2.
|
107
|
+
rubygems_version: 2.2.0
|
108
108
|
signing_key:
|
109
109
|
specification_version: 4
|
110
110
|
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
|