Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

regread, regwrite -- backslashes in name 1

Status
Not open for further replies.

pdorman

Programmer
Feb 26, 2004
4
NZ
Hi,

I'm trying to write a script which will change some drive letters. The key I need to edit is:

[HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices], and the value is: "\\DosDevices\\Q:"=hex:5c,00,0.......1,00,7d,00", where the hex value has been trimmed for readability.

As you can see, the value name has backslashes, which is really annoying for me, as I can't seem to read or write keys with backslashes in the value name (they are interpreted as keys).

I don't think the regread and regwrite functions are going to help me in this case, but does anybody have an alternative method of reading and writing keys? I would very much like to avoid reading and writing text registry keys (*.reg files) as that is messy. Is there some API calls or some other tool available?

Thanks in advance for any help.

Regards,
Paul Dorman
 
Hello pdorman,

This can be done with stdregprov.
Code:
const HKEY_LOCAL_MACHINE=&H80000002

sSubkey="SYSTEM\MountedDevices"
sVname="\\dosdevices\\q:"
aValue=array(&h5c,&h00,&h00,&h7d,&h00)   'abriged

set svc=GetObject("winmgmts:root\default:StdRegProv")
iRet=svc.setbinaryvalue(HKEY_LOCAL_MACHINE,sSubkey,sVname,aValue)
set svc=nothing

if iRet=0 then wscript.echo "done" else "failed"
regards - tsuji
 
erratum: The last line should be read:
Code:
if iRet=0 then wscript.echo "done" else wscript.echo "failed"
-tsuji
 
That works really well Tsuji. Thankyou. I have another question though. I can use diskpart or the disk administrator to change a drive letter, and this change is effective immediately without a reboot. Is there any way to force the system to recognise my change without requiring the system to be rebooted? I've looked at various forums, and even tried a command line to do the trick, but that doesn't work for me.

Thanks again. Great answer.
 
pdorman,

If the application does not listen to the windows broadcasting wm_settingchange, I think you have a problem. You have to know exactly how the application being designed in listening what message. If it does, you may still have a problem in the restricted scripting arena officially supported by ms. You can use 3rd party control.

The more widely known are dynawrap (Ploony, Stong, Hines) and wshATO (Washington).

Let me show you and other members interested (as this is a rather faq often answered with obscurity) how to do it with dynawrap. The best way to show the mechanism is to stick to one particular setting change which otherwise need a reboot or logoff-logon to take effect. Let me use the NoRecendDocsHistory setting. It is setting related to the [start|documents].

In the code below, I have isolated the Broadcast_it sub. You can use it as such for your purpose after you change the registry. Just appending those lines and call it.

Code:
'---tsuji/throw-away/200402---

Const sRoot="HKEY_CURRENT_USER"
Const sKey="Software\Microsoft\Windows\CurrentVersion\Policies\Explorer"
Const sValueName="NoRecentDocsHistory"

dim wshshell, sVN, dwRet, iRet, prmpt

sVN=sRoot & "\" & sKey & "\" & sValueName

set wshshell=createobject("wscript.shell")

on error resume next
dwRet=wshshell.regread(sVN)
if err<>0 then dwRet=0
on error goto 0

if dwRet=1 then
     wscript.echo "The box is in the state no recent docs show up."
else
     wscript.echo "The box is in the state recent docs show up."
end if

prmpt="Do you want to toggle the state?"
iRet=msgbox(prmpt,vbYesNo,"Windows Script Host")

if iRet=vbNo then set wshshell=nothing : wscript.quit

'Toggle the setting
if dwRet=1 then dwRet=0 else dwRet=1

wshshell.regwrite sVN, dwRet, "REG_DWORD"
wscript.echo "The NoRecentDocsHistory state is toggled."
set wshshell=nothing

prmpt="The change will take effect upon logoff-logon without broadcast the setting change." & _
    vbcrlf & "Do you want to broadcast the change? If yes, It will take effect immediately."
iRet=msgbox(prmpt,vbYesNo,"Windows Script Host")
if iRet=vbYes then
    Broadcast_it
    wscript.echo "The setting takes effects now."
else
    wscript.echo "The new setting takes effect upon logoff-logon."
end if

