mIRC Homepage
Posted By: westor $regread - Registry "READ" Identifier - 17/03/16 02:49 PM
Hello,

It would be nice to have an identifier in mIRC that it could only READ the Windows Registry and get details, i hope my idea will not go into the heaven.

Usage: $regread(path,N).prop
Properties: .type - .value

Examples:

$regread(HKEY_CURRENT_USER\SOFTWARE\Microsoft\Notepad,0) = the total names from the direction.
$regread(HKEY_CURRENT_USER\SOFTWARE\Microsoft\Notepad,1) = the 1st name from the direction.
$regread(HKEY_CURRENT_USER\SOFTWARE\Microsoft\Notepad,1).type = the type (REG_SZ,REG_BINARY,...) for the 1st name from the direction.
$regread(HKEY_CURRENT_USER\SOFTWARE\Microsoft\Notepad,1).value = the value for the 1st name from the direction.

- Thanks!
Posted By: klez Re: $regread - Registry "READ" Identifier - 25/03/16 12:26 PM
Very good idea! Plus, will be good to add and /regwrite /regdelete /regcreate dirs subdirs keys and so on
Posted By: kap Re: $regread - Registry "READ" Identifier - 09/08/16 12:50 PM
+1 and *bump*
Posted By: argv0 Re: $regread - Registry "READ" Identifier - 10/08/16 12:39 AM
Well FWIW you can use this small alias to do it already:

Code:
alias regread {
 if ($com(rr)) { !.comclose rr }
 !.comopen rr WScript.Shell
 var %a = $com(rr,RegRead,3,bstr,$1-)
 var %a = $com(rr).result
 !.comclose rr
 !return $iif(%a,%a,$null)
}



//echo -a $regread(HKLM\Software\Microsoft\Windows\CurrentVersion\ProgramFilesDir)

It's worth having in mIRC, but you shouldn't be blocked on it.
Posted By: Wims Re: $regread - Registry "READ" Identifier - 10/08/16 12:05 PM
Just use $1, instead of $1- and your $iif is just wrong, should be just 'return %a', otherwise it won't work for $false (rare) and 0.
Posted By: Dazuz Re: $regread - Registry "READ" Identifier - 10/08/16 01:09 PM
Might as well take it a bit further and speed it up a tiny bit:
Code:
alias regread {
  if ($com(rr)) .comclose rr
  .comopen rr WScript.Shell
  tokenize 32 $com(rr,RegRead,3,bstr,$1) $com(rr).result
  .comclose rr
  return $2-
}
Posted By: Wims Re: $regread - Registry "READ" Identifier - 10/08/16 01:14 PM
Lol, yeah, those femto seconds you saved there? It will matter so much for people executing $regread 100 times in a row! grin
Posted By: Dazuz Re: $regread - Registry "READ" Identifier - 10/08/16 01:30 PM
Yes! My nearly OCD level obsession with performance won't let me skip those femtoseconds!

All you need to do is to save 1 billion femtoseconds to gain one whole millisecond! I'd call that a good deal!
Originally Posted By: Dazuz
Yes! My nearly OCD level obsession with performance won't let me skip those femtoseconds!

All you need to do is to save 1 billion femtoseconds to gain one whole millisecond! I'd call that a good deal!


Code:
alias regread {
  if (!$com(regread)) .comopen regread WScript.Shell
  noop $com(regread,RegRead,3,bstr,$1) $com(regread,&regread).result
  return $bvar(&regread,1-).text
}
Posted By: Dazuz Re: $regread - Registry "READ" Identifier - 10/08/16 02:14 PM
It leaves the COM open, which is not really acceptable, unless you keep executing the identifier constantly.

Also, the binvar thing slows it down, so:
Code:
alias regread {
  if (!$com(rr)) .comopen rr WScript.Shell
  tokenize 32 $com(rr,RegRead,3,bstr,$1) $com(rr).result
  return $2-
}
Posted By: Wims Re: $regread - Registry "READ" Identifier - 10/08/16 05:09 PM
I don't see any benchmark, how do you know the binvar usage slows it down?
Posted By: Dazuz Re: $regread - Registry "READ" Identifier - 10/08/16 05:35 PM
EDIT #2: just noticed the first edit used long(er) COM/binvar name for regred2, so third's the charm:
Code:
alias regread1 {
  tokenize 1 HKEY_CURRENT_USER\SOFTWARE\mIRC\LastRun\
  if (!$com(rr)) .comopen rr WScript.Shell
  tokenize 32 $com(rr,RegRead,3,bstr,$1) $com(rr).result
  return $2-
}

alias regread2 {
  tokenize 1 HKEY_CURRENT_USER\SOFTWARE\mIRC\LastRun\
  if (!$com(rr)) .comopen rr WScript.Shell
  noop $com(rr,RegRead,3,bstr,$1) $com(rr,&r).result
  return $bvar(&r,1-).text
}


