插件:写入注册表REG_MULTI_SZ 类型的问题

优质
小牛编辑
112浏览
2023-12-01
这个插件不错,支持很多类型的键值的读取和写入,真的非常不错,对于经常跟注册表打交道的汉化软件安装程序,一定要备一个!

引用RegistryTest.nsi的内容:

Name "RegistryTest"
OutFile "RegistryTest.exe"

!include "Sections.nsh"

Var RADIOBUTTON

Page components
Page instfiles


Section "Basic registry functions" Basic
	registry::Write "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS" "new" "%WINDIR%\notepad.exe" "REG_EXPAND_SZ" .R0
	MessageBox MB_OK "registry::Write$\n$\n\
			Errorlevel: [$R0]"

	registry::Read "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS" "new" .R0 .R1 .R2 .R3
	MessageBox MB_OK 'registry::Read$\n$\n\
			$$R0    "path"   =[$R0]$\n\
			$$R1    "value" =[$R1]$\n\
			$$R2    "string" =[$R2]$\n\
			$$R3    "type"   =[$R3]$\n'

	registry::CreateKey "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS" "new1\new2" .R0
	MessageBox MB_OK "registry::CreateKey$\n$\n\
			Errorlevel: [$R0]"

	registry::CreateKey "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS" "new1\new2" .R0
	MessageBox MB_OK "registry::CreateKey$\n$\n\
			Errorlevel: [$R0]"

	registry::DeleteKey "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS\new1" .R0
	MessageBox MB_OK "registry::DeleteKey$\n$\n\
			Errorlevel: [$R0]"

	registry::DeleteValue "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS" "new" .R0
	MessageBox MB_OK "registry::DeleteValue$\n$\n\
			Errorlevel: [$R0]"

	registry::StrToHex "Some Value" .r0
	registry::Write "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS" "new" "$0" "REG_BINARY" .R0
	MessageBox MB_OK "registry::StrToHex$\n$\n\
			Hex string: [$0]"
	registry::Read "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS" "new" .R0 .R1 .R2 .R3
	registry::HexToStr "$R2" .R0
	MessageBox MB_OK "registry::HexToStr$\n$\n\
			String: [$R0]"
	registry::DeleteValue "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS" "new" .R0
SectionEnd


Section /o "Search for value 'Content Type'" SearchValue
	registry::Open /NOUNLOAD "HKEY_LOCAL_MACHINE" "/K=0 /V=1 /S=0 /B=1 /N='Content Type'" .r0
	StrCmp $0 -1 error

	loop:
	registry::Find /NOUNLOAD .r1 .r2 .r3 .r4

	MessageBox MB_OKCANCEL '$$1    "path"   =[$1]$\n\
				$$2    "value" =[$2]$\n\
				$$3    "string" =[$3]$\n\
				$$4    "type"   =[$4]$\n\
								$\n\
				Find next?' IDOK loop

	registry::Close
	goto end

	error:
	MessageBox MB_OK "Error"

	end:
SectionEnd


Section /o "Search and write founded in text file" SearchAndWriteInFile
	registry::Open /NOUNLOAD "HKEY_CURRENT_CONFIG" "/B=1" .r0
	StrCmp $0 -1 error

	GetTempFileName $R0
	FileOpen $R1 $R0 w
	FileWrite $R1 'HKEY_CURRENT_CONFIG$\r$\n$\r$\n'

	loop:
	registry::Find /NOUNLOAD .r1 .r2 .r3 .r4

	StrCmp $4 '' show
	StrCmp $4 'REG_KEY' 0 +3
	FileWrite $R1 '$4:"$1\$2"$\r$\n'
	goto +2
	FileWrite $R1 '$4:"$1" "$2"="$3"$\r$\n'
	goto loop

	show:
	registry::Close
	FileClose $R1
	Exec '"notepad.exe" "$R0"'
	goto end

	error:
	MessageBox MB_OK "Error"

	end:
SectionEnd


### If nsx.dll not found then "Search with banner" example will not be compile ###
!system 'ECHO.>"%TEMP%\Temp$$$.nsh"'
!system 'IF EXIST "${NSISDIR}\Plugins\nxs.dll" ECHO !define nxs_exist>>"%TEMP%\Temp$$$.nsh"'
!include "$%TEMP%\Temp$$$.nsh"
!system 'DEL "%TEMP%\Temp$$$.nsh"'

!ifdef nxs_exist
Section /o "Search with banner - 'NxS' plugin required" SearchWithBanner
	HideWindow

	nxs::Show /NOUNLOAD `$(^Name) Setup`\
		/top `Setup searching something$\nPlease wait... If you can...`\
		/pos 78 /h 0 /can 1 /end
	registry::Open /NOUNLOAD "HKLM\System" '/K=0 /V=1 /S=0 /N="Unexisted Name" /T=REG_DWORD /B=2' .r0
	StrCmp $0 -1 error

	loop:
	registry::Find /NOUNLOAD .r1 .r2 .r3 .r4

	StrCmp $4 'BANNER' 0 code
	nxs::Update /NOUNLOAD /sub "$1" /end
	nxs::HasUserAborted /NOUNLOAD
	Pop $0
	StrCmp $0 1 close

	code:
	StrCmp $4 '' close
	;... code
	goto loop

	close:
	registry::Close
	nxs::Destroy
	goto end

	error:
	MessageBox MB_OK "Error"

	end:
	BringToFront
