1 /** 2 * Copyright: Copyright (c) 2011 Nick Sabalausky. All rights reserved. 3 * Authors: Nick Sabalausky 4 * Version: Initial created: Jun 4, 2011 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 6 */ 7 module dvm.util.DvmRegistry; 8 9 version (Windows): 10 11 /// DVM-Specific Registry Utilities 12 13 import tango.io.Console; 14 import tango.io.Stdout; 15 import tango.text.Unicode; 16 17 import mambo.core._; 18 import Path = dvm.io.Path; 19 import dvm.io.Console; 20 import dvm.util.Registry; 21 import dvm.util.Windows; 22 import dvm.util.Util; 23 24 private string dvmEnvVar = "DVM"; 25 26 void updateEnvironment (string binDir, string dmdDir="") 27 { 28 string dvmEnvVarExpand = "%"~dvmEnvVar~"%"; 29 binDir = Path.native(binDir.dup); 30 dmdDir = Path.native(dmdDir.dup); 31 string dvmEnvValue = (dmdDir == "")? binDir : dmdDir~";"~binDir; 32 33 scope envKey = new RegistryKey(RegRoot.HKEY_CURRENT_USER, "Environment"); 34 envKey.setValue(dvmEnvVar, dvmEnvValue); 35 36 if (envKey.valueExists("PATH")) 37 { 38 auto path = envKey.getValue("PATH"); 39 40 if (path.type != RegValueType.SZ && path.type != RegValueType.EXPAND_SZ) 41 throw new RegistryException(envKey.toString ~ `\PATH`, false, "Expected type REG_SZ or REG_EXPAND_SZ, not " ~ dvm.util.Registry.toString(path.type)); 42 43 if (!path.asString.contains(dvmEnvVarExpand)) 44 envKey.setValueExpand("PATH", dvmEnvVarExpand ~ ";" ~ path.asString); 45 } 46 47 else 48 envKey.setValueExpand("PATH", dvmEnvVarExpand); 49 } 50 51 /// Returns empty string if there's no default compiler 52 string getDefaultCompilerPath() 53 { 54 scope envKeyRead = new RegistryKey(RegRoot.HKEY_CURRENT_USER, "Environment", RegKeyOpenMode.Open, RegKeyAccess.Read); 55 if (envKeyRead.valueExists(dvmEnvVar)) 56 { 57 auto pathValue = envKeyRead.getValue(dvmEnvVar); 58 59 if (pathValue.type == RegValueType.SZ || pathValue.type == RegValueType.EXPAND_SZ) 60 { 61 auto bothPaths = pathValue.asString; 62 auto sepIndex = bothPaths.indexOf(";"); 63 64 if (sepIndex < sepIndex.max) 65 return bothPaths[0..sepIndex]; 66 } 67 } 68 69 return ""; 70 } 71 72 bool isDMDDir(string path) 73 { 74 path = expandEnvironmentStrings(path); 75 76 foreach (singlePath; split(path, ";")) 77 { 78 Path.native(singlePath); 79 if (singlePath.length != 0 && singlePath[$-1] != '\\') 80 singlePath ~= '\\'; 81 82 if (Path.exists(singlePath) && Path.isFolder(singlePath)) 83 { 84 if ( (Path.exists(singlePath~"dmd.exe") && Path.isFile(singlePath~"dmd.exe")) || 85 (Path.exists(singlePath~"dmd.bat") && Path.isFile(singlePath~"dmd.bat")) ) 86 return true; 87 } 88 } 89 90 return false; 91 } 92 93 void checkSystemPath() 94 { 95 auto envKeyPath = `SYSTEM\CurrentControlSet\Control\Session Manager\Environment`; 96 scope envKeyRead = new RegistryKey(RegRoot.HKEY_LOCAL_MACHINE, envKeyPath, RegKeyOpenMode.Open, RegKeyAccess.Read); 97 if (envKeyRead.valueExists("PATH")) 98 { 99 auto pathValue = envKeyRead.getValue("PATH"); 100 101 if (pathValue.type != RegValueType.SZ && pathValue.type != RegValueType.EXPAND_SZ) 102 throw new RegistryException(envKeyRead.toString ~ `\PATH`, false, "Expected type REG_SZ or REG_EXPAND_SZ, not " ~ dvm.util.Registry.toString(pathValue.type)); 103 104 // Check each path 105 string[] pathsWithDMD; 106 string[] pathsWithoutDMD; 107 foreach (path; split(pathValue.asString, ";")) 108 { 109 if(isDMDDir(path)) 110 pathsWithDMD ~= path; 111 else 112 pathsWithoutDMD ~= path; 113 } 114 115 // DMD found in system PATH? 116 if (pathsWithDMD.length > 0) 117 { 118 println("Your system PATH appears to already contain DMD:"); 119 120 foreach (path; pathsWithDMD) 121 println(" ", path); 122 123 println(""); 124 println("The above path(s) must be removed from your system PATH or else DVM won't"); 125 println("be able to set your \"default\" compiler. (However, you can still use DVM"); 126 println("to set your \"current\" compiler.)"); 127 println(""); 128 println("Would you like DVM to automatically remove those existing DMD entries from"); 129 println("your system path? (If 'yes', this will affect ALL USERS on this computer.)"); 130 println(""); 131 132 bool shouldRemoveDMD = promptYesNo(); 133 134 // Remove DMD paths from system PATH? 135 if (shouldRemoveDMD) 136 { 137 string newValue = ""; 138 foreach (path; pathsWithoutDMD) 139 { 140 if (newValue != "") 141 newValue ~= ';'; 142 143 newValue ~= path; 144 } 145 146 try 147 { 148 scope envKeyRW = new RegistryKey(RegRoot.HKEY_LOCAL_MACHINE, envKeyPath); 149 envKeyRW.setValueExpand("PATH", newValue); 150 } 151 catch(Exception e) 152 { 153 println("DVM was unable to edit your system PATH."); 154 println("(Maybe you don't have sufficient privileges?)"); 155 println(""); 156 println("You'll have to remove the DMD from your system PATH manually,"); 157 println("or contact your system administrator."); 158 println(""); 159 } 160 } 161 } 162 } 163 }