There are already lots of questions on how to read/write windows and their are number of good jni/non-jni solutions available. I've gone through a few, but neither of them provided means to traverse the registry.
By traversal, I mean to say that I want to know all sub-folders of a particular folder in Windows Registry and then all keys within that folder.
The available solutions, let's one read the registry key, but not the registry folder to find the sub-folders within.
Leverage the Windows API for registry access, and expose it via JNI.
Windows Registry API: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724875(v=vs.85).aspx
Key function being RegEnumKeyEx
Here is a tutorial on walking the registry keys in c++: http://www.codeguru.com/cpp/w-p/ce/registry/article.php/c8301/Walking-The-Registry-Tree.htm
I was requiring some solution in java, but then found some VBScrip that can do this much easily
Const HKEY_LOCAL_MACHINE = &H80000002
strKeyPath = "SOFTWARE\MICROSOFT\Windows\CurrentVersion\MMDevices\Audio\Capture"
Sub EnumerateKeys(hive, key)
'WScript.Echo key
reg.EnumKey hive, key, arrSubKeys
If Not IsNull(arrSubKeys) Then
For Each subkey In arrSubKeys
EnumerateKeys hive, key & "\" & subkey
Next
End If
reg.GetDWORDValue hive,key,"DeviceState",nn
'WScript.Echo key & " = " & nn
If nn=268435457 Then
'WScript.Echo "Good morning!"
reg.SetDWORDValue hive,key,"DeviceState",1
ElseIf nn=1 Then
reg.SetDWORDValue hive,key,"DeviceState",268435457
Else
'WScript.Echo "Have a nice day!"
End If
End Sub
Set reg = GetObject("winmgmts://./root/default:StdRegProv")
EnumerateKeys HKEY_LOCAL_MACHINE, strKeyPath
Above script not only iterates, over keys & subkeys, it also reads and compares and then sets DWORD values.
Quick Reference
Related
I am working on packaging a script for the company that I work for that will allow field service techs to convert computers in a private workstation OU to a team workstation OU and vice versa.
That is a small part of this script for now and one that has had me puzzled for most of the day. I've tried different variations of this script and landed on one that I believe will get me on the right track.
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select Name from Win32_ComputerSystem",,48)
For Each objItem in colItems
strPCName = objItem.Name
Next
Set objNewOU = GetObject("LDAP://OU=Computers,OU=Corporate,DC=xxxxx,DC=net")
Set objMoveComputer = objNewOU.MoveHere("LDAP://CN=" & strPCName & ",OU=Computers,OU=Corporate,DC=xxxxx,DC=net",vbnullstring)
I get an error, There is no such object on the server. When I put the computer manually in the OU in question, I don't get that error message. This is where I'm stuck at the moment.
The scripting is in my personal lab at the moment.
I was able to get a solution that did work, by using the following script.
Set objSysInfo = CreateObject("ADSystemInfo")
strComputerDN = objSysInfo.ComputerName
Set objNewOU = GetObject("LDAP://OU=Private Workstations,OU=xxxx,OU=xxxx,DC=xxxx,DC=xxxx")
Set objMoveComputer = objNewOU.MoveHere _ ("LDAP://" & strComputerDN, vbNullString)
Judging by the script's behavior, it uses strComputerDN to determine where the computer is, and the objNewOU determines where the computer is going. The objmoveComputer consolidates this information as best as I can determine to move the computer to it's OU.
Is there way to find the PC user in visual basic (C:\User\"here").
After we get it, just save it as a string.
I know the answer might be a bit obvious, but I cannot find out how to do this
Fairly simple, from here ( http://blogs.msdn.com/b/alejacma/archive/2008/03/11/how-to-get-the-user-running-a-vbscript.aspx )
Dim networkInfo
Set networkInfo = CreateObject("WScript.NetWork")
Dim infoStr
infoStr = "User name is " & networkInfo.UserName & vbCRLF & _
"Computer name is " & networkInfo.ComputerName & vbCRLF & _
"Domain Name is " & networkInfo.UserDomain
MsgBox infoStr
The simplest way might be to query the environment.
There are USERDOMAIN, USERNAME, USERPROFILE and COMPUTERNAME environment variables containing the obvious values.
Querying those would depend solely on WScript.Shell instead of on WScript.Network as in the accepted (and correct) answer. If you already have a reference to the shell, this might be a slightly more comfortable way.
I have an old VB6 app that opens an Word document (.doc). It has worked perfectly on Windows XP for a long time. My problem is that when I install the app on Windows 7 or Windows 8, the code will open Word, but not bring up the actual document. When it opens Word, I am able to navigate to file and open it perfectly fine, so there is no issue with the file. It seems like I'm missing something simple here, but after a lot of searching and reading, I can't pinpoint it.
I've made sure that Word is the program associated to .doc files on the Windows 7 and 8 computers, so that's not it.
Here is the code I use to open the document:
Dim iret As Long
iret = ShellExecute(hwnd, vbNullString, QuoteFilePath & File1.FileName, vbNullString, "c:\", SW_SHOWNORMAL)
Any help is appreciated!
There are a number of reasons why this special folder should not actually be used to store user documents. Microsoft and even 3rd parties have begun to use it for entirely different purposes. Depending on what applications have been installed you might even find DLLs in here.
If you mistrain users to play with this folder they might delete a file critical to the operation of some other program.
But if you insist on doing this note that it is not safe to refer to the folder by a literal string value since it can appear under varying aliases based on the user's language settings. It might even be relocated elsewhere through administrative actions.
It also hasn't been necessary to stoop to using the non-COM ShellExecute entrypoint in ages, at least as far back as version 5.0 of Shell32.dll.
This should work at least from WinXP forward:
Option Explicit
Private Const ssfCOMMONDOCUMENTS As Long = &H2E
Private Enum SHOW_WINDOW
SW_HIDE = 0
SW_SHOWNORMAL = 1
SW_SHOWMINIMIZED = 2
SW_SHOWMAXIMIZED = 3
SW_SHOWNOACTIVATE = 4
SW_SHOW = 5
SW_SHOWMINNOACTIVE = 7
SW_SHOWDEFAULT = 10
End Enum
Private Shell As Object
Private Path As String
Private Sub File1_Click()
On Error Resume Next
'Works on XP through Vista, fails on Win7:
'Shell.ShellExecute File1.FileName, , Path, "open", SW_SHOWNORMAL
'Works on XP through Win7:
Shell.ShellExecute Path & "\" & File1.FileName, , , "open", SW_SHOWNORMAL
If Err Then
MsgBox "Error " & CStr(Err.Number) & " " & Err.Description
End If
End Sub
Private Sub Form_Load()
Set Shell = CreateObject("Shell.Application")
With Shell.NameSpace(ssfCOMMONDOCUMENTS).Self
Path = .Path
End With
With File1
.Pattern = "*.doc"
.Path = Path
End With
End Sub
I want to find out the file sizes of the hives in the registry using WMI and VBScript. This is what I have so far:
const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set objReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\"&_
strComputer & "\root\cimv2:StdRegProv")
strKeyPath = "System\CurrentControlSet\Control\Hivelist"
objReg.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrVals, arrTypes
WScript.Echo "Values under System\CurrentControlSet\Control\Hivelist"
For Each val In arrVals
objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, val, dwValue
WScript.Echo dwValue
Next
This gives me the correct list, but then I need to get the file sizes. What is the best way to accomplish this?
To avoid type prefix fraud and meaningless variable names, use strRFSpec instead of dwValue
Convert the registry file spec (e.g. "\Device\HarddiskVolume1\Documents and Settings\NetworkService\NTUSER.DAT") into a strFSpec understandable to the FileSystemObject (e.g. "C:\Documents and Settings\NetworkService\NTUSER.DAT")
Check existence and accessability of strFSpec
WScript.Echo goFS.GetFile(strFSpec).Size
(tested under Win XP)
ADDED (wrt comment):
The conversion from strRFSpec to strFSpec may need more effort than a simple Replace() using hardcoded strings. Your Documents and Settings or your WINDOWS could live on F:\. So maybe you'll have to look for a WMI class that maps "\Device\HarddiskVolume... to a drive letter, to use %windir% on strFSpecs containing \system\, or ask WshShell.SpecialFolders("MyDocuments") for a drive letter. As my setup is simple, I can't give further - tested - advice.
I've got data in the registry under Current User which I want to add into predefined bookmarks in Word documents. Now, the thing is, I want the exact same macro in every single Word document and have the macro skip the step if it can't find the predefined bookmark.
I've got this code already where I need to predefine an array of the total data I've got in the registry. The macro stores the values of each subkey from the registry into a string. But doesn't insert the value into the bookmark unless the bookmark exists. Well, that's the idea anyway.
Public Sub TemplateData()
Dim objShell
Dim strShell
Dim strDataArea
Dim Values() As String
Dim Fields
' Input the exact same key as in registry
Fields = Array("DEPARTMENT", "LETTER", "LNAME", "FNAME")
Set objShell = CreateObject("Wscript.Shell")
strDataArea = "HKCU\Templates\"
On Error Resume Next
For iTeller = 0 To UBound(Fields)
Dim sBookMarkName, sValue
sBookMarkName = "Bookmark" & Fields(iTeller)
sValue = objShell.RegRead(strDataArea & Fields(iTeller))
Selection.GoTo What:=wdGoToBookmark, Name:=sBookMarkName
Selection.Delete Unit:=wdCharacter, Count:=0
Selection.InsertAfter sValue
Next
On Error GoTo 0
End Sub
If I put a breakpoint on the bottom Next, I can see that it indeed finds the bookmarks, but somehow it inserts the values of every registry subkey until it finds the correct one. And the initial idea is also to have the macro delete whatever words are in the bookmkarks if I run the macro again since if the data in the registry get updates, the macro should pick that up and insert it into the document.
Can anyone find what might be wrong here?
Error in a Word VBA macro, trying to insert values into bookmarks
has answers. Kenny learned himself (re-set the Bookmark):
ActiveDocument.Bookmarks.Add Range:=Selection.Range, Name:=sBookMarkName
and Tom helped to check before use...
If ActiveDocument.Bookmarks.Exists(sBookmarkName) Then
... insert using your code
End If