Quote:
20:47:31 * Starting "regread1" test: 50,000 times, 5 cycles.
20:47:34 * Cycle #1 done: 2234 ms (0.04468 ms/command)
20:47:36 * Cycle #2 done: 2281 ms (0.04562 ms/command)
20:47:38 * Cycle #3 done: 2250 ms (0.045 ms/command)
20:47:40 * Cycle #4 done: 2234 ms (0.04468 ms/command)
20:47:43 * Cycle #5 done: 2266 ms (0.04532 ms/command)
20:47:43 * Done: 5 cycles done in 11,265 ms, 2253 ms/cycle on average.
20:47:48 * Starting "regread2" test: 50,000 times, 5 cycles.
20:47:51 * Cycle #1 done: 2375 ms (0.0475 ms/command)
20:47:53 * Cycle #2 done: 2359 ms (0.04718 ms/command)
20:47:55 * Cycle #3 done: 2359 ms (0.04718 ms/command)
20:47:58 * Cycle #4 done: 2359 ms (0.04718 ms/command)
20:48:00 * Cycle #5 done: 2359 ms (0.04718 ms/command)
20:48:00 * Done: 5 cycles done in 11,811 ms, 2362.2 ms/cycle on average.




Click to reveal.. (A major mess)

regread1 tokenizes the result instantly, regread2 performs /noop, and then uses $bvar to get the result. It has to do more, which slows it down.

Code:
alias regread2 {
  tokenize 1 HKEY_CURRENT_USER\SOFTWARE\mIRC\LastRun\
  if ($com(rr)) .comclose rr
  .comopen rr WScript.Shell
  noop $com(rr,RegRead,3,bstr,$1) $com(rr,&r).result
  .comclose rr
  return $bvar(&r,1-).text
}

alias regread1 {
  tokenize 1 HKEY_CURRENT_USER\SOFTWARE\mIRC\LastRun\
  if ($com(rr)) .comclose rr
  .comopen rr WScript.Shell
  tokenize 32 $com(rr,RegRead,3,bstr,$1) $com(rr).result
  .comclose rr
  return $2-
}


Quote:

20:30:24 * Starting "regread1" test: 50,000 times, 5 cycles.
20:30:27 * Cycle #1 done: 2891 ms (0.05782 ms/command)
20:30:30 * Cycle #2 done: 2843 ms (0.05686 ms/command)
20:30:33 * Cycle #3 done: 2891 ms (0.05782 ms/command)
20:30:36 * Cycle #4 done: 2859 ms (0.05718 ms/command)
20:30:39 * Cycle #5 done: 2875 ms (0.0575 ms/command)
20:30:39 * Done: 5 cycles done in 14,359 ms, 2871.8 ms/cycle on average.
20:30:43 * Starting "regread2" test: 50,000 times, 5 cycles.
20:30:46 * Cycle #1 done: 2984 ms (0.05968 ms/command)
20:30:49 * Cycle #2 done: 2969 ms (0.05938 ms/command)
20:30:52 * Cycle #3 done: 2969 ms (0.05938 ms/command)
20:30:55 * Cycle #4 done: 3000 ms (0.06 ms/command)
20:30:58 * Cycle #5 done: 2953 ms (0.05906 ms/command)
20:30:58 * Done: 5 cycles done in 14,875 ms, 2975 ms/cycle on average.


Test alias:
Code:
alias test {
  if ($1 isnum 1-) { var %t = $1 | tokenize 32 $2- }
  else var %t = 1000
  if ($1 isnum 1-) { var %c = $1 | tokenize 32 $2- }
  else var %c = 5
  if (!$1) echo -at * ERROR: invalid input: Usage: /TEST [times] [cycles] <alias> 
  elseif ($isalias($1)) {
    echo -at * Starting $qt($1-) test: $bytes(%t,b) times, $bytes(%c,b) cycles.
    %test.cycle = 0
    %test.cycles = %c
    %test.times = %t
    %test.cmd = $1
    %test.total = 0
    .timertest -iom %c 500 test.cycle
  }
  else echo -at * ERROR: $qt($1) no such alias.
}

alias -l test.cycle {
  inc %test.cycle
  var %x = %test.times,%t $ticks
  while (%x) { %test.cmd | dec %x }
  tokenize 1 $calc($ticks -%t)
  inc %test.total $1
  echo -at * Cycle $chr(35) $+ $bytes(%test.cycle,b) done: $1 ms $b($calc($1 /%test.times) ms/command)
  if (%test.cycle == %test.cycles) {
    echo -at * Done: $bytes($v2,b) cycles done in $bytes(%test.total,b) ms, $calc(%test.total /$v2) ms/cycle on average.
    unset %test.*
  }
  :error
  if ($error) {
    echo -at * ERROR: an error occurred while executing a $qt(%test.cmd) test cycle: $error
    .timertest off
    unset %test.*
    reseterror
  }
}




