Shoutbox

Parse Registry SubKeys in JScript? - Printable Version

-Shoutbox (https://shoutbox.menthix.net)
+-- Forum: MsgHelp Archive (/forumdisplay.php?fid=58)
+--- Forum: Messenger Plus! for Live Messenger (/forumdisplay.php?fid=4)
+---- Forum: Scripting (/forumdisplay.php?fid=39)
+----- Thread: Parse Registry SubKeys in JScript? (/showthread.php?tid=65331)

Parse Registry SubKeys in JScript? by Jedimark on 08-24-2006 at 05:23 PM

Does anyone know how to do the equivalent of this C# code in JScript?

Cheers,
- Mark

code:
try
{
        RegistryKey rootPath = Registry.CurrentUser.OpenSubKey("Software\\Item1\\Item2", true);
        foreach(string newKey in rootPath.GetSubKeyNames())
        {
                // other stuff here
        }
}

RE: Parse Registry SubKeys in JScript? by J-Thread on 08-24-2006 at 07:52 PM

I think we had a thread about this a few weeks ago, but I can't find it anymore...

I think the solution was to use a win32 function for listing registry subkeys, because it seems like it cannot be done easily with the scripting engine.

Can somebody else find the thread / remember the solution?


RE: Parse Registry SubKeys in JScript? by Ezra on 08-24-2006 at 10:35 PM

quote:
Originally posted by Jedimark
Does anyone know how to do the equivalent of this C# code in JScript?

Cheers,
- Mark

code:
try
{
        RegistryKey rootPath = Registry.CurrentUser.OpenSubKey("Software\\Item1\\Item2", true);
        foreach(string newKey in rootPath.GetSubKeyNames())
        {
                // other stuff here
        }
}



Why not make a nice dll that returns an array with keys?
RE: Parse Registry SubKeys in JScript? by Shondoit on 08-24-2006 at 10:54 PM

No need for a DLL, it can be done without it

I have the code, but I'll have to look for it though
post them asap

-edit1- I found the code, but it is script specific, I will make it variable now
-edit2- Changed the code, gonna test it now...

-edit3- Here is the final code. The first function enumerates all available subkey names, the second function enumerates all key value names, could be used to look wich programs run on windows startup ("HKLM\Software\Microsoft\Windows\CurrentVersion\Run", if you'd want to know, user specific startup is located in HKCU instead of HKLM)

code:
function EnumSubKeys (RegKey) {
  var RootKey = new Object()
  RootKey["HKCR"] = RootKey["HKEY_CLASSES_ROOT"]   = 0x80000000;
  RootKey["HKCU"] = RootKey["HKEY_CURRENT_USER"]   = 0x80000001;
  RootKey["HKLM"] = RootKey["HKEY_LOCAL_MACHINE"]  = 0x80000002;
  RootKey["HKUS"] = RootKey["HKEY_USERS"]          = 0x80000003;
  RootKey["HKCC"] = RootKey["HKEY_CURRENT_CONFIG"] = 0x80000005;
  var RootVal = RootKey[RegKey.substr(0, RegKey.indexOf("\\"))]
  if (RootVal != undefined) {
    Locator = new ActiveXObject("WbemScripting.SWbemLocator");
    ServerConn = Locator.ConnectServer(null, "root\\default");
    Registry = ServerConn.Get("StdRegProv");
    Method = Registry.Methods_.Item("EnumKey");
    p_In = Method.InParameters.SpawnInstance_();
    p_In.hDefKey = RootVal;
    p_In.sSubKeyName = RegKey.substr(RegKey.indexOf("\\") + 1)
    p_Out = Registry.ExecMethod_(Method.Name, p_In);
    return p_Out.sNames.toArray();
  }
}

function EnumValues (RegKey) {
  var RootKey = new Object()
  RootKey["HKCR"] = RootKey["HKEY_CLASSES_ROOT"]   = 0x80000000;
  RootKey["HKCU"] = RootKey["HKEY_CURRENT_USER"]   = 0x80000001;
  RootKey["HKLM"] = RootKey["HKEY_LOCAL_MACHINE"]  = 0x80000002;
  RootKey["HKUS"] = RootKey["HKEY_USERS"]          = 0x80000003;
  RootKey["HKCC"] = RootKey["HKEY_CURRENT_CONFIG"] = 0x80000005;
  var RootVal = RootKey[RegKey.substr(0, RegKey.indexOf("\\"))]
  if (RootVal != undefined) {
    Locator = new ActiveXObject("WbemScripting.SWbemLocator");
    ServerConn = Locator.ConnectServer(null, "root\\default");
    Registry = ServerConn.Get("StdRegProv");
    Method = Registry.Methods_.Item("EnumValues");
    p_In = Method.InParameters.SpawnInstance_();
    p_In.hDefKey = RootVal;
    p_In.sSubKeyName = RegKey.substr(RegKey.indexOf("\\") + 1)
    p_Out = Registry.ExecMethod_(Method.Name, p_In);
    return p_Out.sNames.toArray();
  }
}

Then you can use it like this...
code:
var SubKeyArray = EnumSubKeys("HKEY_CURRENT_USER\\Software\\Item1\\Item2");
for (Index in SubKeyArray) {
   Debug.Trace(SubKeyArray[Index])
}

Or enumerate all programs running on startup...
code:
var Shell = new ActiveXObject("WScript.Shell")
var Key = "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
var ValuesArray = EnumValues(Key);
Debug.Trace("=== Global startup ===")
for (Index in ValuesArray) {
   var ValueName = ValuesArray[Index]
   ValueValue = Shell.RegRead(Key + "\\" + ValueName)
   Debug.Trace(ValueName + " = " + ValueValue)
}
var Key = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
var ValuesArray = EnumValues(Key);
Debug.Trace("=== User startup ===")
for (Index in ValuesArray) {
   var ValueName = ValuesArray[Index]
   ValueValue = Shell.RegRead(Key + "\\" + ValueName)
   Debug.Trace(ValueName + " = " + ValueValue)
}


RE: Parse Registry SubKeys in JScript? by CookieRevised on 08-25-2006 at 12:00 AM

new ActiveXObject("WbemScripting.SWbemLocator") ????
Locator.ConnectServer(null, "root\\default") ????
Registry.Methods_.Item("EnumValues") ????
etc...

I'm sorry but all this stuff is really not needed at all.

J-Thread is absolutely correct, 'simply' use the available Windows registry API's to do the job. They are all you need (although the method you showed has some "je-ne-sais-qua" too; still I really don't like the detour which activex takes (afterall, it uses those very same apis)).

Speaking of which, I have seen many registry accessing codes, and they are almost always exactly the same (with the same 'mistakes' or limitations), although they 'work', I haven't seen many totally fool proof and correct 100% codes (eg: first checking the length a registry key is, instead of assuming the key wnt be longer than x bytes, before retrieving it)

IIRC, Matty already posted an almost complete (but with some limitations) registry accessing script on the forums...
EDIT: I was wrong(partially) what Matty used was an external DLL => ActiveX Registry Access for Scripts


RE: Parse Registry SubKeys in JScript? by Shondoit on 08-25-2006 at 12:09 AM

What do you mean "not needed at all", it does the job doesn't it?
He got his answer. It doesn't have to be from the API...

Personally, I always forget to 'Free' the Dll's I used, and a lot of scripts I looked at forget it too...
This way is a much cleaner way, because you don't have to use anything external, so it saves from using DataBloc structures (Interop.Allocate)

And by the way, these methods use an official Registry control object (StdRegProv)


RE: RE: Parse Registry SubKeys in JScript? by CookieRevised on 08-25-2006 at 12:14 AM

quote:
Originally posted by Shondoit
What do you mean "not needed at all", it does the job doesn't it?
With a detour, yes...
quote:
Originally posted by Shondoit
He got his answer. It doesn't have to be from the API...
You'll learn more from using APIs (if APIs can be used) than anything else. APIs are the stuff under the hood and do not have the limitations which activex objects like that have.
quote:
Originally posted by Shondoit
Personally, I always forget to 'Free' the Dll's I used, and a lot of scripts I looked at forget it too...
You don't need to free system DLLs (as a matter of fact, freeing them will actually not free them at all) (and as another matter of fact, you probably use more memory when you use that activex than when you use the APIs; moreover in Plus! scripting, once you loaded an activex object it stays loaded; eg: try to delete an activex dll after you've loaded it in your script, you wont be able to do it)
quote:
Originally posted by Shondoit
This way is a much cleaner way, because you don't have to use anything external, so it saves from using DataBloc structures (Interop.Allocate)
I don't find that cleaner at all, matter of opinion probably...
quote:
Originally posted by Shondoit
And by the way, these methods use an official Registry control object (StdRegProv)
Which has probably some restrictions too (like every activex) and which on its term uses the APIs anyways. So why use a detour when you can use the stuff you need directly, without any restrictions...