SectionEnd
!endif


Section /o "Save to the file" SaveKey
	registry::SaveKey "HKEY_LOCAL_MACHINE\SOFTWARE\NSIS" "saved.reg" "/G=1 /D=2" .R0
	MessageBox MB_OK "registry::SaveKey$\n$\n\
			Errorlevel: $R0"
SectionEnd


Section /o "Restore from the file" RestoreKey
	registry::RestoreKey "saved.reg" .R0
	MessageBox MB_OK "registry::RestoreKey$\n$\n\
			Errorlevel: $R0"
SectionEnd


Function .onInit
	StrCpy $RADIOBUTTON ${Basic}
FunctionEnd

Function .onSelChange
	!insertmacro StartRadioButtons $RADIOBUTTON
	!insertmacro RadioButton ${Basic}
	!insertmacro RadioButton ${SearchValue}
	!insertmacro RadioButton ${SearchAndWriteInFile}
	!ifdef nxs_exist
		!insertmacro RadioButton ${SearchWithBanner}
	!endif
	!insertmacro RadioButton ${SaveKey}
	!insertmacro RadioButton ${RestoreKey}
	!insertmacro EndRadioButtons
FunctionEnd
插件与例子点击这里另存

至于不用插件,纯用脚本写的对于注册表这种类型的值的写入,以下是一个参考脚本例子:

OutFile "REG_MULTI_SZ_writer.exe"
Name "REG_MULTI_SZ"
ShowInstDetails show

!define HKEY_CLASSES_ROOT        0x80000000
!define HKEY_CURRENT_USER        0x80000001
!define HKEY_LOCAL_MACHINE      0x80000002
!define HKEY_USERS              0x80000003
!define HKEY_PERFORMANCE_DATA    0x80000004
!define HKEY_PERFORMANCE_TEXT    0x80000050
!define HKEY_PERFORMANCE_NLSTEXT 0x80000060
!define HKEY_CURRENT_CONFIG      0x80000005
!define HKEY_DYN_DATA            0x80000006

!define KEY_QUERY_VALUE          0x0001
!define KEY_SET_VALUE            0x0002
!define KEY_create_SUB_KEY      0x0004
!define KEY_ENUMERATE_SUB_KEYS  0x0008
!define KEY_NOTIFY              0x0010
!define KEY_create_LINK          0x0020

!define REG_NONE                0
!define REG_SZ                  1
!define REG_EXPAND_SZ            2
!define REG_BINARY              3
!define REG_DWORD                4
!define REG_DWORD_LITTLE_ENDIAN  4
!define REG_DWORD_BIG_ENDIAN    5
!define REG_LINK                6
!define REG_MULTI_SZ            7

!define RegcreateKey            "Advapi32::RegcreateKeyA(i, t, *i) i"
!define RegSetValueEx            "Advapi32::RegSetValueExA(i, t, i, i, i, i) i"
!define RegCloseKey              "Advapi32::RegCloseKeyA(i) i"

####### Edit this!
!define ROOT_KEY                "${HKEY_LOCAL_MACHINE}"
!define SUB_KEY                  "SOFTWARE\NSIS"
!define VALUE                    "RegMultiSzTest"
!define DATA_1                  "First string"
!define DATA_2                  "Second string"
####### Stop editing

Section "Write"
  SetPluginUnload alwaysoff
  ; create a buffer for the multi_sz value
  System::Call "*(t${NSIS_MAX_STRLEN}) i.r1"
  ; Open/create the registry key
  System::Call "${RegcreateKey}(${ROOT_KEY}, '${SUB_KEY}', .r0) .r9"
  ; Failed?
  IntCmp $9 0 write
    MessageBox MB_OK|MB_ICONSTOP "Can't create registry key! ($9)"
    Goto noClose

   write:
    ; Fill in the buffer with our strings
    StrCpy $2 $1                            ; Initial position

    StrLen $9 '${DATA_1}'                  ; Length of first string
    IntOp $9 $9 + 1                        ; Plus null
    System::Call "*$2(t$9 '${DATA_1}')"    ; Place the string
    IntOp $2 $2 + $9                        ; Advance to the next position

    StrLen $9 '${DATA_2}'                  ; Length of second string
    IntOp $9 $9 + 1                        ; Plus null
    System::Call "*$2(t$9 '${DATA_2}')"    ; Place the string
    IntOp $2 $2 + $9                        ; Advance to the next position

    System::Call "*$2(t1 '')"              ; Place the terminating null
    IntOp $2 $2 + 1                        ; Advance to the next position

     ; create/write the value
    IntOp $2 $2 - $1                        ; Total length
    System::Call "${RegSetValueEx}(r0, '${VALUE}', 0, ${REG_MULTI_SZ}, r1, r2) .r9"
    ; Failed?
    IntCmp $9 0 done
      MessageBox MB_OK|MB_ICONSTOP "Can't set key value! ($9)"
      Goto done

   done:
    ; Close the registry key
    System::Call "${RegCloseKey}(r0)"

noClose:
  ; Clear the buffer
  SetPluginUnload manual
  System::Free $1
SectionEnd