EDIT: just realized I technically used the wrong aliases, so let's try again:
Code:
alias regread1 {
  tokenize 1 HKEY_CURRENT_USER\SOFTWARE\mIRC\LastRun\
  if (!$com(rr)) .comopen rr WScript.Shell
  tokenize 32 $com(rr,RegRead,3,bstr,$1) $com(rr).result
  return $2-
}

alias regread2 {
  tokenize 1 HKEY_CURRENT_USER\SOFTWARE\mIRC\LastRun\
  if (!$com(regread)) .comopen regread WScript.Shell
  noop $com(regread,RegRead,3,bstr,$1) $com(regread,&regread).result
  return $bvar(&regread,1-).text
}



Quote:
20:42:12 * Starting "regread1" test: 50,000 times, 5 cycles.
20:42:14 * Cycle #1 done: 2250 ms (0.045 ms/command)
20:42:17 * Cycle #2 done: 2218 ms (0.04436 ms/command)
20:42:19 * Cycle #3 done: 2219 ms (0.04438 ms/command)
20:42:21 * Cycle #4 done: 2235 ms (0.0447 ms/command)
20:42:23 * Cycle #5 done: 2219 ms (0.04438 ms/command)
20:42:23 * Done: 5 cycles done in 11,141 ms, 2228.2 ms/cycle on average.
20:42:28 * Starting "regread2" test: 50,000 times, 5 cycles.
20:42:31 * Cycle #1 done: 2375 ms (0.0475 ms/command)
20:42:34 * Cycle #2 done: 2359 ms (0.04718 ms/command)
20:42:36 * Cycle #3 done: 2359 ms (0.04718 ms/command)
20:42:38 * Cycle #4 done: 2390 ms (0.0478 ms/command)
20:42:41 * Cycle #5 done: 2359 ms (0.04718 ms/command)
20:42:41 * Done: 5 cycles done in 11,842 ms, 2368.4 ms/cycle on average.

Why is the com being left open unacceptable, especially in this case? If mIRC closes, the com is auto-closed. If wscript.exe is closed then the com on mIRC will error. Unlike other objects, the usage of this one will not create an unstable state for either mIRC, wscript or the OS

Your benchmark is correct in that tokenize is faster than using bvars but the assumption as to why is incorrect. The reason has nothing to do with the command call at all; the way mIRC handles command evaluation is that it evaluates the input portion then passes the result to the command. The same initial leg work is being done by both /noop and /tokenize. The reason bvars are slow is, I believe, due to having to, internally, convert a binary array into a string and then utf encoding that string before giving a result.

Regardless here's an even faster way (Yes, the com is left open, that's intended):

Code:
alias regread {
  if (!$~com(regread)) !.comopen regread WScript.Shell
  noop $~com(regread,RegRead,3,bstr,$~1) 
  !return $~com(regread).result
}


edits
1: clarified message
2: "/ " no longer works in place of noop
Posted By: Dazuz Re: $regread - Registry "READ" Identifier - 10/08/16 06:15 PM
I just personally prefer it when scripts clean up after themselves and get rid of stuff that is no longer needed.

Leaving a COM open for something that probably doesn't get used often just feel messy.

Also, there's the winner!


EDIT:
Didn't even notice the earlier version didn't work properly, had regread COM already open, so it kept getting the old result.

Also, you can make the new version a tiny bit faster:
Code:
alias regread {
  if (!$~com(r)) !.comopen r WScript.Shell
  !noop $~com(r,RegRead,3,bstr,$~1)
  !return $~com(r).result
}

Shorter COM name and ! in front of "noop" did the trick.
Since you wanted a tidy alias I'll do you one better: subsequent calls in the same execution block won't have the overhead of reopening the com, but the com will still get closed at the end of the block:

Code:
alias regread {
  if (!$com(regread)) {
    .comopen regread WScript.Shell
    .timer -io 1 0 .comclose regread
  }
  noop $com(regread,RegRead,3,bstr,$1)
  return $com(regread).result
}
Posted By: Dazuz Re: $regread - Registry "READ" Identifier - 10/08/16 06:49 PM
If a script had to make look up loads of reg entries, I'd probably make a custom version of the regread alias just for it. One that would keep the COM open as long as it's needed.



EDIT:
Forgot to try one more thing, and it sped up the script even more, although the difference is only about 10 ms when doing 50,000 times.
Code:
alias regread if (!$~com(r)) !.comopen r WScript.Shell | !noop $~com(r,RegRead,3,bstr,$~1) | !return $~com(r).result
© mIRC Discussion Forums