注册表学习及其使用

Windows系统
522
0
0
2023-06-23

1. 注册表

是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息。

  • [ HKEY_CLASSES_ROOT ]==[ HKCR ]系统文件信息

记录Windows操作系统中所有数据文件的格式和关联信息,主要记录不同文件的文件名后缀和与之对应的应用程序。其下子键可分为两类:一类是已经注册的各类文件的扩展名,这类子键前面都有一个“.”;另一类是各类文件类型有关信息。

  • 官方已做如下建议:

HKEY_CLASSES_ROOT为早期版本的 Windows 设计的程序提供此合并视图。 若要更改交互式用户的设置,必须更改 HKEY_CURRENT_USER Software Classes ,而不是HKEY_CLASSES_ROOT。 若要更改默认设置,必须更改 HKEY_LOCAL_MACHINESoftwareClasses 。 如果将信息写入注册表项下的HKEY_CLASSES_ROOT,系统会将信息存储在 HKEY_LOCAL_MACHINESoftwareClasses 下。 如果将值写入 HKEY_CLASSES_ROOT 下的项,并且该项键值已存在,则系统会将信息存储在 HKEY_CURRENT_USERSoftwareClasses ,而不是存储在 HKEY_LOCAL_MACHINESoftwareClasses 。

  • [ HKEY_CURRENT_USER ]==[ HKCU ]当前用户数据

当前登录用户的用户配置文件信息。

  • [ HKEY_LOCAL_MACHINE ]==[ HKLM ]系统核心数据

当前计算机的配置数据,包括所安装的硬件以及软件的设置。

  • [ HKEY_USERS ]==[ HKU ]用户数据

默认用户的信息(Default子键)和所有以前登录用户的信息。

  • [ HKEY_CURRENT_CONFIG ]当前配置数据

是HKEY_LOCAL_MACHINE中的一部分,其中存放的是计算机当前设置。

2. 修改注册表的方法

切记修改注册表前,一定要备份

  • regedit 注册表编辑器

在dos窗口或 powershell 窗口,输入regedit回车,出现注册表编辑器界面。

  • reg命令

在dos窗口或powershell窗口,输入reg /?查看帮助。

  • powershell(pwsh)

在powershell窗口,输入help item查看相关帮助。

  • 编写reg注册表脚本文件

扩展名为.reg的文本文件,有固定的格式要求。

一般少量零星的注册表操作, 直接使用regedit或reg过powershell操作方便; 为实现某个功能需对注册表进行有关联的操作,编写.reg文件比较合适。

3. 数据类型对照表

:

  1. reg_multi_sz和reg_expand_sz不常用, 若必须使用,建议用regedit、reg、powershell操作注册表
  2. 键值支持 环境变量 (%var%)和位置参数(%n)
  3. 特殊字符(“)需转义(), 如:””%SystemRoot%system32notepad.exe ” “%1″”

4. 修改注册表配置环境变量

修改注册表的项键值,达到设置环境变量的目的。

4.1. 环境变量所在注册表位置

  • 用户变量所在位置 :HKEY_CURRENT_USEREnvironment
  • 系统变量所在位置 :HKEY_LOCAL_MACHINESYSTEMControlSet001ControlSession ManagerEnvironment

4.2. regedit注册表编辑器

按win+r后,输入regedit回车,出现注册表编辑器界面,可以直接进行增删改查、导出、导入等操作。

4.3. reg和powershell操作注册表

设置java环境变量为例,编写bat或cmd或ps1文件。

  • reg命令
 :: env_java.bat or env_java.cmd
:: reg /?

:: 临时变量
set hkcu_env_root="HKEY_CURRENT_USEREnvironment"
set hklm_env_root="HKEY_LOCAL_MACHINESYSTEMControlSetControlSession ManagerEnvironment"

reg query %hkcu_env_root%
reg query %hklm_env_root%CLASSPATH