-------------

EDIT
quote:
Originally posted by Shondoit
(btw: I don't have access to the thread you showed... or something like that)
thread reported to be moved from private beta forum to public scripting forum... my bad, sorry

RE: Parse Registry SubKeys in JScript? by Shondoit on 08-25-2006 at 12:17 AM

Matter of opinion indeed...

I still think, using a class specificaly designed for Reg access is much easier, Most people don't create Windows with API calls either

(btw: I don't have access to the thread you showed... or something like that)


RE: Parse Registry SubKeys in JScript? by matty on 08-25-2006 at 01:52 AM

quote:
Originally posted by CookieRevised
IIRC, Matty already posted an almost complete (but with some limitations) registry accessing script on the forums...
EDIT: I was wrong(partially) what Matty used was an external DLL => ActiveX Registry Access for Scripts

I should slap you soooooooooo hard did you forget this module?

Next thing to add is the SetBinaryValue
GetBinaryValue doesn't work unless the value going to be returned is a string (need to figure this out).
Combine all GetValues and SetValues into one.

Then anything else that could be thought of really.
RE: Parse Registry SubKeys in JScript? by -dt- on 08-25-2006 at 04:15 AM

I havent yet looked at yours matty (I am now) but i made a registry class not that long ago to do this for someone on irc

http://svn.thedt.net/cgi/viewcvs.cgi/scripts/code...ass.js?view=markup


RE: Parse Registry SubKeys in JScript? by CookieRevised on 08-25-2006 at 03:26 PM

Matty: woopsy....
Matty, -dt-: nice, but misses a few things, and makes some of those common 'mistakes' (not really mistakes, but rather things which are't totally as it should be)


RE: Parse Registry SubKeys in JScript? by Jedimark on 08-26-2006 at 12:48 PM

Thanks for the pointers guys, I found the WMI code on the web also. Does seem a bit overkill. Matty, your code looks like it will do the trick :)

- Mark