sub Broadcast_it    'reduced version
    'broadcast wm_settingchange
    'Dynwrap pre-installed is required.
    const HWND_BROADCAST=&HFFFF
    const WM_SETTINGCHANGE=&H1A
    Dim oDynWrap 
    Set oDynWrap=createobject("DynamicWrapper")
    oDynWrap.Register "user32.dll", "SendMessageA", "i=llll", "f=s", "r=l"
    oDynWrap.SendMessageA HWND_BROADCAST, WM_SETTINGCHANGE,0,0
    set oDynWrap=nothing
end sub
- tsuji
 
erratum:
Should add err.clear in the sector of on error resume next.
Code:
on error resume next
dwRet=wshshell.regread(sVN)
if err<>0 then dwRet=0 : err.clear
on error goto 0
- tsuji
 
have a star from me, ive been using the enumKeys function to do it and wrote a FAQ on it. I will continue to use the enumKeys as i do other stuff during the iteration but none the less it is a very useful post

thanks
vonmoyla
 
About windows broadcasting wm_settingchange, I learned a while back that only the Windows NT OS family (NT, 2000, XP, etc.) have this feature to update as-is without rebooting.

Certain things will NOT work on Windows 98, 98se or Millennium, as they REQUIRE a reboot for any changes to be propagated throughout the OS. For example, in thread329-731144 I tried to take the user's login name and copy it at login into the DOS window's SET variables through the registry keys, but none of the DOS windows noticed the change until after a reboot. (Windows NT, 2000, XP already have a username SET variable which gets updated, but there is none in 98/98se/Me.)

dbMark
 
Hello dbMark,

The way you put it is not exact. I don't think it is 9x vs nt. Both have wm_settingchange implemented as message. It's so very fundamental that it be implemented dated long back. The only criteria is that if a certain application (top-level window) listens to the message & react to accordingly or not.

If you are interested in this, you can run my sample in win9x and you'll see what I mean. It is specially designed to demonstrate this fact with positive result.

regards - tsuji
 
Hello to Tek-Tips and the VBscript forum. As a longtime occasional VBscript programmer, I was delighted to discover Tek-Tips and this forum.

I need to do the same thing as pdorman. That is, change some drive letters and have Windows recognize the changes without rebooting (as is possible manually using Disk Management). Changing the registry in MountedDevices was easy, but tsuji's Broadcast_It sub isn't working for me.

My code functions without aborting and changes the registry values in MounterDevices but the drive letter changes don't show up until after rebooting.

Here's my Broadcast_It:
Sub Broadcast_It
'Broadcast disk drive changes
Dim iRet
Const HWND_BROADCAST = &HFFFF
Const WM_SETTINGCHANGE = &H1A
Dim oDynWrap
Set oDynWrap = CreateObject("DynamicWrapper")
iRet = oDynWrap.Register("user32.dll", "SendMessageA", "i=llll", "f=s", "r=l")
If (iRet <> 0) Or (Err.Number <> 0) Then
Wscript.Echo "Error DynWrap.Register " & " [" & iRet & "," & Err.Number & "]"
End If
iRet = oDynWrap.SendMessageA(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0)
If (iRet <> 0) Or (Err.Number <> 0) Then
Wscript.Echo "Error DynWrap.SendMessageA " & " [" & iRet & "," & Err.Number & "]"
End If
Set oDynWrap = Nothing
End Sub

1) Should Broadcast_It as written work for this situation of altered drive letters?
2) If not, can you suggest the appropriate broadcast and DynaWrap code?
3) My environment is Windows XP. Should that matter?
4) Is DynaWrap supposed to return a status? If so, I get True for the call to .Register and 1 for the call to .SendMessageA.
5) Is there a better alternative to DynaWrap?

Thanks for any help
greggardner
 
Hello greggardner,

I have been taking this and other settings as a general topic for further study time-in time-out. I cannot give intelligent response to your satisfaction, in particular, I cannot test out broadly at this moment.

I would propose you pose the question to vb6/vb.net forums where you'll find many more members knowledgeable and fluent in windows messaging who may help rightaway. I'll be watching as well. In the meantime, maybe some other vbscripter will volunteer to contribute more insight...

One thing vbscripters may have to take with good grace all the same is that they have to accept there are areas where scripting is not going to be effective/efficient...

regards - tsuji
 
As a followup to my problem with changing drive letters from a script w/o rebooting, I've not yet found the proper way to work this using Win32 API calls.

However, in my Windows XP environment, I've discovered the diskpart.exe utility which will do what I need and can be controlled from a script.

It's not nearly as clean but was reasonably easy to setup and seems reliable so far.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top