//v0.1 - 2014.09 //- initial version //v0.3.3 //- min version added //- scriptwizard support //v0.4 - 2015.03 //- support for powershell style registry paths containing ":" (like "HKLM:\..") //- minor tweaks var SCRIPTFILENAME = '*GoRegistry.js*'; /////////////////////////////////////////////////////////////////////////////// function OnInit(data) { //uid added via script wizard (do not change after publishing this script) var uid = "D3FCA703-8CAE-4118-B82E-A0EBB72DC8FC"; //resource center url added via script wizard (required for updating) var url = "http://resource.dopus.com/viewtopic.php?f=35&t=22946"; data.name = "Command.Generic: GoRegistry"; data.desc = "Open registry editor for a given registry path."; data.copyright = "tbone"; data.version = "0.4"; data.min_version = "11.6"; data.log_prefix = "GoRegistry"; data.default_enable = true; /////////////////////////////////////////////////////////////////////////// function ConfigHelper(data){ this.data=data; this.descriptions=null; this.last=null; this.add = function(name, val, description){ this.data.config[name]=val; this.last=[this.data.config[name],name]; if (description!=undefined) this.des(description); return this;} this.des = function(description){ if (!(description && DOpus.version.AtLeast("11.6.1"))) return this; if (!this.descriptions){ this.descriptions=DOpus.NewMap(); data.config._descriptions=this.descriptions; } this.descriptions(this.last[1])=description; return this;} this.val = function(val){ if (typeof this.last[0]=="object") this.last[0].push_back(val); else this.last[0]=val; return this;} } /////////////////////////////////////////////////////////////////////////// //HKEY_LOCAL_MACHINE\SOFTWARE\WinRAR\Capabilities\FileAssociations\.iso /////////////////////////////////////////////////////////////////////////// var cfg = new ConfigHelper(data); cfg.add("DebugOutput", false). des("Enable debug output in the script console."); cfg.add("WatchLocationFields", false). des("Enable registry path detection if pasted to location fields."); cfg.add("Requester", true). des("Enable retry requester if the registry path was invalid."); cfg.add("RequesterOnSuccess", false). des("Re/Open retry requester after locating valid keys as well. Notice: The requester needs to be enabled for this option to take effect."); cfg.add("BestMatch", false). des("Use best match mode by default."); cfg.add("BestMatchAuto", true). des("Use strict mode for valid keys, but automatically fall back to best match mode, if key is invalid."); cfg.add("OpenValidKeysOnly", false). des("Do not open registry editor, if the given key is invalid"); cfg.add("NoAutoSelect", false). des("Disable automatic selection of registry sub-key."); cfg.add("°", ""); cfg.add("° ", "############################################"); cfg.add("° ", "# Notice: It takes approximately 10s for changes to apply. #"); cfg.add("° ", "############################################"); } /////////////////////////////////////////////////////////////////////////////// var ABORT = true; var SUCCESS = false; var FOLDERCHANGE_CANCEL = true; var FOLDERCHANGE_PROCEED = false; var COMMAND_ABORTED = false; //==0 var COMMAND_SUCCEEDED = true; //!=0 /////////////////////////////////////////////////////////////////////////////// try{ if (DOpus.vars.Exists("Script.GoRegistry.WatchLocationFields") && DOpus.vars("Script.GoRegistry.WatchLocationFields") == true ){ //Debug(" VAR Script.WatchLocationFields = true / notexists"); //Debug(" Binding OnBeforeFolderChange():"); this.OnBeforeFolderChange = OnBeforeFolderChange_Callback; } else { //Debug(" VAR Script.WatchLocationFields = false"); //Debug(" NOT Binding OnBeforeFolderChange():"); } //Debug(" Config.WatchLocationFields = " + Script.config.WatchLocationFields); } catch(e){ //Debug(" Config.WatchLocationFields = ?"); } /////////////////////////////////////////////////////////////////////////////// function OnScriptConfigChange(){ SetVariable_WatchLocationFields("AfterConfig"); TouchScript(); } /////////////////////////////////////////////////////////////////////////////// function TouchScript(){ var scripts = DOpus.FSUtil.Resolve("/dopusdata/script addins"); var home = DOpus.FSUtil.Resolve("/home"); var cmd = 'cmd.exe /C timeout /t 8 /nobreak && "'+home+'\\dopusrt.exe'+ '" /cmd '+'SetAttr MODIFIED=now FILE="'+scripts+'\\'+SCRIPTFILENAME+'"'; new ActiveXObject("WScript.Shell").Run(cmd, 0, false); } /////////////////////////////////////////////////////////////////////////////// function OnAddCommands(data){ Debug("GoRegistry.OnAddCommands():"); var cmd = data.AddCommand(); cmd.name = "GoRegistry"; cmd.method = "Command_GoRegistry"; cmd.desc = "Open registry editor for a given registry path."; cmd.label = "GoRegistry"; cmd.template = "BESTMATCHAUTO/S,BESTMATCH/S,VALIDONLY/S,NOAUTOSELECT/S,REQUESTER/S,REQUESTERONSUCCESS/S,PATH/R"; } /////////////////////////////////////////////////////////////////////////////// function SetVariable_WatchLocationFields(source){ if (Script.config.WatchLocationFields == true){ Debug(" Setting Script.GoRegistry.WatchLocationFields = 1 " + source); DOpus.vars.Set("Script.GoRegistry.WatchLocationFields", 1); DOpus.vars("Script.GoRegistry.WatchLocationFields").persist = true; } else { DOpus.vars.Set("Script.GoRegistry.WatchLocationFields", 0); DOpus.vars("Script.GoRegistry.WatchLocationFields").persist = true; Debug(" Setting Script.GoRegistry.WatchLocationFields = 0 " + source); } } /////////////////////////////////////////////////////////////////////////////// function OnBeforeFolderChange_Callback(data) { Debug("GoRegistry.OnBeforeFolderChange():"); var rawInput = new String(data.path); Debug(" Input: " + rawInput); Debug(" Quicktesting possible registry path.."); if (rawInput.toUpperCase().indexOf("HK")==-1){ Debug(" failed."); Debug(" Proceeding with folderchange."); return FOLDERCHANGE_PROCEED; } Debug(" succeeded."); var regKey = GetCleanedLocationBarInput(rawInput, data); regKey = ParseForRegistryPath(regKey); if(!regKey) return FOLDERCHANGE_PROCEED; var cmd = '"'+DOpus.FSUtil.Resolve('/home')+'\\dopusrt.exe" /cmd GoRegistry '; if (Script.config["Requester"]) cmd+="REQUESTER "; if (Script.config["RequesterOnSuccess"]) cmd+="REQUESTERONSUCCESS "; if (Script.config["BestMatch"]) cmd+="BESTMATCH "; if (Script.config["BestMatchAuto"]) cmd+="BESTMATCHAUTO "; if (Script.config["OpenValidKeysOnly"]) cmd+="VALIDONLY "; if (Script.config["NoAutoSelect"]) cmd+="NOAUTOSELECT "; cmd+="PATH="+regKey; Debug(" Running GoRegistry script command.."); Debug(" Cmd: " + cmd); new ActiveXObject("WScript.Shell").Run(cmd, 0, false); return FOLDERCHANGE_CANCEL; } /////////////////////////////////////////////////////////////////////////////// function Command_GoRegistry(data) { Debug("GoRegistry():"); data.func.command.ClearFiles(); var cmdOptions = { test : GetParameter(data, "TEST", null, false), requester: GetParameter(data, "REQUESTER", null, false), requesterOnSuccess: GetParameter(data, "REQUESTERONSUCCESS", null, false), bestMatch: GetParameter(data, "BESTMATCH", null, false), bestMatchAuto: GetParameter(data, "BESTMATCHAUTO", null, false), noAutoSelect: GetParameter(data, "NOAUTOSELECT", null, false), validOnly: GetParameter(data, "VALIDONLY", null, false) } var regKey = GetParameter(data, "PATH", null, ""); Debug(" Path: " + regKey); for(var key in cmdOptions) Debug(" "+key.toUpperCase()+": " + cmdOptions[key]); //trim slashes regKey = regKey.replace(/^\\+|\\+$/g, ''); if (regKey==""){ Debug(" Missing or empty PATH parameter, aborting."); return ABORT; } return GoRegistry_Core(regKey, cmdOptions); } /////////////////////////////////////////////////////////////////////////////// function GoRegistry_Core(regKey, cmdOptions){ function HandleDialogResult(result, regKey, cmdOptions){ cmdOptions.requesterOnSuccess = result.reopen; Debug(" DialogResult: " + result.result); if (result.result==1){ //go auto cmdOptions.bestMatch = false; cmdOptions.bestMatchAuto = true; GoRegistry_Core(result.regKey, cmdOptions); } if (result.result==2){ //go strict cmdOptions.bestMatch = false; cmdOptions.bestMatchAuto = false; GoRegistry_Core(result.regKey, cmdOptions); } if (result.result==3){ //go best match cmdOptions.bestMatch = true; cmdOptions.bestMatchAuto = false; GoRegistry_Core(result.regKey, cmdOptions); } } switch (OpenRegistryOnPath( regKey, null, cmdOptions)){ case OPEN_SUCCESS: DOpus.Delay(50); if (cmdOptions.requester && cmdOptions.requesterOnSuccess){ var result = SuccessDialog(regKey, cmdOptions.requesterOnSuccess); HandleDialogResult(result, regKey, cmdOptions); } //cancel, quitting return SUCCESS; break; case OPEN_ERROR_TRASH: case OPEN_ERROR_FIXED: default: DOpus.Delay(50); if (cmdOptions.requester){ var result = RetryDialog(regKey, cmdOptions.requesterOnSuccess); HandleDialogResult(result, regKey, cmdOptions); } //cancel, quitting return ABORT; break; } } /////////////////////////////////////////////////////////////////////////////// var OPEN_SUCCESS = 0; var OPEN_ERROR_TRASH = 1; var OPEN_ERROR_FIXED = 2; /////////////////////////////////////////////////////////////////////////////// function OpenRegistryOnPath( regKey, shell, cmdOptions){ var regKeyNotFixed = regKey = ParseForRegistryPath(regKey); if(!regKey) return OPEN_ERROR_TRASH; var regKeyUpperCase = regKey.toUpperCase(); if (shell == undefined) shell = new ActiveXObject("WScript.Shell"); var validKey=false; var valueItem = ""; var fixAttemptsCount=0; while (validKey===false){ fixAttemptsCount++; if (fixAttemptsCount>512) break; try { //fails if key not present (tries to read default key value) Debug(" Checking existence of path ["+regKeyUpperCase + "\\"+"]"); var result = shell.RegRead(regKeyUpperCase + "\\"); Debug(" succeeded."); validKey = true; } catch (e){ try{ //reading key default-value failed, maybe it's a subkey-name Debug(" failed."); Debug(" Testing for value.."); var result = shell.RegRead(regKeyUpperCase); Debug(" succeeded, stripping last part."); } catch (e){ Debug(" failed."); Debug(" ValueItem = false"); valueItem=null; } //read succeeded, a value was given //remove the subkey-name from the path as we need a key var lastSlash = regKey.lastIndexOf("\\"); if (lastSlash==-1) break; if (valueItem!==null) valueItem = regKey.substring(lastSlash+1); regKey = regKey.substring(0,lastSlash); regKeyUpperCase = regKeyUpperCase.substring(0,lastSlash); Debug(" Path (stripped): " + regKey); } } Debug(" FixAttemptsCount: " + fixAttemptsCount); var keyHasBeenFixed = ((fixAttemptsCount>1 && valueItem===null)?true:false); //if best match, force key to be valid, use original input if (cmdOptions.bestMatch){ Debug(" Best match mode, using non-validated input."); regKey = regKeyNotFixed; validKey = true; } if (keyHasBeenFixed && cmdOptions.bestMatchAuto){ Debug(" Invalid key, falling back to best match mode."); regKey = regKeyNotFixed; cmdOptions.bestMatch = true; validKey = true; } if (!validKey){ Debug(" No valid registry path, aborting."); return OPEN_ERROR_TRASH; } Debug(" Open registry editor?"); if (cmdOptions.bestMatch || !cmdOptions.validOnly || (!keyHasBeenFixed && cmdOptions.validOnly)){ Debug(" Yes."); OpenRegistryEditor( regKey, cmdOptions, valueItem, shell); } else Debug(" No (key was invalid/has been fixed and current options forbid opening of such keys)."); if (keyHasBeenFixed){ Debug(" Registry path has been fixed."); return OPEN_ERROR_FIXED; } Debug(" Registry path was valid "+(cmdOptions.bestMatch?"(forced to be valid -> best match).":".")); return OPEN_SUCCESS; } /////////////////////////////////////////////////////////////////////////////// function RetryDialog( regKey, reopen ){ var dlg = DOpus.Dlg; //dlg.window = DOpus.Listers(0) dlg.window = null; dlg.message = "The registry path was invalid."; dlg.title = "GoRegistry - Error"; dlg.buttons = "Retry Auto|Retry Strict+Retry Best Match|Cancel"; dlg.icon = "warn"; dlg.max = 512; dlg["default"] = regKey; var label = "Reopen requester after locating a valid key"; for(var len=0;len<120;len++) label+=" ";label+="\t"; dlg.options(0).label = label; dlg.options(0).state = (reopen?1:0); ret = dlg.Show(); return { result:ret, regKey:dlg.input, reopen:dlg.options(0).state }; } /////////////////////////////////////////////////////////////////////////////// function SuccessDialog( regKey, reopen ){ var dlg = DOpus.Dlg; //dlg.window = DOpus.Listers(0) dlg.window = null; dlg.message = "The registry path was valid."; dlg.title = "GoRegistry - Success"; dlg.buttons = "Go Auto|Go Strict+Go Best Match|Cancel"; dlg.icon = "info"; dlg.max = 512; dlg["default"] = regKey; var label = "Reopen requester after locating a valid key"; for(var len=0;len<120;len++) label+=" ";label+="\t"; dlg.options(0).label = label; dlg.options(0).state = (reopen?1:0); ret = dlg.Show(); return { result:ret, regKey:dlg.input, reopen:dlg.options(0).state }; } /////////////////////////////////////////////////////////////////////////////// function OpenRegistryEditor( path, cmdOptions, valueItem, shell){ //now handled in ParseForRegistryPath()! //prevents "not found" if registry hive is just not uppercased //path = path.replace(/^(HKCU|HKEY_CURRENT_USER)\:?/i,"HKEY_CURRENT_USER"); //path = path.replace(/^(HKLM|HKEY_LOCAL_MACHINE)\:?/i,"HKEY_LOCAL_MACHINE"); //path = path.replace(/^(HKCR|HKEY_CLASSES_ROOT)\:?/i,"HKEY_CLASSES_ROOT"); DOpus.Output("RegKey: " + path); Debug(" Killing existing regedit.exe instances.."); Debug(" Running taskkill.exe (invisible, wait for return).."); result = shell.Run("taskkill.exe /IM regedit.exe /F", 0, true); Debug(" Putting new 'LastKey' value into registry.."); shell.RegWrite( "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Lastkey", "Computer\\"+path, "REG_SZ"); //run regedit.exe, visible, don't wait for return Debug(" Running regedit.exe (visible, don't wait for return).."); shell.Run("regedit.exe", 1, false); function SendKeysEscaped(keys, shell){ keys = keys.replace(/(\{|\})/g,"{$1}"); // { and } keys = keys.replace(/\~/g,"{~}"); keys = keys.replace(/\+/g,"{+}"); keys = keys.replace(/\%/g,"{%}"); keys = keys.replace(/\^/g,"{^}"); Debug(" Sending: " + keys); shell.SendKeys(keys); } if (ActivateRegistryEditor(shell, 20)){ Debug(" Registry editor activated (window found)."); //best match mode "typing" full reg key to get as near as possible if(cmdOptions.bestMatch){ //512 is max depth of registry, closing possibly open branches for(var i=0;i<512;i++) shell.SendKeys("{LEFT}"); shell.SendKeys("{HOME}"); //make sure we are really at the top var parts = path.toUpperCase().split("\\"); for(var i=0;i