65.9K
CodeProject 正在变化。 阅读更多。
Home

打开 Regedit 并连接到远程主机

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1投票)

2008年11月13日

CPOL

2分钟阅读

viewsIcon

47295

downloadIcon

502

打开 regedit 并连接到远程主机的代码。

引言

这段代码接受一个主机名,打开 REGEDIT.EXE 并输入按键以连接到远程注册表。

背景

我找不到任何以编程方式打开注册表编辑器并连接到远程主机的方法。 在观看 REGMON (由 Sysinternals 提供) 打开注册表编辑器并自动导航到特定注册表项后,我受到了启发,编写了这段代码。
由于我找不到其他方法来做到这一点,我认为其他人可能会觉得这很有用。

Using the Code

Sub ControlRegedit

接受一个主机名作为 String,然后打开 regedit,导航到您输入主机名的地方,将主机名输入到框中并按回车键。

Sub ActivateRegeditWindow

激活任何标题为“注册表编辑器”的窗口。

Sub Snooze

接受以毫秒为单位的数字作为 Long。 暂停执行指定的毫秒数。

Sub KillRegedit

杀死名为“regedit”的进程。

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

关注点

只要可以通过键盘操作应用程序,就可以轻松地修改此代码以与任何其他程序一起使用。

注意:使用 kbd_event 输入按键时,它只是按下该键,以小写形式,就像您使用键盘一样。 但是在按下 ALT、CTRL、SHIFT 或 Windows 键时,它们会保持按下状态,直到被告知释放为止。 因此,试验此代码可能会导致您的键盘做出奇怪的事情。 如果它们看起来卡住了;多次按下 ALT、CTRL、SHIFT 和 Windows 键中的每一个似乎可以释放它们。

历史 

我计划在不久的将来编写一个控制台版本,该版本接受“regconnect \\<主机名>”。 我会在完成后发布它。

  • 2008 年 11 月 13 日下午 2:32 - 在编写控制台版本时,我发现反斜杠被转换为 Windows 键的十六进制值 (&H5C)。 因此,输入 \\L 作为主机名会被解释为 <Windows 键><Windows 键>L,这是“锁定桌面”的热键。
© . All rights reserved.