mono_reg_utils.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import os
  2. import platform
  3. if os.name == 'nt':
  4. import sys
  5. import winreg
  6. def _reg_open_key(key, subkey):
  7. try:
  8. return winreg.OpenKey(key, subkey)
  9. except (WindowsError, OSError):
  10. if platform.architecture()[0] == '32bit':
  11. bitness_sam = winreg.KEY_WOW64_64KEY
  12. else:
  13. bitness_sam = winreg.KEY_WOW64_32KEY
  14. return winreg.OpenKey(key, subkey, 0, winreg.KEY_READ | bitness_sam)
  15. def _reg_open_key_bits(key, subkey, bits):
  16. sam = winreg.KEY_READ
  17. if platform.architecture()[0] == '32bit':
  18. if bits == '64':
  19. # Force 32bit process to search in 64bit registry
  20. sam |= winreg.KEY_WOW64_64KEY
  21. else:
  22. if bits == '32':
  23. # Force 64bit process to search in 32bit registry
  24. sam |= winreg.KEY_WOW64_32KEY
  25. return winreg.OpenKey(key, subkey, 0, sam)
  26. def _find_mono_in_reg(subkey, bits):
  27. try:
  28. with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey:
  29. value = winreg.QueryValueEx(hKey, 'SdkInstallRoot')[0]
  30. return value
  31. except (WindowsError, OSError):
  32. return None
  33. def _find_mono_in_reg_old(subkey, bits):
  34. try:
  35. with _reg_open_key_bits(winreg.HKEY_LOCAL_MACHINE, subkey, bits) as hKey:
  36. default_clr = winreg.QueryValueEx(hKey, 'DefaultCLR')[0]
  37. if default_clr:
  38. return _find_mono_in_reg(subkey + '\\' + default_clr, bits)
  39. return None
  40. except (WindowsError, EnvironmentError):
  41. return None
  42. def find_mono_root_dir(bits):
  43. root_dir = _find_mono_in_reg(r'SOFTWARE\Mono', bits)
  44. if root_dir is not None:
  45. return str(root_dir)
  46. root_dir = _find_mono_in_reg_old(r'SOFTWARE\Novell\Mono', bits)
  47. if root_dir is not None:
  48. return str(root_dir)
  49. return ''
  50. def find_msbuild_tools_path_reg():
  51. import subprocess
  52. vswhere = os.getenv('PROGRAMFILES(X86)')
  53. if not vswhere:
  54. vswhere = os.getenv('PROGRAMFILES')
  55. vswhere += r'\Microsoft Visual Studio\Installer\vswhere.exe'
  56. vswhere_args = ['-latest', '-products', '*', '-requires', 'Microsoft.Component.MSBuild']
  57. try:
  58. lines = subprocess.check_output([vswhere] + vswhere_args).splitlines()
  59. for line in lines:
  60. parts = line.decode("utf-8").split(':', 1)
  61. if len(parts) < 2 or parts[0] != 'installationPath':
  62. continue
  63. val = parts[1].strip()
  64. if not val:
  65. raise ValueError('Value of `installationPath` entry is empty')
  66. # Since VS2019, the directory is simply named "Current"
  67. msbuild_dir = os.path.join(val, 'MSBuild\\Current\\Bin')
  68. if os.path.isdir(msbuild_dir):
  69. return msbuild_dir
  70. # Directory name "15.0" is used in VS 2017
  71. return os.path.join(val, 'MSBuild\\15.0\\Bin')
  72. raise ValueError('Cannot find `installationPath` entry')
  73. except ValueError as e:
  74. print('Error reading output from vswhere: ' + e.message)
  75. except WindowsError:
  76. pass # Fine, vswhere not found
  77. except (subprocess.CalledProcessError, OSError):
  78. pass
  79. # Try to find 14.0 in the Registry
  80. try:
  81. subkey = r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0'
  82. with _reg_open_key(winreg.HKEY_LOCAL_MACHINE, subkey) as hKey:
  83. value = winreg.QueryValueEx(hKey, 'MSBuildToolsPath')[0]
  84. return value
  85. except (WindowsError, OSError):
  86. return ''