Introduction
This code accepts a hostname, opens REGEDIT.EXE and enters the keystrokes to connect to a remote registry.
Background
I couldn't find any way of programmatically opening regedit and connecting to a remote host. After watching REGMON (by Sysinternals) open regedit and automatically navigate to a specific registry key, I was inspired to write this.
Since I couldn't find any other way of doing it, I figured others might find this useful.
Using the Code
Sub ControlRegedit
Accepts a hostname As String
then opens regedit
, navigates to where you enter a hostname, enters the hostname into the box and presses enter.
Sub ActivateRegeditWindow
Activates any window titled "Registry Editor".
Sub Snooze
Accepts number of milliseconds As Long
. Pauses execution for number of milliseconds.
Sub KillRegedit
Kills process called "regedit
".
Imports System.Runtime.InteropServices
Imports System.Text.RegularExpressions
Public Class RegeditConnector
Const VK_MENU = &H12
Const VK_F = &H46
Const VK_C = &H43
Const VK_Enter = &HD
Const VK_Left = &H25
Const VK_Right = &H27
Const VK_Home = &H24
Const VK_ESCAPE = &H1B
<DllImport("user32.dll", CallingConvention:=CallingConvention.StdCall, _
CharSet:=CharSet.Unicode, EntryPoint:="keybd_event", _
ExactSpelling:=True, SetLastError:=True)> _
Public Shared Sub keybd_event(ByVal bVk As Byte, ByVal bScan As Byte, _
ByVal dwFlags As IntPtr, ByVal dwExtraInfo As IntPtr)
End Sub
Private Declare Function TerminateProcess Lib "kernel32" Alias "TerminateProcess" _
(ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Sub btnOpenReg_Click(ByVal sender As System.Object, ByVal e _
As System.EventArgs) Handles btnOpenReg.Click
If txtRegRemoteHost.Text = "enter hostname" Then Exit Sub
Dim strHostname As String = Nothing
Dim reAlphaNumeric As New Regex("[a-zA-Z0-9_\-\.]")
If txtRegRemoteHost.Text <> "" Then
strHostname = txtRegRemoteHost.Text
Else
Exit Sub
End If
If Mid(strHostname, 1, 2) = "\\" Then strHostname = _
Replace(strHostname, "\\", "")
If reAlphaNumeric.IsMatch(strHostname) = True Then ControlRegedit(strHostname)
End Sub
Private Sub ControlRegedit(ByVal strHostname As String)
Dim intCharValue = Nothing
Dim hexCharValue = Nothing
Dim strCharToConvert As String = Nothing
Dim strSingleCharacter = Nothing
If cbxReuseRegedit.Checked = False Then KillRegedit() : Snooze(500)
Process.Start("regedit.exe")
Snooze(500)
ActivateRegeditWindow()
keybd_event(VK_ESCAPE, 0, 0, 0)
keybd_event(VK_Home, 0, 0, 0)
keybd_event(VK_Left, 0, 0, 0)
Snooze(25)
ActivateRegeditWindow()
keybd_event(VK_MENU, 0, 0, 0)
keybd_event(VK_F, 0, 0, 0)
keybd_event(VK_MENU, 0, 2, 0)
keybd_event(VK_C, 0, 0, 0)
Snooze(100)
ActivateRegeditWindow()
For i As Integer = 1 To Len(strHostname)
strSingleCharacter = Mid(strHostname, i, 1)
intCharValue = Asc(strSingleCharacter.ToUpper)
hexCharValue = "&H" & Hex(intCharValue)
keybd_event(hexCharValue, 0, 0, 0)
Snooze(20)
ActivateRegeditWindow()
Next
keybd_event(VK_Enter, 0, 0, 0)
If cbxExitWhenFinished.Checked = True Then End
End Sub
Private Sub ActivateRegeditWindow()
Try
AppActivate("Registry Editor")
Catch ex As Exception When ex.Message = _
"Process 'Registry Editor' was not found."
MsgBox("Error opening regedit")
End
End Try
End Sub
Private Sub Snooze(ByVal Milliseconds As Long)
System.Threading.Thread.Sleep(Milliseconds)
End Sub
Private Sub KillRegedit()
Dim myProcesses As Process() = Process.GetProcessesByName("regedit")
Dim myProcess As Process
For Each myProcess In myProcesses
If myProcess.MainWindowTitle = "Registry Editor" Then myProcess.Kill()
Next myProcess
End Sub
Private Sub txtRegRemoteHost_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles txtRegRemoteHost.Click
If txtRegRemoteHost.Text = "enter hostname" Then txtRegRemoteHost.Text = ""
If txtRegRemoteHost.Text > "" Then txtRegRemoteHost.SelectAll()
End Sub
Private Sub txtRegRemoteHost_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) Handles txtRegRemoteHost.KeyDown
If e.KeyCode = Keys.Enter Then
btnOpenReg.PerformClick()
End If
End Sub
End Class
Points of Interest
This code could easily be modified to work with any other program as long as the app can be manipulated by the keyboard.
Note: When entering key strokes with kbd_event
it simply presses the key, in lower case, as you would with the keyboard. But when pressing ALT, CTRL, SHIFT or the Windows keys they stay down until told to release. So experimenting with this code can cause your keyboard to do funny things. If they seem stuck; pressing each of the ALT, CTRL, SHIFT and Windows keys a few times seems to release them.
History
I plan on writing a console version that accepts "regconnect \\<hostname>
" in the near future. I will post it when I do.
- 11/13/2008 2:32 PM - While writing the console version, I found that backslash gets converted into the hex value for the Windows key (&H5C). So entering
\\L
for a hostname gets interpreted into <Windows key><Windows key>L
which is the hotkey for "lock the desktop".