chef/cookbooks/uber_helpers/libraries/win_utils.rb (59 lines of code) (raw):

# # Cookbook:: uber_helpers # Libraries:: win_utils # # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2 # # Copyright:: (c) 2019-present, Uber Technologies, Inc. # All rights reserved. # # This source code is licensed under the Apache 2.0 license found in the # LICENSE file in the root directory of this source tree. # if Chef::Platform.windows? module UberHelpers class WinUtils def self.win_pkg_ver(win_pkg_name) require 'win32/registry' pkg_version = nil # Begin Checking HKEY_LOCAL_MACHINE paths for install. { 'HKEY_LOCAL_MACHINE' => [ 'Software\Microsoft\Windows\CurrentVersion\Uninstall', 'Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall', 'Software\Wow6464Node\Microsoft\Windows\CurrentVersion\Uninstall', ], 'HKEY_CURRENT_USER' => [ 'Software\Microsoft\Windows\CurrentVersion\Uninstall', ], }.each do |reg_loc, reg_path| # dont process path if the version has already been discovered break unless pkg_version.nil? # Begin loop to check and process each registry path reg_path.each do |rpath| # break out of loop if pkg_version already found break unless pkg_version.nil? # break if the registry path does not exist break unless reg_path_exist?(reg_loc, rpath) win32_name = "::Win32::Registry::#{reg_loc}" win32_class = Object.const_get(win32_name) # Read in the path and get child keys reg = win32_class.open(rpath) # query each of the subkeys reg.each_key do |key| # break out of loop if already found break unless pkg_version.nil? # open subkey and peak inside k = reg.open(key) begin # assign variable to each key pkg_name = k['DisplayName'] pkg_ver = k['DisplayVersion'] # make sure that the result can get a similiar to exact match. if pkg_name && pkg_ver && pkg_name.include?(win_pkg_name) # update the pkg_version from 0 to discovered version. pkg_version = pkg_ver # close the keypath k.close # break out of this path search once a match is made. break end rescue StandardError # process next subkey on error. next end # close the open key only if pkg_version hasnt been found. break unless pkg_version.nil? k.close end reg.close end end return pkg_version end # returns windows friendly version of the provided path, # ensures backslashes are used everywhere def self.friendly_path(path) path.gsub(::File::SEPARATOR, ::File::ALT_SEPARATOR || '\\') if path end def self.reg_path_exist?(reg_loc, reg_path) win32_name = "::Win32::Registry::#{reg_loc}" win32_class = Object.const_get(win32_name) win32_class.open(reg_path, ::Win32::Registry::KEY_READ) return true rescue StandardError return false end end end end