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