:: 设置系统环境变量
reg add %hklm_env_root% /v JAVA_HOME /t REG_SZ /d "D:\java\jdk-" /f
reg add %hklm_env_root% /v CLASSPATH /t REG_SZ /d .;^%JAVA_HOME^%lib /f
:: 注意: 在扩充字符串中使用插入符号 ( ^ ) 保留%
: reg add %hklm_env_root% /v Path /t REG_EXPAND_SZ  /d ^%JAVA_HOME^%bin;%Path% /f
:: %var%将被替换为实际值
reg add %hklm_env_root% /v Path /t REG_EXPAND_SZ  /d "%JAVA_HOME%bin;%Path%" /f

:: 若是设置用户环境变量,用%hkcu_env_root% 
  • 用powershell
 ; env_java.ps
; help item

; 临时变量
$hkcu_env_root="Registry::HKEY_CURRENT_USEREnvironment"
$hklm_env_root="Registry::HKEY_LOCAL_MACHINESYSTEMControlSetControlSession ManagerEnvironment"
; Registry::HKEY_CURRENT_USER === HKCU:
; $hkcu_env_root="HKCU:Environment"
; $hklm_env_root="HKLM:SYSTEMControlSetControlSession ManagerEnvironment"

; 查看已存在的环境变量
get-item $hkcu_env_root
get-item $hklm_env_root

; help  Get-ItemProperty
; Get-ItemProperty -path $hklm_env_root -name TMP
Get-ItemProperty $hklm_env_root TMP
Get-ItemPropertyValue $hklm_env_root TMP

; 设置系统环境变量
; help Set-ItemProperty
; -type [String<REG_SZ>|ExpandString<REG_EXPAND_SZ>|Binary<REG_BINARY>|DWord<REG_DWORD>|MultiString<REG_MULTI_SZ>|Qword<REG_QWORD>]
; Set-ItemProperty -path $hklm_env_root -name JAVA_HOME -value "D:\java\jdk-\" -type string -force
Set-ItemProperty $hklm_env_root JAVA_HOME "D:javajdk-" -type string -force
; 仅使用时%JAVA_HOME%会被替换实际值
Set-ItemProperty $hklm_env_root CLASSPATH ".;%JAVA_HOME%lib" -type ExpandString -force
Set-ItemProperty $hklm_env_root Path "%JAVA_HOME%bin;%Path%" -type String -force

; 若是设置用户环境变量,用$hkcu_env_root 

5. reg文件编写

5.1. .reg文件

Windows 中的注册表文件( system.dat 和 user.dat )是 Windows 的核心数据库。

REG文件实际上是一种注册表脚本文件,双击REG文件即可将其中的数据导入到注册表中。

路径分隔符不要用’/’

5.2. 文件格式

 <关键字>
<空行>
; 注释行
<注册表操作集合>
<空行> 

<关键字> :一般是”Windows Registry Editor Version 5.00″。 若是Windows9X/ME/NT4.0是REGEDIT4。

<注册表操作集合> : 一般格式如下的一行或多行:

 [注册表路径]
[-注册表路径]
[注册表路径项名]
; REG_SZ的格式
"键名"="数据值"
[注册表路径项名]
; 非REG_SZ的格式
"键名"=数据类型:新数据值
[注册表路径项名]
"键名"=- 

PS: 当数据类型是非REG_GZ,需要填入 Hex值 ,可以用regedit随便创建一个项键值对,将值填入需要的数据,然后导出此项的reg文件,查看此文件中的键值内容。

5.3. 字符串与hex的互转

用pwsh将字符串( reg_expand_sz 或 reg_multi_sz )与Hex( Hex(2) 或 Hex(7) )实现互转:

 ; reg_expand_sz => Hex()
; 单行实现
 'hex():{0},00,00' -f (@( [System.Text. Encoding ]::GetEncoding("utf-16").GetBytes("%tmp%;0123,abcd;中文;!@#$") | %{ $_.tostring('x2')} ) -join ',' )
; 分步实现
$str_value ="%tmp%;,abcd;中文;!@#$"
; $str_bin =  @( $str_value.ToCharArray() | %{ ([int]$_).ToString('x04') } | %{ '{1},{0}' -f $_.substring(0,2), $_.substring(2,2) } ) -join ','
$str_bin =  @( [System.Text.Encoding]::GetEncoding("utf-").GetBytes($str_value) | %{ $_.tostring('x2')} ) -join ','
$hex_value = 'hex():{0},00,00' -f $str_bin
"CONVERT '{}' TO '{1}'" -f $str_value, $hex_value

