Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

Open Regedit and Connect to Remote Host

4.00/5 (1 vote)
13 Nov 2008CPOL2 min read 46.9K   481  
Code to open regedit and connect to remote host

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

VB.NET
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.

VB.NET
Sub ActivateRegeditWindow

Activates any window titled "Registry Editor".

VB.NET
Sub Snooze

Accepts number of milliseconds As Long.  Pauses execution for number of milliseconds.

VB.NET
Sub KillRegedit

Kills process called "regedit".

VB.NET
Imports System.Runtime.InteropServices
Imports System.Text.RegularExpressions

' Key sequence to connect to remote registry:
' With regedit.exe open type: 
' 1)  ALT+F           Open file menu
' 2)  C               Select "Connect Remote Registry"
' 3)  release ALT     Let go of ALT key (obvious to us humans 
'                     but the computer has to be told)
' 4)  type hostname   Type hostname of remote host
' 5)  press enter     Pressing enter clicks OK


Public Class RegeditConnector
    Const VK_MENU = &H12    ' ALT
    Const VK_F = &H46       ' F
    Const VK_C = &H43       ' C
    Const VK_Enter = &HD    ' ENTER
    Const VK_Left = &H25    ' LEFT arrow
    Const VK_Right = &H27   ' RIGHT arrow
    Const VK_Home = &H24    ' HOME
    Const VK_ESCAPE = &H1B  ' ESCAPE


    <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

    ' Function to terminate a process
    Private Declare Function TerminateProcess Lib "kernel32" Alias "TerminateProcess" _
			(ByVal hProcess As Long, ByVal uExitCode As Long) As Long

    ' btnOpenReg
    Private Sub btnOpenReg_Click(ByVal sender As System.Object, ByVal e _
			As System.EventArgs) Handles btnOpenReg.Click
        ' Oops, someone clicked the button too soon
        If txtRegRemoteHost.Text = "enter hostname" Then Exit Sub

        ' Var to store hostname
        Dim strHostname As String = Nothing

        ' Finds any alphanumeric string, underscore, hyphen and period 
        Dim reAlphaNumeric As New Regex("[a-zA-Z0-9_\-\.]")

        ' Assign txtRegRemoteHost to strHostname if there is something to add.
        If txtRegRemoteHost.Text <> "" Then
            strHostname = txtRegRemoteHost.Text
        Else
            Exit Sub
        End If

        ' If \\<hostname> was entered then replace the \\ with nothing
        If Mid(strHostname, 1, 2) = "\\" Then strHostname = _
					Replace(strHostname, "\\", "")

        ' If all characters are valid then assume its a hostname and run regedit
        If reAlphaNumeric.IsMatch(strHostname) = True Then ControlRegedit(strHostname)

    End Sub

    ''' <summary>
    ''' Sub to send keystrokes to regedit
    ''' </summary>
    ''' <param name="strHostname">Hostname to connect regedit to As String</param>
    ''' <remarks></remarks>
    Private Sub ControlRegedit(ByVal strHostname As String)
        Dim intCharValue = Nothing
        Dim hexCharValue = Nothing
        Dim strCharToConvert As String = Nothing
        Dim strSingleCharacter = Nothing

        ' If Reuse Regedit isn't checked then kill Regedit and sleep for a half second
        If cbxReuseRegedit.Checked = False Then KillRegedit() : Snooze(500)

        Process.Start("regedit.exe")        ' Run regedit.exe
        Snooze(500)                         ' Pause for .5 second for regedit to appear

        ActivateRegeditWindow()             ' Activate Regedit Window

        ' The following 3 lines are optional.  They collapse the local registry 
        ' tree down to "My Computer" so its easier to see the remote hosts registry.
        keybd_event(VK_ESCAPE, 0, 0, 0)     ' Hit escape twice to clear 
				       ' any existing regedit dialogs
        keybd_event(VK_Home, 0, 0, 0)       ' Go to top of Registry tree 
                                            ' and by hitting HOME key
        keybd_event(VK_Left, 0, 0, 0)       ' Hit Left arror to collapse 
                                            ' local registry tree
        Snooze(25)

        ActivateRegeditWindow()             ' Activate Regedit Window again 
                                            ' in case it lost focus

        keybd_event(VK_MENU, 0, 0, 0)       ' Press and hold ALT key
        keybd_event(VK_F, 0, 0, 0)          ' Press F
        keybd_event(VK_MENU, 0, 2, 0)       ' Release ALT key
        keybd_event(VK_C, 0, 0, 0)          ' Hit C to select "Connect Network Registry"
        Snooze(100)                         ' Wait for "Select Computer" 
                                            ' dialog to appear

        ActivateRegeditWindow()             ' Activate Regedit Window again 
                                            ' in case it lost focus

        ' Convert each char in the hostname to HEX values and type the keystrokes 
        ' into the object name field
        For i As Integer = 1 To Len(strHostname)            ' Loop once for each 
                                                            ' character entered
            strSingleCharacter = Mid(strHostname, i, 1)     ' Grab single character and 
						     ' assign to 
                                                            ' strSingleCharacter
            intCharValue = Asc(strSingleCharacter.ToUpper)  ' Get the decimal value of 
                                                            ' single character and 
                                                            ' assign to intCharValue
            hexCharValue = "&H" & Hex(intCharValue)         ' Convert intCharValue to 
                                                            ' Hex and prepend &H to make 
                                                            ' it look like real 
                                                            ' authentic Hex
            keybd_event(hexCharValue, 0, 0, 0)              ' Press key based on its 
                                                            ' hex value
            Snooze(20)                                      ' Pause briefly (this 
                                                            ' prevents missing letters)
            ActivateRegeditWindow()                         ' Activate Regedit Window 
                                                            ' again in case it 
                                                            ' lost focus
        Next

        keybd_event(VK_Enter, 0, 0, 0)                      ' Press enter which clicks OK

        If cbxExitWhenFinished.Checked = True Then End '      If "Exit When Finished" 
                                                       '      is checked then End
    End Sub

    ''' <summary>
    ''' Sub to activate Registry Editor window
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub ActivateRegeditWindow()
        Try
            AppActivate("Registry Editor")  ' Make Registry Editor the active window
        Catch ex As Exception When ex.Message = _
				"Process 'Registry Editor' was not found."
            MsgBox("Error opening regedit")
            End ' Can't find registry editor window so end
        End Try
    End Sub

    ''' <summary>
    ''' Sub to pause execution for n number of milliseconds
    ''' </summary>
    ''' <param name="Milliseconds">Number of milliseconds to pause As Long</param>
    ''' <remarks></remarks>
    Private Sub Snooze(ByVal Milliseconds As Long)
        System.Threading.Thread.Sleep(Milliseconds)
    End Sub

    ''' <summary>
    ''' Sub to Kill Regedit process if found.
    ''' </summary>
    ''' <remarks></remarks>
    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

    ' Clear "enter hostname" if found otherwise SelectAll text
    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

    ' Pressing Enter in hostname textbox clicks btnOpenReg
    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".

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)