WindowsInstaller 0.1.8 → 0.1.9
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 +82 -42
- metadata +16 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4b02f7b76db9098d099061851306f4e8b2281d72
|
4
|
+
data.tar.gz: 95c25ad242617d7e9bc91dd07a45e924e0765dc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d49221e68bc561f5f56c0f79d61554ac88e105928b209b2c4e1892a386d3147099a78fb4952df958e3f57bb3822cfe1a16edcf31f1968e3f926ac663fc7c986
|
7
|
+
data.tar.gz: 048f2955c009333b2e10a2b1fe2b18eea04ba467d673f820a3bb9950e5fedd7afee1fdbcd7303d62024f63f16032084be19c2d66e837931c28f93ae4a1600fb7
|
data/lib/WindowsInstaller.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'win32ole'
|
2
|
-
require '
|
2
|
+
require 'cmd'
|
3
3
|
require 'sys/proctable'
|
4
|
-
require 'tempfile'
|
5
4
|
|
6
5
|
class WindowsInstaller < Hash
|
7
6
|
@@default_options = {mode: '/passive'}
|
@@ -9,20 +8,28 @@ class WindowsInstaller < Hash
|
|
9
8
|
def initialize(options = {})
|
10
9
|
@@default_options.each { |key, value| self[key] = value }
|
11
10
|
options.each { |key, value| self[key] = value}
|
11
|
+
|
12
|
+
@installer = WIN32OLE.new('WindowsInstaller.Installer')
|
12
13
|
end
|
13
14
|
|
14
15
|
def self.default_options(hash)
|
15
16
|
hash.each { |key,value| @@default_options[key] = value }
|
16
17
|
end
|
17
18
|
|
18
|
-
def msi_installed?(msi_file)
|
19
|
+
def msi_installed?(msi_file)
|
19
20
|
info = msi_properties(msi_file)
|
20
21
|
return product_code_installed?(info['ProductCode'])
|
21
22
|
end
|
23
|
+
|
24
|
+
def product_installed?(product_name)
|
25
|
+
product_code = installed_get_product_code(product_name)
|
26
|
+
return false if(product_code.empty?)
|
27
|
+
|
28
|
+
return product_code_installed?(product_code)
|
29
|
+
end
|
22
30
|
|
23
31
|
def product_code_installed?(product_code)
|
24
|
-
|
25
|
-
installer.Products.each { |installed_product_code| return true if (product_code == installed_product_code) }
|
32
|
+
@installer.Products.each { |installed_product_code| return true if (product_code == installed_product_code) }
|
26
33
|
return false
|
27
34
|
end
|
28
35
|
|
@@ -58,30 +65,14 @@ class WindowsInstaller < Hash
|
|
58
65
|
end
|
59
66
|
end
|
60
67
|
|
61
|
-
private
|
62
|
-
def installed_properties(product_code)
|
63
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer')
|
64
|
-
|
65
|
-
hash = Hash.new
|
66
|
-
# known product keywords found on internet. Would be nice to generate.
|
67
|
-
%w[Language PackageCode Transforms AssignmentType PackageName InstalledProductName VersionString RegCompany
|
68
|
-
RegOwner ProductID ProductIcon InstallLocation InstallSource InstallDate Publisher LocalPackage HelpLink
|
69
|
-
HelpTelephone URLInfoAbout URLUpdateInfo InstanceType].sort.each do |prop|
|
70
|
-
value = installer.ProductInfo(product_code, prop)
|
71
|
-
hash[prop] = value unless(value.nil? || value == '')
|
72
|
-
end
|
73
|
-
return hash
|
74
|
-
end
|
75
|
-
|
76
68
|
def msi_properties(msi_file)
|
77
69
|
raise "#{msi_file} does not exist!" unless(File.exists?(msi_file))
|
78
70
|
|
79
71
|
properties = {}
|
80
72
|
|
81
|
-
installer = WIN32OLE.new('WindowsInstaller.Installer')
|
82
73
|
sql_query = "SELECT * FROM `Property`"
|
83
74
|
|
84
|
-
db = installer.OpenDatabase(msi_file, 0)
|
75
|
+
db = @installer.OpenDatabase(msi_file, 0)
|
85
76
|
view = db.OpenView(sql_query)
|
86
77
|
view.Execute(nil)
|
87
78
|
|
@@ -94,35 +85,84 @@ class WindowsInstaller < Hash
|
|
94
85
|
end
|
95
86
|
db.ole_free
|
96
87
|
db = nil
|
97
|
-
|
98
|
-
installer.ole_free
|
99
|
-
installer = nil
|
100
88
|
|
101
89
|
return properties
|
102
90
|
end
|
103
91
|
|
104
|
-
def
|
105
|
-
|
106
|
-
|
92
|
+
def installation_properties(product_name)
|
93
|
+
product_code = installed_get_product_code(product_name)
|
94
|
+
return nil if(product_code == '')
|
95
|
+
|
96
|
+
return installed_properties(product_code)
|
107
97
|
end
|
108
98
|
|
109
99
|
private
|
110
|
-
def
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
100
|
+
def installed_get_product_code(product_name)
|
101
|
+
return '' if(product_name.empty?)
|
102
|
+
|
103
|
+
@installer.Products.each do |product_code|
|
104
|
+
name = @installer.ProductInfo(product_code, "ProductName")
|
105
|
+
return product_code if (product_name == name)
|
106
|
+
end
|
107
|
+
|
108
|
+
return ''
|
116
109
|
end
|
117
110
|
|
118
|
-
def
|
119
|
-
|
120
|
-
reg_file = File.read("#{lib_directory}/always_install_elevated_template.reg")
|
121
|
-
reg_file=reg_file.gsub(/VALUE/,value)
|
122
|
-
file = Tempfile.new('wininst')
|
123
|
-
file.write(reg_file)
|
111
|
+
def installed_properties(product_code)
|
112
|
+
return nil if(!product_code_installed?(product_code))
|
124
113
|
|
125
|
-
|
126
|
-
|
114
|
+
hash = Hash.new
|
115
|
+
# known product keywords found on internet. Would be nice to generate.
|
116
|
+
%w[Language PackageCode Transforms AssignmentType PackageName InstalledProductName VersionString RegCompany
|
117
|
+
RegOwner ProductID ProductIcon InstallLocation InstallSource InstallDate Publisher LocalPackage HelpLink
|
118
|
+
HelpTelephone URLInfoAbout URLUpdateInfo InstanceType].sort.each do |prop|
|
119
|
+
value = @installer.ProductInfo(product_code, prop)
|
120
|
+
hash[prop] = value unless(value.nil? || value == '')
|
121
|
+
end
|
122
|
+
hash['ProductCode'] = product_code
|
123
|
+
return hash
|
124
|
+
end
|
125
|
+
|
126
|
+
def msiexec(cmd)
|
127
|
+
cmd_options = { echo_command: false, echo_output: false} unless(self[:debug])
|
128
|
+
if(self.has_key?(:administrative_user))
|
129
|
+
msiexec_admin(cmd, cmd_options)
|
130
|
+
else
|
131
|
+
command = CMD.new(cmd, cmd_options)
|
132
|
+
command.execute
|
133
|
+
end
|
127
134
|
end
|
135
|
+
|
136
|
+
def msiexec_admin(cmd, options)
|
137
|
+
cmd = "runas /noprofile /savecred /user:#{self[:administrative_user]} \"#{cmd}\""
|
138
|
+
command = CMD.new(cmd, options)
|
139
|
+
wait_on_spawned(cmd) { cmd.execute }
|
140
|
+
end
|
141
|
+
|
142
|
+
def wait_on_spawned_process(cmd)
|
143
|
+
pre_execute = Sys::ProcTable.ps
|
144
|
+
|
145
|
+
pre_pids = []
|
146
|
+
pre_execute.each { |ps| pre_pids << ps.pid }
|
147
|
+
|
148
|
+
yield
|
149
|
+
|
150
|
+
exe = cmd[:command].match(/\\(?<path>.+\.exe)/i).named_captures['path']
|
151
|
+
exe = File.basename(exe)
|
152
|
+
#puts "Exe: #{exe}"
|
153
|
+
|
154
|
+
msiexe_pid = 0
|
155
|
+
post_execute = Sys::ProcTable.ps
|
156
|
+
post_execute.each do |ps|
|
157
|
+
msiexe_pid = ps.pid if((ps.name.downcase == exe.downcase) && pre_pids.index(ps.pid).nil?)
|
158
|
+
end
|
159
|
+
|
160
|
+
if(msiexe_pid != 0)
|
161
|
+
loop do
|
162
|
+
s = Sys::ProcTable.ps(msiexe_pid)
|
163
|
+
break if(s.nil?)
|
164
|
+
sleep(1)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
128
168
|
end
|
metadata
CHANGED
@@ -1,83 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: WindowsInstaller
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.9
|
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-11-15 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
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: execute
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - ~>
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
description: Class wrapper for Microsoft Windows WindowsInstaller object
|
@@ -88,7 +88,7 @@ extra_rdoc_files: []
|
|
88
88
|
files:
|
89
89
|
- LICENSE
|
90
90
|
- lib/WindowsInstaller.rb
|
91
|
-
homepage: http://rubygems.org/gems/
|
91
|
+
homepage: http://rubygems.org/gems/WindowsExecute
|
92
92
|
licenses:
|
93
93
|
- Apache 2.0
|
94
94
|
metadata: {}
|
@@ -98,19 +98,18 @@ require_paths:
|
|
98
98
|
- lib
|
99
99
|
required_ruby_version: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: 1.9.1
|
104
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
|
-
- -
|
106
|
+
- - ">="
|
107
107
|
- !ruby/object:Gem::Version
|
108
108
|
version: '0'
|
109
109
|
requirements: []
|
110
110
|
rubyforge_project:
|
111
|
-
rubygems_version: 2.
|
111
|
+
rubygems_version: 2.4.5.1
|
112
112
|
signing_key:
|
113
113
|
specification_version: 4
|
114
114
|
summary: Class wrapper for Microsoft Windows WindowsInstaller object
|
115
115
|
test_files: []
|
116
|
-
has_rdoc:
|