A)是爲什麼我的腳本不能正常工作
的可能的原因我不知道。聽起來似乎合理。
B)如果有一個註冊表編輯器替代
您可以查詢註冊表值與WMI和StdRegProv class。
試着保持它的美好和簡單。
對不起。這既不好也不簡單。
我不得不使用過去的WMI查詢模擬reg.exe
來查詢遠程註冊表。我一起砍了一個:getRegValue
函數,可以自動執行這個功能。運行這個,看看它是否會爲你的想法。
@echo off
setlocal
call :getRegValue accessVer HKCR\Access.Application\CurVer\
echo Result: %accessVer%
call :getRegValue shell "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell"
echo Result: %shell%
goto :EOF
:getRegValue <return_var> <root\path\valname>
setlocal enabledelayedexpansion
rem // constants
set "hive[HKCR]=&H80000000"
set "hive[HKCU]=&H80000001"
set "hive[HKLM]=&H80000002"
set "hive[HKU]=&H80000003"
set "hive[HKCC]=&H80000005"
set "type[1]=GetStringValue"
set "type[2]=GetExpandedStringValue"
set "type[3]=GetBinaryValue"
set "type[4]=GetDWORDValue"
set "type[7]=GetMultiStringValue"
set "type[11]=GetQWORDValue"
SET "wmic=wmic /namespace:\\root\default class stdregprov call"
rem // split %~2 into hive, path, leaf
set "regpath=%~2"
if "%regpath:~-1%"=="\" set "regpath=%regpath%(Default)"
set hive=%regpath:\=&rem;%
set "regpath=!regpath:%hive%\=!"
set "leaf=%regpath%"
:leaf
set "leaf=%leaf:*\=%"
if not "%leaf%"=="%leaf:\=%" goto leaf
set "regpath=!regpath:\%leaf%=!"
set "hive=!hive[%hive%]!"
rem // get data type of leaf (default: string)
set "method=%type[1]%"
for %%I in (names types nameidx) do set "%%I="
2>NUL (
for /f "tokens=2 delims={}" %%I in (
'%wmic% EnumValues hDefKey^="%hive%" sSubkeyName^="%regpath:\=\\%"^
^| find "= {"'
) do (
if not defined names (set "names=%%I") else set "types=%%I"
)
)
if defined names (
for %%n in (names types) do (
set idx=0
for %%I in (!%%n!) do (
if defined nameidx (
if !idx! equ !nameidx! set "method=!type[%%~I]!"
) else if /i "%%~I"=="%leaf%" (
set "nameidx=!idx!"
)
set /a idx += 1
)
)
)
if /i "%leaf%"=="(Default)" set "leaf="
rem // get data value of leaf
2>NUL (
for /f "delims=" %%I in (
'%wmic% %method% hDefKey^="%hive%" sSubkeyName^="%regpath:\=\\%"^
sValueName^="%leaf%" ^| findstr "[su]Value"'
) do (
for %%# in (%%I) do set "ret=%%~#"
)
)
endlocal & set "%~1=%ret%" & goto :EOF
的思想作爲額外的食物,wmic.exe
支持以下語法遠程查詢:
wmic /node:remotePC /user:domain\remoteAdmin /password:password verbs...
而不是讓每個用戶在登錄時運行腳本,你可以使用遙控開關來查詢所有機器都批量生產。
天色作爲一項學術活動,部分來阻止任何人誰可能會想:「你應該使用PowerShell」,我改寫了:getRegValue
函數調用PowerShell的混合代碼。不幸的是,使用PowerShell通過WMI查詢註冊表仍然很複雜。雖然字符串操作和對象檢索更容易,但稍微更經濟的代碼並不能證明增加的執行時間。
<# : regval.bat
@echo off
setlocal
call :getRegValue accessVer HKCR\Access.Application\CurVer\
echo Result: %accessVer%
call :getRegValue shell "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell"
echo Result: %shell%
goto :EOF
:getRegValue <return_var> <root\path\valname>
setlocal
set "regpath=%~2"
for /f "delims=" %%I in (
'powershell -noprofile -noninteractive "iex (gc \"%~f0\" | out-string)"'
) do (
endlocal
set "%~1=%%~I"
)
goto :EOF
: powershell hybrid code #>
$hiveConst = @{
"HKCR" = 2147483648
"HKCU" = 2147483649
"HKLM" = 2147483650
"HKU" = 2147483651
"HKCC" = 2147483653
}
# http://www.vistax64.com/powershell/10160-powershell-remote-registry-access-via-wmi.html
$reg = gwmi -List -Namespace root\default | ?{ $_.Name -eq "StdRegProv" }
# split $env:regpath into $hive, $regpath, $leaf
$regpath = $env:regpath -split "\\"
$hive = $hiveConst[$regpath[0]]
$leaf = $regpath[$regpath.length - 1]
if ($leaf) {
$regpath = $regpath[1..($regpath.length - 2)] -join "\"
} else {
$regpath = $regpath[1..($regpath.length - 1)] -join "\"
}
if ($leaf -match "^\(Default\)$") { $leaf = "" }
# get data type of leaf (default: string)
$method = 1
$res = $reg.EnumValues($hive, $regpath)
for ($i = 0; $i -lt $res.sNames.length; $i++) {
if ($res.sNames[$i] -eq $leaf) {
$method = $res.Types[$i]
}
}
# get data value of leaf
switch ($method) {
1 { $reg.GetStringValue($hive, $regpath, $leaf).sValue; break }
2 { $reg.GetExpandedStringValue($hive, $regpath, $leaf).sValue; break }
3 { $reg.GetBinaryValue($hive, $regpath, $leaf).uValue; break }
4 { $reg.GetDWORDValue($hive, $regpath, $leaf).uValue; break }
7 { $reg.GetMultiStringValue($hive, $regpath, $leaf).sValue; break }
11 { $reg.GetQWORDValue($hive, $regpath, $leaf).uValue; break }
}
只是因爲我覺得自己是一個挑戰,我決定嘗試第三個版本採用的JScript混合代碼這段時間。相信與否,這是三種方法中最快的。
@if (@CodeSection == @Batch) @then
@echo off & setlocal
call :getRegValue accessVer HKCR\Access.Application\CurVer\
echo Result: %accessVer%
call :getRegValue shell "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell"
echo Result: %shell%
goto :EOF
:getRegValue <return_var> <root\path\valname>
for /f "delims=" %%I in ('cscript /nologo /e:JScript "%~f0" "%~2"') do set "%~1=%%~I"
goto :EOF
@end // end batch/begin JScript hybrid code
function reg(strMethod, objParams) {
try {
var winmgmts = GetObject('winmgmts:root\\default'),
StdRegProv = winmgmts.Get('StdRegProv');
params = StdRegProv.Methods_(strMethod).InParameters.SpawnInstance_();
for (var i in objParams) params[i] = objParams[i];
return winmgmts.ExecMethod('StdRegProv', strMethod, params);
}
catch(e) { return {'sValue':''} }
};
var hiveConst = {
"HKCR" : 2147483648,
"HKCU" : 2147483649,
"HKLM" : 2147483650,
"HKU" : 2147483651,
"HKCC" : 2147483653
},
methodConst = {
"1" : "GetStringValue",
"2" : "GetExpandedStringValue",
"3" : "GetBinaryValue",
"4" : "GetDWORDValue",
"7" : "GetMultiStringValue",
"11" : "GetQWORDValue"
},
regpath = WSH.Arguments(0).split('\\'),
hive = hiveConst[regpath.shift()],
leaf = regpath.pop(),
regpath = regpath.join('\\');
if (/^\(Default\)$/.test(leaf)) leaf = '';
// get data type of leaf (default: string)
try {
var params = {'hDefKey': hive, 'sSubKeyName': regpath},
res = reg('EnumValues', params),
sNames = res.sNames.toArray(),
Types = res.Types.toArray();
for (var i in sNames) {
if (sNames[i] == leaf) var method = methodConst[Types[i]];
}
}
catch(e) { var method = methodConst[1] }
// get and output data value of leaf
var params = {'hDefKey': hive, 'sSubKeyName': regpath, 'sValueName': leaf},
res = reg(method, params);
WSH.Echo(res.sValue || res.uValue);
有一個wmi類可以讀取註冊表。雖然這不是很好,但很簡單。只要有機會,我會發佈一個答案,除非其他人感覺像展示。 – rojo