; reg_multi_sz => hex()
; 单行实现
'hex():{0},00,00' -f  ( ( @( [System.Text.Encoding]::GetEncoding("utf-16").GetBytes("%tmp%

abcd
中文
!@#$
") | %{ $_.tostring('x')} ) -join ',' ) -replace ',0a,00',',00,00' )
; 分步实现
$str_value = "%tmp%
abcd
中文
!@#$

"
$str_bin =  @( [System.Text.Encoding]::GetEncoding("utf-").GetBytes($str_value) | %{ $_.tostring('x2')} ) -join ','
$hex_value = 'hex():{0}' -f  ( $str_bin -replace ',0a,00',',00,00' )
"CONVERT '{}' TO '{1}'" -f $str_value, $hex_value


; reg_expand_sz <= hex()
; 单行实现
[System.Text.Encoding]::GetEncoding("utf-").GetString(@( ("hex(2):25,00,74,00,6d,00,70,00,25,00,3b,00,30,00,31,00,32,00,33,00,2c,00,61,00,62,00,63,00,64,00,3b,00,2d,4e,87,65,3b,00,21,00,40,00,23,00,24,00,00,00".Remove(0,7) -replace ',00,00$','') -split ','  | % { (Invoke-Expression "0x$_") } ))
; 分步实现
$hex_value = "hex():25,00,74,00,6d,00,70,00,25,00,3b,00,30,00,31,00,32,00,33,00,2c,00,61,00,62,00,63,00,64,00,3b,00,2d,4e,87,65,3b,00,21,00,40,00,23,00,24,00,00,00"
$hex_data = $hex_value.substring( , $hex_value.length - 7 )
; $hex_data = ",00,74,00,6d,00,70,00,25,00,3b,00,30,00,31,00,32,00,33,00,2c,00,61,00,62,00,63,00,64,00,3b,00,2d,4e,87,65,3b,00,21,00,40,00,23,00,24,00,00,00"
$hex_data = $hex_data.substring(, $hex_data.length - 6 )
$str_bytes = @( $hex_data -split ','  | % { (Invoke-Expression "x$_") } )
$str_value = [System.Text.Encoding]::GetEncoding("utf-").GetString($str_bytes)
; $str_value = @( ( $hex_data | Select-String '([-9a-fA-F]{2},[0-9a-fA-F]{2})' -AllMatches  ).matches.value  |  % { "0x{1}{0}" -f $_.substring(0,2),$_.substring(3,2)} | % { [char] (Invoke-Expression $_) } ) -join ''
; $str_value = @( [regex]::matches($hex_data, "(?i)([-9a-fA-F]{2},[0-9a-fA-F]{2})") | %{$_.Groups[1].Value}  |  % { "0x{1}{0}" -f $_.substring(0,2),$_.substring(3,2)} | % { [char] (Invoke-Expression $_) } ) -join ''
"CONVERT '{}' TO '{1}'" -f $hex_value, $str_value


; reg_multi_sz <= hex()
; 单行实现
[System.Text.Encoding]::GetEncoding("utf-").GetString(@( ("hex(7):25,00,74,00,6d,00,70,00,25,00,00,00,30,00,31,00,32,00,33,00,00,00,61,00,62,00,63,00,64,00,00,00,2d,4e,87,65,00,00,21,00,40,00,23,00,24,00,00,00,00,00".Remove(0,7) -replace ',00,00$','') -split ','  | % { (Invoke-Expression "0x$_") } ))  -split ''
; 分步实现
$hex_value = "hex():25,00,74,00,6d,00,70,00,25,00,00,00,30,00,31,00,32,00,33,00,00,00,61,00,62,00,63,00,64,00,00,00,2d,4e,87,65,00,00,21,00,40,00,23,00,24,00,00,00,00,00"
$hex_data = $hex_value.substring( , $hex_value.length - 7 )
; $hex_data = ",00,74,00,6d,00,70,00,25,00,00,00,30,00,31,00,32,00,33,00,00,00,61,00,62,00,63,00,64,00,00,00,2d,4e,87,65,00,00,21,00,40,00,23,00,24,00,00,00,00,00"
$hex_data = $hex_data.substring(, $hex_data.length - 6 )
$str_bytes = @( $hex_data -split ','  | % { (Invoke-Expression "x$_") } )
$str_value = [System.Text.Encoding]::GetEncoding("utf-").GetString($str_bytes)
$str_value = $str_value -split ''
"CONVERT '{}' TO '" -f $hex_value; $str_value; "'"

5.4. 增删操作

5.4.1. 增删项

  • 在HKEY_CURRENT_CONFIG下新建项new_item
 [HKEY_CURRENT_CONFIGnew_item] 
  • 删除HKEY_CURRENT_CONFIG的项new_item
 [-HKEY_CURRENT_CONFIGnew_item] 

5.4.2. 增删键值

  • 在HKEY_CURRENT_CONFIGnew_item下新建键new_key
 [HKEY_CURRENT_CONFIGnew_item]
"new_key"="a new key's value"
; 修改直接将key的填改为新值 
  • 删除HKEY_CURRENT_CONFIGnew_item键new_key
 [HKEY_CURRENT_CONFIGnew_item]
"new_key"=- 

5.5. .reg样例(常见数据类型键值对)

 Windows Registry Editor Version.00

[HKEY_CURRENT_CONFIGtest]
@="我的默认字符串值"
"reg_sz"="%tmp%;,abcd;中文;!@#$"
"reg_binary"=hex:
"reg_dword"=dword:
"reg_qword"=hex(b):,00,00,00,00,00,00,00
"reg_expand_sz"=hex():25,00,74,00,6d,00,70,00,25,00,3b,00,30,00,31,00,32,00,33,00,2c,00,61,00,62,00,63,00,64,00,3b,00,2d,4e,87,65,3b,00,21,00,40,00,23,00,24,00,00,00
"reg_multi_sz"=hex():25,00,74,00,6d,00,70,00,25,00,00,00,30,00,31,00,32,00,33,00,00,00,61,00,62,00,63,00,64,00,00,00,2d,4e,87,65,00,00,21,00,40,00,23,00,24,00,00,00,00,00

6. 上下文(右键)菜单

6.1. 文件上下文菜单

在文件上右击,出现的菜单项.

6.1.1. 注册表位置([…*])

 ;; 文件选中
; 系统
[HKEY_CLASSES_ROOT* shell ]
[HKEY_CLASSES_ROOT${MyProgID}shell open ]
; 右键上下文菜单
@="菜单文字"
[HKEY_CLASSES_ROOT*shellexContextMenuHandlers] 
; 当前用户 和  本机
[HKEY_CURRENT_USERSoftwareClasses*]
[HKEY_LOCAL_MACHINESOFTWAREClasses*] 

6.1.2. 配置notepad++上下文菜单<文件>

 Windows Registry Editor Version.00

; 文件上下文菜单: "用notepad++打开"
[HKEY_CLASSES_ROOT*shellnotepad++]
@="用notepad++打开"
"icon"="D:\notepad++\notepad++.exe"
[HKEY_CLASSES_ROOT*shellnotepad++command]
@=“D:\notepad++\notepad++.exe "%"

6.1.3. 配置指定扩展名文件上下文菜单<文件>

 Windows Registry Editor Version.00

; MyProgID 配置
[HKEY_CLASSES_ROOT${MyProgID}DefaultIcon]
@="${MyProgID}.ico"
[HKEY_CLASSES_ROOT${MyProgID}shellopen]
; 右键上下文菜单
@="用${MyProgID}打开"
[HKEY_CLASSES_ROOT${MyProgID}shellopencommand]
@=""${MyProgID}.exe" "%""

; .myext关联${MyProgID}且有上下文菜单
[HKEY_CLASSES_ROOT.myext]
@="${MyProgID}"
[HKEY_CLASSES_ROOT.myextOpenWithProgids]
"${MyProgID}"=hex():

6.2. 目录上下文菜单

在目录上或当前目录空白处右击,出现的菜单项.

6.2.1. 注册表位置([… Directory ])

 ;; 系统
; 目录选中
[HKEY_CLASSES_ROOTDirectoryshell]
[HKEY_CLASSES_ROOTDirectoryshellexContextMenuHandlers]

; 当前目录空白处
[HKEY_CLASSES_ROOTDirectoryBackgroundshell]
[HKEY_CLASSES_ROOTDirectoryBackgroundshellexContextMenuHandlers]

;; 当前用户 和  本机
[HKEY_CURRENT_USERSOFTWAREClassesDirectory]
[HKEY_CURRENT_USERSOFTWAREClassesDirectoryBackground]
[HKEY_LOCAL_MACHINESOFTWAREClassesDirectory]
[HKEY_LOCAL_MACHINESOFTWAREClassesDirectoryBackground]

6.2.2. 配置wt(Windows Terminal)上下文菜单<目录>

 Windows Registry Editor Version.00

;; 右键菜单
; 右键目录(已选中)菜单
[HKEY_CLASSES_ROOTDirectoryshellwt]
; 菜单名称
@="Windows Terminal"
; 图标
"Icon"="D:\mylink\wt\terminal.ico"
[HKEY_CLASSES_ROOTDirectoryshellwtcommand]
; 执行命令
@="C:\Users\wuxr\AppData\Local\Microsoft\WindowsApps\wt.exe -d %V"

; 目录(未选中)右键菜单
[HKEY_CLASSES_ROOTDirectoryBackgroundshellwt]
@="Windows Terminal"
"Icon"="D:\mylink\wt\terminal.ico"
[HKEY_CLASSES_ROOTDirectoryBackgroundshellwtcommand]
@="C:\Users\wuxr\AppData\Local\Microsoft\WindowsApps\wt.exe -d %V"


; 以管理员身份运行 HKEY_CURRENT_USER 或 HKEY_LOCAL_MACHINE
[HKEY_CURRENT_USERSOFTWAREMicrosoftWindows NTCurrentVersionAppCompatFlagsLayers]
"C:\Users\wuxr\AppData\Local\Microsoft\WindowsApps\wt.exe"="~ RUNASADMIN"
PS: 若仅配置当前用户或本机,请修改为其对应的注册表位置.

7. 文件关联

将扩展名的文件关联一个或多个程序,会呈现默认关联程序图标,双击直接打开,右击出现”打开方式…”选择关联程序打开.

词条说明 :

  • 图标 = 呈现关联程序图标
  • 打开方式 = 右击文件出现”打开方式…”选项
  • 双击打开 = 双击文件由关联程序或选择某个关联程序打开

7.1. 注册表位置([….myext])

假定扩展名是.myext。

 ; 系统
[HKEY_CLASSES_ROOT.myext]
; 当前用户 
[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerFileExts.myext]

; 程序ID
[HKEY_CLASSES_ROOT${程序ID}]
[HKEY_CLASSES_ROOTApplications${程序ID}] 

7.2. 已存在的程序ID注册表配置

假设应用程序notepad++,notepad,vscode都已安装正常,并已存在下面的注册表内容.

 Windows Registry Editor Version.00

;; 程序ID
; [HKEY_CLASSES_ROOT${程序ID}]
; [HKEY_CLASSES_ROOTApplications${程序ID}]

;; notepad++
; ID=Notepad++_file
[HKEY_CLASSES_ROOTNotepad++_file]
[HKEY_CLASSES_ROOTNotepad++_fileSupportedTypes]
; ".myext"=""
[HKEY_CLASSES_ROOTNotepad++_fileshellopencommand]
@=""D:\notepad++\notepad++.exe" "%""
; ID=notepad++.exe
[HKEY_CLASSES_ROOTApplicationsnotepad++.exe]
[HKEY_CLASSES_ROOTApplicationsnotepad++.exeshellopencommand]
@=""D:\notepad++\notepad++.exe" "%""

;; VSCODE
; ID=vscode
[HKEY_CLASSES_ROOTvscode]
[HKEY_CLASSES_ROOTvscodeshellopencommand]
@=""D:\VSCode-win-x64\Code.exe" --open-url -- "%1""
; ID=Code.exe
[HKEY_CLASSES_ROOTApplicationsCode.exe]
[HKEY_CLASSES_ROOTApplicationsCode.exeshellopencommand]
@=""C:\Users\wuxr\AppData\Local\Programs\Microsoft VS Code\Code.exe" "%""

;; notepad
; ID=notepad.exe
[HKEY_CLASSES_ROOTApplicationsnotepad.exe]
[HKEY_CLASSES_ROOTApplicationsnotepad.exeshellopencommand]
@="%SystemRoot%systemnotepad.exe %1"

;; command=程序 参数...  支持环境变量(%var%),位置参数(%n),特殊符号(")需转义
; ""D:\notepad++\notepad++.exe" "%""
; "%SystemRoot%systemnotepad.exe %1"
; ""D:\VSCode-win-x64\Code.exe" --open-url -- "%1""
; ""C:\Users\wuxr\AppData\Local\Programs\Microsoft VS Code\Code.exe" "%""

7.3. 配置扩展名的关联程序

下面是扩展名(.myext)的文件,配置关联程序(notepad++,notepad,vscode)的注册表配置.

7.3.1. 全局扩展名关联

扩展名关联配置对所有用户有效.

  • 关联方法1
 Windows Registry Editor Version.00

;;; 关联方法:默认链接已存在的程序ID(仅限[HKEY_CLASSES_ROOT]下)
;; .myext默认关联包括: 图标, 打开方式,双击打开
[HKEY_CLASSES_ROOT.myext]
; 程序ID(仅[HKEY_CLASSES_ROOTNotepad++_file])
; @="${程序ID}"   ; 等同于链接
@="Notepad++_file"
  • 关联方法2
 Windows Registry Editor Version.00

;;; 关联方法:新建并关联程序
;; .myext默认关联包括: 图标,双击打开
[HKEY_CLASSES_ROOT.myextDefaultIcon]
@=""D:\notepad++\notepad++.exe","
[HKEY_CLASSES_ROOT.myextshellopencommand]
; 程序(D:\notepad++\notepad++.exe)
@=""D:\notepad++\notepad++.exe " "%""
; [-HKEY_CLASSES_ROOT.myextshell]
  • 关联方法3
 Windows Registry Editor Version.00

;;; 关联方法:OpenWithProgids链接已存在的程序ID(仅限[HKEY_CLASSES_ROOT]下)
;; .myext默认关联包括: 图标, 打开方式,双击打开
[HKEY_CLASSES_ROOT.myextOpenWithProgids]
; 程序ID(仅[HKEY_CLASSES_ROOT${程序ID}])   叠加OpenWithList
; "${程序ID}"=hex():   ; 等同于链接
"Notepad++_file"=hex():
"vscode"=hex():
  • 关联方法4
 Windows Registry Editor Version.00

;;; 关联方法:OpenWithList链接已存在的程序ID(仅限[HKEY_CLASSES_ROOTApplications]下)
;; .myext默认关联包括: 打开方式
[HKEY_CLASSES_ROOT.myextOpenWithList]
; 程序ID(仅[HKEY_CLASSES_ROOTApplications${程序ID}])
[HKEY_CLASSES_ROOT.myextOpenWithListnotepad++.exe]
[HKEY_CLASSES_ROOT.myextOpenWithListnotepad.exe]
; [-HKEY_CLASSES_ROOT.myextOpenWithList]

7.3.2. 当前用户配置扩展名关联

扩展名关联配置仅对当前用户有效.

  • 关联方法5
 Windows Registry Editor Version.00

;; 当前用户.myext的关联
[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerFileExts.myext]

;; .myext默认关联包括: 图标, 打开方式,双击打开
[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerFileExts.myextOpenWithProgids]
; 程序ID(仅[HKEY_CLASSES_ROOT${程序ID}])   叠加OpenWithList
; "${程序ID}"=hex():   ; 等同于链接
"Notepad++_file"=hex():
"vscode"=hex():

;; .myext默认关联包括: 双击打开选择关联程序
[HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerFileExts.myextOpenWithList]
; 程序ID(仅[HKEY_CLASSES_ROOTApplications${程序ID}])
"a"="notepad++.exe"
"b"="notepad.exe"
"MRUList"="ab"

;[-HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerFileExts.myext]

8. 参考资料

  1. 高级用户的 Windows 注册表信息
  2. 如何使用-reg-文件添加-修改或删除注册表子项和值
  3. powershellcore(pwsh)参考
  4. powershell关于正则
  5. Powershell: The many ways to use regex