Many thanks Justin !
I had tried with "As variant BYREF" too but didn't use "safeArray = varNamesArr\parray". I guess it was the problem.
Do you have an idea why it is not working when compiled in 64 bits ?
EDIT :
Ok, I'm able to list installed softwares but the automatic redirection 32/64bits always redirects my request to WOW6432Node because it's (for now) a 32bits compiled program.
I read this article
https://docs.microsoft.com/en-us/window ... t-platform but I don't know how to apply to my code...
Code: Select all
XIncludeFile "COMatePlus\COMatePLUS.pbi"
Define.s Hostname, login, password, strKeyPath, strKeyPath32, strValueName
Define.COMateObject objLocator, objService, objReg, objCtx
hkey = #HKEY_LOCAL_MACHINE
strKeyPath = "Software\Microsoft\Windows\CurrentVersion\Uninstall\"
strKeyPath32 = "Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
strValueName = "DisplayName"
Define.COMateObject objReg
Define.i safeArray
Define.VARIANT varNamesArr, varName
Define.s subkeyname
objReg = COMate_GetObject("winmgmts:\\.\root\default:StdRegProv", "")
If objReg
; first list from "Software\Microsoft\Windows\CurrentVersion\Uninstall\"
If objReg\Invoke("EnumKey(" + Str(hkey) + ", '" + strKeyPath + "', " + Str(@varNamesArr) + " AS variant BYREF)") = #S_OK
safeArray = varNamesArr\parray
SafeArrayGetLBound_(safeArray, 1, @lBound)
SafeArrayGetUBound_(safeArray, 1, @uBound)
For i = lBound To uBound
ret = SafeArrayGetElement_(safeArray, @i, @varName)
If ret = #S_OK
If varName\bstrVal
subkeyname = PeekS(varName\bstrVal, -1, #PB_Unicode)
SysFreeString_(varName\bstrVal)
varName\bstrVal = 0
If objReg\Invoke("GetStringValue(" + Str(hkey) + ", '" + strKeyPath + subkeyname + "', '" + strValueName + "', " + Str(@dwValue) + " BYREF)") = #S_OK
If dwValue <> 1 ; NOT SURE ABOUT THAT TEST (if the key is not present, the pointer should be null but it seems its value is 1
sValue$ = PeekS(dwValue, -1, #PB_Unicode)
SysFreeString_(dwValue)
Debug "registry value = " + sValue$
Else
; Debug "no key"
EndIf
dwValue = 0
Else
Debug "GetStringValue error : " + COMate_GetLastErrorDescription()
EndIf
EndIf
Else
If ret = #DISP_E_BADINDEX : Debug "erreur #DISP_E_BADINDEX" : EndIf
If ret = #E_INVALIDARG : Debug "erreur #E_INVALIDARG" : EndIf
If ret = #E_OUTOFMEMORY : Debug "erreur #E_OUTOFMEMORY" : EndIf
EndIf
Next
SafeArrayDestroy_(safeArray)
Else
Debug "invoke EnumKey error"
Debug COMate_GetLastErrorDescription()
EndIf
Debug "-----------------------------------------------------------------------------"
; second list from "Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
If objReg\Invoke("EnumKey(" + Str(hkey) + ", '" + strKeyPath32 + "', " + Str(@varNamesArr) + " AS variant BYREF)") = #S_OK
safeArray = varNamesArr\parray
SafeArrayGetLBound_(safeArray, 1, @lBound)
SafeArrayGetUBound_(safeArray, 1, @uBound)
For i = lBound To uBound
ret = SafeArrayGetElement_(safeArray, @i, @varName)
If ret = #S_OK
If varName\bstrVal
subkeyname = PeekS(varName\bstrVal, -1, #PB_Unicode)
SysFreeString_(varName\bstrVal)
varName\bstrVal = 0
If objReg\Invoke("GetStringValue(" + Str(hkey) + ", '" + strKeyPath32 + subkeyname + "', '" + strValueName + "', " + Str(@dwValue) + " BYREF)") = #S_OK
If dwValue <> 1 ; NOT SURE ABOUT THAT TEST (if the key is not present, the pointer should be null but it seems its value is 1
sValue$ = PeekS(dwValue, -1, #PB_Unicode)
SysFreeString_(dwValue)
Debug "registry value = " + sValue$
Else
; Debug "no key"
EndIf
dwValue = 0
Else
Debug "GetStringValue error : " + COMate_GetLastErrorDescription()
EndIf
EndIf
Else
If ret = #DISP_E_BADINDEX : Debug "erreur #DISP_E_BADINDEX" : EndIf
If ret = #E_INVALIDARG : Debug "erreur #E_INVALIDARG" : EndIf
If ret = #E_OUTOFMEMORY : Debug "erreur #E_OUTOFMEMORY" : EndIf
EndIf
Next
SafeArrayDestroy_(safeArray)
Else
Debug "invoke EnumKey error"
Debug COMate_GetLastErrorDescription()
EndIf
objReg\Release()
Else
Debug "objet error"
EndIf