diff --git a/package.json b/package.json index d36d023..29d46bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "JUSTAR", - "version": "2.2.3", + "version": "2.2.4", "description": "钜星科技便民问诊系统", "main": "src/index.js", "scripts": { @@ -26,6 +26,10 @@ { "from": "./appData", "to": "../appData" + }, + { + "from": "./node_modules/regedit/vbs", + "to": "../src/vbs" } ], "files": [ @@ -94,6 +98,7 @@ "jquery": "^3.6.0", "node-fetch": "2.6.1", "popper.js": "^1.16.1", + "regedit": "^5.1.2", "windows-shortcuts": "^0.1.6" }, "devDependencies": { diff --git a/src/js/main.js b/src/js/main.js index 1dae679..f568f21 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -159,7 +159,7 @@ let main ={ } }, { - label:'版本号:2.2.3', + label:'版本号:2.2.4', icon: respath + path.sep+ "static"+ path.sep+"images"+ path.sep+"paste.png", },] }); diff --git a/src/vbs/ArchitectureAgnosticRegistry.vbs b/src/vbs/ArchitectureAgnosticRegistry.vbs new file mode 100644 index 0000000..bc92d85 --- /dev/null +++ b/src/vbs/ArchitectureAgnosticRegistry.vbs @@ -0,0 +1,75 @@ +' Notes: wanted to implement this using a class but: +' 1. No matter what I did I could not assign the result of GetObject to a private member +' 2. It looks as if all methods were treated as subs from the outside world which is not good since +' some of these need to return a value +' + +Set private_oReg = GetObject("winmgmts:\root\default:StdRegProv") + +Function SetStringValue(constHive, strSubKey, strValueName, strValue) + SetStringValue = private_oReg.SetStringValue(constHive, strSubKey, strValueName, strValue) +End Function + +Sub GetStringValue(constHive, strKey, strValueName, strValue) + private_oReg.GetStringValue constHive, strKey, strValueName, strValue +End Sub + +Function SetExpandedStringValue(constHive, strSubKey, strValueName, strValue) + SetExpandedStringValue = private_oReg.SetExpandedStringValue(constHive, strSubKey, strValueName, strValue) +End Function + +Sub GetExpandedStringValue(constHive, strKey, strValueName, strValue) + private_oReg.GetExpandedStringValue constHive, strKey, strValueName, strValue +End Sub + +Function SetMultiStringValue(constHive, strSubKey, strValueName, arrValue) + SetMultiStringValue = private_oReg.SetMultiStringValue(constHive, strSubKey, strValueName, arrValue) +End Function + +Sub GetMultiStringValue(constHive, strKey, strValueName, arrStrValue) + private_oReg.GetMultiStringValue constHive, strKey, strValueName, arrStrValue +End Sub + +Function SetDWORDValue(constHive, strSubKey, strValueName, arrValue) + SetDWORDValue = private_oReg.SetDWORDValue(constHive, strSubKey, strValueName, arrValue) +End Function + +Sub GetDWORDValue(constHive, strKey, strValueName, intDWordValue) + private_oReg.GetDWORDValue constHive, strKey, strValueName, intDWordValue +End Sub + +Function SetQWORDValue(constHive, strSubKey, strValueName, strQWordValue) + SetQWORDValue = private_oReg.SetQWORDValue(constHive, strSubKey, strValueName, strQWordValue) +End Function + +Sub GetQWORDValue(constHive, strKey, strValueName, intQWordValue) + private_oReg.GetQWORDValue constHive, strKey, strValueName, intQWordValue +End Sub + +Function SetBinaryValue(constHive, strSubKey, strValueName, arrValue) + SetBinaryValue = private_oReg.SetBinaryValue(constHive, strSubKey, strValueName, arrValue) +End Function + +Sub GetBinaryValue(constHive, strKey, strValueName, arrBinaryValue) + private_oReg.GetBinaryValue constHive, strKey, strValueName, arrBinaryValue +End Sub + +Function EnumKey(constHive, strSubKey, arrKeyNames) + EnumKey = private_oReg.EnumKey(constHive, strSubKey, arrKeyNames) +End Function + +Function EnumValues(constHive, strSubKey, arrValueNames, arrValueTypes) + EnumValues = private_oReg.EnumValues(constHive, strSubKey, arrValueNames, arrValueTypes) +End Function + +Function CreateKey(constHive, strSubKey) + CreateKey = private_oReg.CreateKey(constHive, strSubKey) +End Function + +Function DeleteKey(constHive, strSubKey) + DeleteKey = private_oReg.DeleteKey(constHive, strSubKey) +End Function + +Function DeleteValue(constHive, strSubKey, strValue) + DeleteValue = private_oReg.DeleteValue(constHive, strSubKey, strValue) +End Function diff --git a/src/vbs/ArchitectureSpecificRegistry.vbs b/src/vbs/ArchitectureSpecificRegistry.vbs new file mode 100644 index 0000000..58dba9c --- /dev/null +++ b/src/vbs/ArchitectureSpecificRegistry.vbs @@ -0,0 +1,358 @@ +' Notes: wanted to implement this using a class but: +' 1. No matter what I did I could not assign the result of GetObject to a private member +' 2. It looks as if all methods were treated as subs from the outside world which is not good since +' some of these need to return a value + +' should be removed when migration is complete +Set private_oReg = GetObject("winmgmts:\root\default:StdRegProv") + +Set private_oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") +private_oCtx.Add "__ProviderArchitecture", CInt(OSArchitecture) + +Set private_oLocator = CreateObject("Wbemscripting.SWbemLocator") +Set private_oServices = private_oLocator.ConnectServer(".", "root\default","","",,,,private_oCtx) +Set private_oRegSpecific = private_oServices.Get("StdRegProv") + +Function CheckAccess(hDefKey,sSubKeyName,uRequired, bGranted ) + Set Inparams = private_oRegSpecific.Methods_("CheckAccess").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.uRequired = uRequired + + set Outparams = private_oRegSpecific.ExecMethod_("CheckAccess", Inparams,,private_oCtx) + + bGranted = Outparams.bGranted + + + CheckAccess = 0 + +End Function + +Function CreateKey(hDefKey,sSubKeyName) + Set Inparams = private_oRegSpecific.Methods_("CreateKey").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + set Outparams = private_oRegSpecific.ExecMethod_("CreateKey", Inparams,,private_oCtx) + + + CreateKey = 0 + +End Function + +Function DeleteKey(hDefKey,sSubKeyName) + Set Inparams = private_oRegSpecific.Methods_("DeleteKey").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + set Outparams = private_oRegSpecific.ExecMethod_("DeleteKey", Inparams,,private_oCtx) + + + DeleteKey = 0 + +End Function + +Function DeleteValue(hDefKey,sSubKeyName,sValueName) + Set Inparams = private_oRegSpecific.Methods_("DeleteValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + set Outparams = private_oRegSpecific.ExecMethod_("DeleteValue", Inparams,,private_oCtx) + + + DeleteValue = 0 + +End Function + +Function EnumKey(hDefKey,sSubKeyName, sNames ) + Set Inparams = private_oRegSpecific.Methods_("EnumKey").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + set Outparams = private_oRegSpecific.ExecMethod_("EnumKey", Inparams,,private_oCtx) + + sNames = Outparams.sNames + + + EnumKey = 0 + +End Function + +Function EnumValues(hDefKey,sSubKeyName, sNames,Types ) + Set Inparams = private_oRegSpecific.Methods_("EnumValues").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + set Outparams = private_oRegSpecific.ExecMethod_("EnumValues", Inparams,,private_oCtx) + + sNames = Outparams.sNames + + Types = Outparams.Types + + + EnumValues = 0 + +End Function + +Function GetBinaryValue(hDefKey,sSubKeyName,sValueName, uValue ) + Set Inparams = private_oRegSpecific.Methods_("GetBinaryValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + set Outparams = private_oRegSpecific.ExecMethod_("GetBinaryValue", Inparams,,private_oCtx) + + uValue = Outparams.uValue + + + GetBinaryValue = 0 + +End Function + +Function GetDWORDValue(hDefKey,sSubKeyName,sValueName, uValue ) + Set Inparams = private_oRegSpecific.Methods_("GetDWORDValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + set Outparams = private_oRegSpecific.ExecMethod_("GetDWORDValue", Inparams,,private_oCtx) + + uValue = Outparams.uValue + + + GetDWORDValue = 0 + +End Function + +Function GetExpandedStringValue(hDefKey,sSubKeyName,sValueName, sValue ) + Set Inparams = private_oRegSpecific.Methods_("GetExpandedStringValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + set Outparams = private_oRegSpecific.ExecMethod_("GetExpandedStringValue", Inparams,,private_oCtx) + + sValue = Outparams.sValue + + + GetExpandedStringValue = 0 + +End Function + +Function GetMultiStringValue(hDefKey,sSubKeyName,sValueName, sValue ) + Set Inparams = private_oRegSpecific.Methods_("GetMultiStringValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + set Outparams = private_oRegSpecific.ExecMethod_("GetMultiStringValue", Inparams,,private_oCtx) + + sValue = Outparams.sValue + + + GetMultiStringValue = 0 + +End Function + +Function GetQWORDValue(hDefKey,sSubKeyName,sValueName, uValue ) + Set Inparams = private_oRegSpecific.Methods_("GetQWORDValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + set Outparams = private_oRegSpecific.ExecMethod_("GetQWORDValue", Inparams,,private_oCtx) + + uValue = Outparams.uValue + + + GetQWORDValue = 0 + +End Function + +Function GetSecurityDescriptor(hDefKey,sSubKeyName, Descriptor ) + Set Inparams = private_oRegSpecific.Methods_("GetSecurityDescriptor").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + set Outparams = private_oRegSpecific.ExecMethod_("GetSecurityDescriptor", Inparams,,private_oCtx) + + Descriptor = Outparams.Descriptor + + + GetSecurityDescriptor = 0 + +End Function + +Function GetStringValue(hDefKey,sSubKeyName,sValueName, sValue ) + Set Inparams = private_oRegSpecific.Methods_("GetStringValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + set Outparams = private_oRegSpecific.ExecMethod_("GetStringValue", Inparams,,private_oCtx) + + sValue = Outparams.sValue + + + GetStringValue = 0 + +End Function + +Function SetBinaryValue(hDefKey,sSubKeyName,sValueName,uValue) + Set Inparams = private_oRegSpecific.Methods_("SetBinaryValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + Inparams.uValue = uValue + + set Outparams = private_oRegSpecific.ExecMethod_("SetBinaryValue", Inparams,,private_oCtx) + + + SetBinaryValue = 0 + +End Function + +Function SetDWORDValue(hDefKey,sSubKeyName,sValueName,uValue) + Set Inparams = private_oRegSpecific.Methods_("SetDWORDValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + Inparams.uValue = uValue + + set Outparams = private_oRegSpecific.ExecMethod_("SetDWORDValue", Inparams,,private_oCtx) + + + SetDWORDValue = 0 + +End Function + +Function SetExpandedStringValue(hDefKey,sSubKeyName,sValueName,sValue) + Set Inparams = private_oRegSpecific.Methods_("SetExpandedStringValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + Inparams.sValue = sValue + + set Outparams = private_oRegSpecific.ExecMethod_("SetExpandedStringValue", Inparams,,private_oCtx) + + + SetExpandedStringValue = 0 + +End Function + +Function SetMultiStringValue(hDefKey,sSubKeyName,sValueName,sValue) + Set Inparams = private_oRegSpecific.Methods_("SetMultiStringValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + Inparams.sValue = sValue + + set Outparams = private_oRegSpecific.ExecMethod_("SetMultiStringValue", Inparams,,private_oCtx) + + + SetMultiStringValue = 0 + +End Function + +Function SetQWORDValue(hDefKey,sSubKeyName,sValueName,uValue) + Set Inparams = private_oRegSpecific.Methods_("SetQWORDValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + Inparams.uValue = uValue + + set Outparams = private_oRegSpecific.ExecMethod_("SetQWORDValue", Inparams,,private_oCtx) + + + SetQWORDValue = 0 + +End Function + +Function SetSecurityDescriptor(hDefKey,sSubKeyName,Descriptor) + Set Inparams = private_oRegSpecific.Methods_("SetSecurityDescriptor").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.Descriptor = Descriptor + + set Outparams = private_oRegSpecific.ExecMethod_("SetSecurityDescriptor", Inparams,,private_oCtx) + + + SetSecurityDescriptor = 0 + +End Function + +Function SetStringValue(hDefKey,sSubKeyName,sValueName,sValue) + Set Inparams = private_oRegSpecific.Methods_("SetStringValue").Inparameters + + Inparams.hDefKey = hDefKey + + Inparams.sSubKeyName = sSubKeyName + + Inparams.sValueName = sValueName + + Inparams.sValue = sValue + + set Outparams = private_oRegSpecific.ExecMethod_("SetStringValue", Inparams,,private_oCtx) + + + SetStringValue = 0 + +End Function diff --git a/src/vbs/JsonSafeTest.wsf b/src/vbs/JsonSafeTest.wsf new file mode 100644 index 0000000..fc97e5e --- /dev/null +++ b/src/vbs/JsonSafeTest.wsf @@ -0,0 +1,7 @@ + + + diff --git a/src/vbs/regCreateKey.wsf b/src/vbs/regCreateKey.wsf new file mode 100644 index 0000000..2c1298c --- /dev/null +++ b/src/vbs/regCreateKey.wsf @@ -0,0 +1,32 @@ + + + \ No newline at end of file diff --git a/src/vbs/regDeleteKey.wsf b/src/vbs/regDeleteKey.wsf new file mode 100644 index 0000000..5592cf7 --- /dev/null +++ b/src/vbs/regDeleteKey.wsf @@ -0,0 +1,29 @@ + + + \ No newline at end of file diff --git a/src/vbs/regDeleteValue.wsf b/src/vbs/regDeleteValue.wsf new file mode 100644 index 0000000..55db463 --- /dev/null +++ b/src/vbs/regDeleteValue.wsf @@ -0,0 +1,29 @@ + + + diff --git a/src/vbs/regList.wsf b/src/vbs/regList.wsf new file mode 100644 index 0000000..01a81dc --- /dev/null +++ b/src/vbs/regList.wsf @@ -0,0 +1,49 @@ +' +' Lists the sub keys and values of a given registry key +' +' cscript regList.wsg HKLM\Software +' +' Will Yield: +' +' { +' "hklm\software": { +' "keys": [ .. array of sub keys .. ], +' "values": { +' "moo": { +' "type": "REG_SZ", +' "value": "bar" +' } +' } +' } +' } + + + \ No newline at end of file diff --git a/src/vbs/regListStream.wsf b/src/vbs/regListStream.wsf new file mode 100644 index 0000000..fdbeeb3 --- /dev/null +++ b/src/vbs/regListStream.wsf @@ -0,0 +1,46 @@ +' +' Lists the sub keys and values of a given registry key, this script is slightly different +' than regList because it reads stdin for the keys to list +' +' echo HKLM\Software | cscript regListStream.wsf A +' +' Will Yield: +' +' { +' "hklm\software": { +' "keys": [ .. array of sub keys .. ], +' "values": { +' "moo": { +' "type": "REG_SZ", +' "value": "bar" +' } +' } +' } +' } + + + \ No newline at end of file diff --git a/src/vbs/regPutValue.wsf b/src/vbs/regPutValue.wsf new file mode 100644 index 0000000..55c9bc5 --- /dev/null +++ b/src/vbs/regPutValue.wsf @@ -0,0 +1,56 @@ + + + \ No newline at end of file diff --git a/src/vbs/regUtil.vbs b/src/vbs/regUtil.vbs new file mode 100644 index 0000000..0dfdf89 --- /dev/null +++ b/src/vbs/regUtil.vbs @@ -0,0 +1,358 @@ +' TODO: consider incorporating a json writer of some sort instead of adhoc solution like the following +' e.g: http://demon.tw/my-work/vbs-json.html + +const HKEY_CLASSES_ROOT = &H80000000 +const HKEY_CURRENT_USER = &H80000001 +const HKEY_LOCAL_MACHINE = &H80000002 +const HKEY_USERS = &H80000003 +const HKEY_CURRENT_CONFIG = &H80000005 + +Sub LoadRegistryImplementationByOSArchitecture() + If IsNull(OSArchitecture) Then + WriteLineErr "missing OSArchitecture global. did not call util.DetermineOSArchitecture? or Forgot to load util.vbs?" + WScript.Quit 25125 + End If + + If OSArchitecture = "A" Then + Include "ArchitectureAgnosticRegistry.vbs" + Else + Include "ArchitectureSpecificRegistry.vbs" + End If +End Sub + +Function PutValue(constHive, strSubKey, strValueName, strValue, strType) + Select Case UCase(strType) + + Case "REG_SZ" + PutValue = SetStringValue(constHive, strSubKey, strValueName, strValue) + + Case "REG_EXPAND_SZ" + PutValue = SetExpandedStringValue(constHive, strSubKey, strValueName, strValue) + + Case "REG_BINARY" + PutValue = SetBinaryValue(constHive, strSubKey, strValueName, ToBinaryValue(strValue)) + + Case "REG_NONE" + PutValue = SetBinaryValue(constHive, strSubKey, strValueName, ToBinaryValue(strValue)) + + ' TODO: need to check that indeed int is the right type here + Case "REG_DWORD" + PutValue = SetDWORDValue(constHive, strSubKey, strValueName, CDbl(strValue)) + + Case "REG_MULTI_SZ" + PutValue = SetMultiStringValue(constHive, strSubKey, strValueName, Split(strValue, ",")) + + Case "REG_QWORD" + PutValue = SetQWORDValue(constHive, strSubKey, strValueName, strValue) + + Case "REG_DEFAULT" + PutValue = SetStringValue(constHive, strSubKey, "", strValue) + + Case Else + PutValue = SetStringValue(constHive, strSubKey, strValueName, strValue) + + End Select +End Function + +' render the child of a sub path strSubKey in hive constHive +' as json. +Sub ListChildrenAsJson(constHive, strSubKey) + ' start outputting json to stdout + Write "{" + + Dim e1: e1 = EnumKey (constHive, strSubKey, arrKeyNames) + If e1 <> 0 Then + Write """exists"": false," + Dim arrValueNames: arrValueNames = null + Else + Write """exists"": true," + + Dim e2: e2 = EnumValues (constHive, strSubKey, arrValueNames, arrValueTypes) + If e2 <> 0 Then + WScript.Quit e2 + End If + End If + + Write """keys"": [" + If Not IsNull(arrKeyNames) Then + For x = 0 To UBound(arrKeyNames) + If (x > 0) Then + Write "," + End If + + Write """" & JsonSafe(arrKeyNames(x)) & """" + Next + End If + Write "]," + ' TODO: some duplicity of code between the two paths of this condition, this needs to be address at some point + Write """values"":{" + If Not IsNull(arrValueNames) Then + For y = 0 To UBound(arrValueNames) + If y > 0 Then + Write "," + End If + + strValueName = arrValueNames(y) + intValueType = arrValueTypes(y) + + ' assign the value to varValue + GetValueByType constHive, strSubKey, strValueName, intValueType, varValue + + WriteValue strValueName, intValueType, varValue + Next + Else + ' fix for keys with only default values in them + ' see http://stackoverflow.com/questions/8840343/how-to-read-the-default-value-from-registry-in-vbscript + GetStringValue constHive, strSubKey, "", strDefaultValue + + If IsNull(strDefaultValue) = false and strDefaultValue <> "" Then + ' write the default value with REG_SZ + WriteValue "", 1, strDefaultValue + End If + End If + Write "}}" +End Sub + +Sub WriteValue (strValueName, intValueType, varValue) + Write """" + Write JsonSafe(strValueName) + Write """:{" + Write """type"": """ + Write RenderType(intValueType) + Write """," + Write """value"":" + Write RenderValueByType(intValueType, varValue) + Write "}" +End Sub + +' give a raw HKLM\something\somewhere +' output the hive constant and the subkey, in this case: +' HKEY_LOCAL_MACHINE will be assigned to outConstHive +' and something\somewhere will be assigned to outStrSubKey +Sub ParseHiveAndSubKey(strRawKey, outConstHive, outStrSubKey) + ' split into two parts to deduce the hive and the sub key + arrSplitted = Split(strRawKey, "\", 2, 1) + + If UBound(arrSplitted) > 0 Then + strHive = arrSplitted(0) + outStrSubKey = arrSplitted(1) + Else + strHive = strRawKey + outStrSubKey = "" + End If + + outConstHive = StringToHiveConst(UCase(strHive)) +End Sub + +Function ArrayRemoveAt(arr, pos) + Dim i + If IsArray(arr) Then + If pos >= 0 And pos <= UBound(arr) Then + For i = pos To UBound(arr) - 1 + arr(i) = arr(i + 1) + Next + ReDim Preserve arr(UBound(arr) - 1) + End If + End If +End Function + +Sub ParseHiveAndSubKeyAndValue(strRawKey, outConstHive, outStrSubKey, outStrValue) + ' split into two parts to deduce the hive and the sub key + arrSplitted = Split(strRawKey, "\", -1, 1) + + If UBound(arrSplitted) > 0 Then + strHive = arrSplitted(0) + outStrValue = arrSplitted(UBound(arrSplitted)) + test = ArrayRemoveAt(arrSplitted, UBound(arrSplitted)) + test = ArrayRemoveAt(arrSplitted, 0) + outStrSubKey = Join(arrSplitted, "\") + Else + strHive = strRawKey + outStrSubKey = "" + End If + + outConstHive = StringToHiveConst(UCase(strHive)) +End Sub + +Function StringToHiveConst(strHive) + + Select Case strHive + Case "HKCR" + StringToHiveConst = HKEY_CLASSES_ROOT + Case "HKCU" + StringToHiveConst = HKEY_CURRENT_USER + Case "HKLM" + StringToHiveConst = HKEY_LOCAL_MACHINE + Case "HKU" + StringToHiveConst = HKEY_USERS + Case "HKCC" + StringToHiveConst = HKEY_CURRENT_CONFIG + Case Else + StringToHiveConst = Null + End Select + +End Function + +' TODO: this entire "by type" should be transformed into OOP style +' where each type will have a class with render(), getValue() etc... + +' convert a value type number into a string label +Function RenderType(intType) + RenderType = "REG_UNKNOWN" + + Select Case intType + Case 0 + RenderType = "REG_NONE" + Case 1 + RenderType = "REG_SZ" + Case 2 + RenderType = "REG_EXPAND_SZ" + Case 3 + RenderType = "REG_BINARY" + Case 4 + RenderType = "REG_DWORD" + Case 7 + RenderType = "REG_MULTI_SZ" + Case 11 + RenderType = "REG_QWORD" + Case Else + ' TODO: should report / throw an error here + WriteErr("invalid Registry Value Type " & intType) + + End Select + +End Function + +' render by value type: +' string will return as a string with double quotes, e.g "value" +' multi string values which return as an array ot strings "["1", "2"]" (double quotes included ofc) +' numeric values like DWORD and QWORD just return as the number e.g. 1 +' byte arrays such as reg_binary return as an array of ints, e.g [1,2,3] +Function RenderValueByType(intType, varValue) + + Select Case intType + ' REG_NONE + Case 0 + RenderValueByType = "0" + + ' REG_SZ + Case 1 + RenderValueByType = """" & JsonSafe(varValue) & """" + + ' REG_EXPAND_SZ + Case 2 + RenderValueByType = """" & JsonSafe(varValue) & """" + + ' REG_BINARY + Case 3 + RenderValueByType = RenderByteArray(varValue) + + ' REG_DWORD + Case 4 + RenderValueByType= varValue + + ' REG_MULYI_SZ' + Case 7 + + RenderValueByType = RenderStringArray(varValue) + ' REG_QWORD + Case 11 + RenderValueByType = varValue + Case Else + ' TODO: should report / throw an error here + WriteErr("invalid Registry Value Type " & intType) + End Select + +End Function + +' get the value of a registry based on its value type and assign it to out parameter outVarValue +Sub GetValueByType(constHive, strKey, strValueName, intType, outVarValue) + + Select Case intType + ' REG_NONE + Case 0 + GetStringValue constHive, strKey, strValueName, "0" + Exit Sub + + ' REG_SZ + Case 1 + GetStringValue constHive, strKey, strValueName, outVarValue + Exit Sub + + ' REG_EXPAND_SZ + Case 2 + GetExpandedStringValue constHive, strKey, strValueName, outVarValue + Exit Sub + + ' REG_BINARY + Case 3 + GetBinaryValue constHive, strKey, strValueName, outVarValue + Exit Sub + + ' REG_DWORD + Case 4 + GetDWORDValue constHive, strKey, strValueName, outVarValue + + ' #21 - VBS does not support UInt32. This is the workaround + If outVarValue < 0 Then outVarValue = 4294967296 + outVarValue + + Exit Sub + + ' REG_MULYI_SZ' + Case 7 + GetMultiStringValue constHive, strKey, strValueName, outVarValue + Exit Sub + + ' REG_QWORD + Case 11 + GetQWORDValue constHive, strKey, strValueName, outVarValue + Exit Sub + + Case Else + ' TODO: should report / throw an error here + WriteErr("invalid Registry Value Type " & intType) + End Select + +End Sub + +' render a byte array as a json array of numbers +Function RenderByteArray(arr) + RenderByteArray = "[]" + + If Not IsNull(arr) Then + RenderByteArray = "[" & Join(arr, ",") & "]" + End If +End Function + +' render a string array as json string array +Function RenderStringArray(arr) + Result = "[" + If Not IsNull(arr) Then + For t = 0 To UBound(arr) + If (t > 0) Then + Result = Result & "," + End If + + Result = Result & """" & JsonSafe(arr(t)) & """" + Next + End If + Result = Result & "]" + + RenderStringArray = Result +End Function + +Function ToBinaryValue(strValue) + + arrValue = Split(strValue, ",") + + If IsNull(arrValue) Then + ToBinaryValue = Array() + Exit Function + End If + + For i = 0 To UBound(arrValue) + arrValue(i) = CInt(arrValue(i)) + Next + + ToBinaryValue = arrValue +End Function \ No newline at end of file diff --git a/src/vbs/util.vbs b/src/vbs/util.vbs new file mode 100644 index 0000000..15fcafb --- /dev/null +++ b/src/vbs/util.vbs @@ -0,0 +1,177 @@ +Set stdout = WScript.StdOut +Set stderr = WScript.StdErr +Set stdin = WScript.StdIn +Set args = WScript.Arguments +Set fs = CreateObject("scripting.filesystemobject") +Dim OSArchitecture + +Sub WriteErr(message) + stderr.Write message +End Sub + +Sub WriteLineErr(message) + stderr.WriteLine message +End Sub + +Sub Write(message) + stdout.Write message +End Sub + +Sub WriteLine(message) + stdout.WriteLine message +End Sub + +Function IndexOf(varNeedle, arrHaystack) + IndexOf = -1 + + If Not IsArray(arrHaystack) Then + Exit Function + End If + + For xyz = 0 To UBound(arrHaystack) + If arrHaystack(xyz) = varNeedle Then + IndexOf = xyz + Exit Function + End If + Next +End Function + +Sub CheckZeroArgs(message) + ' bail if args are missing + If args.Count = 0 Then + WriteLineErr message + WScript.Quit 25121 + End If +End Sub + +Dim ALLOWED_OS_ARCHITECTURE_VALUES: ALLOWED_OS_ARCHITECTURE_VALUES = Array("S", "A", "32", "64") + +' +' determine the architecture of the operating system, that will be used. there are 4 possibilities: +' A - means agnostic +' S - means that we want to use a specific architecture, but auto detect Item +' 32 - explicitly use 32 bit architecture +' 64 - explicitly use 64 bit architecture +' +Sub DetermineOSArchitecture() + strArchitecture = args(0) + + If IsNull(strArchitecture) Then + WriteLineErr "missing architecture argument" + WScript.Quit 25124 + End If + + strArchitecture = UCase(strArchitecture) + + If IndexOf(strArchitecture, ALLOWED_OS_ARCHITECTURE_VALUES) = -1 Then + WriteLineErr "invalid architecture argument" + WScript.Quit 25124 + End If + + If (strArchitecture = "S") Then + OSArchitecture = GetOSArchitecture() + If OSArchitecture = -1 Then + WriteLineErr "invalid os architecture detected " & OSArchitecture + WScript.Quit 25126 + End If + Else + OSArchitecture = strArchitecture + End If + +End Sub + +Sub Include(sPath) + ' TODO this is fragile, but should work for "modules" nested relatively to script root + include_ScriptPath = Left(WScript.ScriptFullName, InStr(WScript.ScriptFullName, WScript.ScriptName) - 2) + sPath = include_ScriptPath & "\" & sPath + + include_code = fs.OpenTextFile(sPath).ReadAll + ExecuteGlobal include_code +End Sub + +Function GetOSArchitecture() + + Dim ObjWMI, ColSettings, ObjProcessor + Dim StrComputer, ObjNetwork + + Set ObjWMI = GetObject("winmgmts:\Root\CIMV2") + Set ColSettings = ObjWMI.ExecQuery ("SELECT DataWidth, AddressWidth, Architecture FROM Win32_Processor") + + ' I make two assumptions here: + ' 1. Eveyone will have CPU0 device + ' 2. There is only one cpu defined in the wmi database (and if not, then they are all of the same architecture) + ' + ' from: https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor + ' Architecture values: + ' x86 (0) + ' MIPS (1) + ' Alpha (2) + ' PowerPC (3) + ' ARM (5) + ' ia64 (6) + ' x64 (9) + ' ARM64 (12) + + Set ObjProcessor = ColSettings.Item("Win32_Processor.DeviceID=""CPU0""") + + If ObjProcessor.Architecture = 0 AND ObjProcessor.AddressWidth = 32 Then + GetOSArchitecture = 32 + ElseIf (ObjProcessor.Architecture = 6 OR ObjProcessor.Architecture = 9) AND ObjProcessor.DataWidth = 64 AND ObjProcessor.AddressWidth = 32 Then + GetOSArchitecture = 32 + ElseIf (ObjProcessor.Architecture = 6 OR ObjProcessor.Architecture = 9) AND ObjProcessor.DataWidth = 64 AND ObjProcessor.AddressWidth = 64 Then + GetOSArchitecture = 64 + ' special case (could be included in the statements above) for Windows VM on Apple Silicon, tested only on parallels + ElseIf ObjProcessor.Architecture = 12 AND ObjProcessor.DataWidth = 64 AND ObjProcessor.AddressWidth = 64 Then + GetOSArchitecture = 64 + Else + GetOSArchitecture = -1 + End If + +End Function + +Function JsonSafe(inStrText) + If inStrText = "" Then + JsonSafe = "" + Exit Function + End If + Dim outStrText: outStrText = inStrText + outStrText = Replace(outStrText, "\", "\\") + outStrText = Replace(outStrText, vbcrlf, "\\r\\n") + outStrText = Replace(outStrText, vblf, "\\n") + outStrText = Replace(outStrText, vbcr, "\\r") + outStrText = Replace(outStrText, """", "\""") + outStrText = JsonU(outStrText) + JsonSafe = outStrText +End Function + +'TODO: need to change this function's name to something more appropriate +Function JsonU(astr) + + If isNull(astr) Then + JsonU = "" + Exit Function + End If + + Dim c + Dim utftext: utftext = "" + + For n = 1 To Len(astr) + c = CLng(AscW(Mid(astr, n, 1))) + + If c < 0 Then + c = &H10000 + c + End If + + If c < &H80 Then + utftext = utftext & Mid(astr, n, 1) + ElseIf c < &H100 Then + utftext = utftext & "\u00" & Hex(c) + ElseIf c < &H1000 Then + utftext = utftext & "\u0" & Hex(c) + Else + utftext = utftext & "\u" & Hex(c) + End If + Next + + JsonU = utftext +End Function diff --git a/src/vbs/wsRegReadList.wsf b/src/vbs/wsRegReadList.wsf new file mode 100644 index 0000000..703b547 --- /dev/null +++ b/src/vbs/wsRegReadList.wsf @@ -0,0 +1,52 @@ +' +' Lists the values of a given registry path, this script takes its input from stdin +' +' cscript regListStream.wsf A "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData" +' +' Will Yield: +' +' { +' "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData": "value here" +' } + + + \ No newline at end of file diff --git a/src/vbs/wsRegReadListStream.wsf b/src/vbs/wsRegReadListStream.wsf new file mode 100644 index 0000000..15f361f --- /dev/null +++ b/src/vbs/wsRegReadListStream.wsf @@ -0,0 +1,47 @@ +' +' Lists the values of a given registry path, this script takes its input from stdin +' +' echo HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData | cscript regListStream.wsf A +' +' Will Yield: +' +' { +' "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\\AppData": "value here" +' } + + + \ No newline at end of file diff --git a/src/views/setting.html b/src/views/setting.html index 4aefab8..5dd665b 100644 --- a/src/views/setting.html +++ b/src/views/setting.html @@ -95,28 +95,21 @@ const ws = require('windows-shortcuts'); const os=require('os'); const process = require('child_process'); - const iconv = require('iconv-lite'); - const encoding = 'cp936'; - const binaryEncoding = 'binary'; - const keyPath = 'HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders';//选择要修改或者保存或者删除的路径(操作路径) let desktop; let ele = require('electron'); let ipcRenderer = ele.ipcRenderer; - window.$ = window.jquery = require('jquery'); - let update_info = {}; - process.exec(`REG QUERY "${keyPath}" /v Desktop`, {encoding: binaryEncoding}, function (error, stdout, stderr) { - if (error != null) { - console.log('获取注册表桌面路径失败,异常如下:' + error); - } else { - let value = iconv.decode(new Buffer(stdout, binaryEncoding), encoding); - value = value.substring(value.indexOf(":") - 1); - desktop = value.replace(/^\s*|\s*$/g, ""); //获取注册表实际值并去除首尾空格 - } - }); + + const regedit = require('regedit') + const regKey = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders'; + regedit.setExternalVBSLocation('src/vbs') + regedit.list([regKey], function(err, result) { + desktop = result[regKey].values.Desktop.value; + }) if (!desktop) { desktop = dpth.join(os.homedir(), 'Desktop'); } - + window.$ = window.jquery = require('jquery'); + let update_info = {}; log.info("-->进入配置页面..."); //进行程序检查更新 ipcRenderer.send("checkForUpdate");