COMatePLus and request on remote host

Just starting out? Need help? Post your questions and find answers here.
tatanas
Enthusiast
Enthusiast
Posts: 204
Joined: Wed Nov 06, 2019 10:28 am
Location: France

COMatePLus and request on remote host

Post by tatanas »

Hi,

I would like to get the installed program list from HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall registry key on remote computers.
I'm trying with COMatePlus and the StdRegProv class with its EnumKey method but I can' connect to the remote computer.

Code: Select all

XIncludeFile "COMatePLUS.pbi"

hostname.s = "host"
login.s = "administrator"
password.s = "adminpass"
HKEY_LOCAL_MACHINE = $80000002
strKeyPath.s = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
objLocator.COMateObject
objService.COMateObject


objLocator = COMate_CreateObject("WbemScripting.SWbemLocator")
If objLocator
	Debug "objLocator ok"
	objLocator\ConnectServer(hostname, "root\CIMV2", login, password)
; 	objLocator\Invoke("ConnectServer(" + "'" + hostname + "', '" + "root\CIMV2" + "', '" + login + "', '" + password + "')")

	objService = COMate_GetObject("winmgmts:\\.\root\default:StdRegProv", "")
	If objService
		Debug "objService ok"

		objService\Invoke("EnumKey(" + Str(HKEY_LOCAL_MACHINE) + ", '" + strKeyPath + "', '" + Str(@dwValue))	
		Debug PeekS(dwValue, -1, #PB_Unicode)	
		SysFreeString_(dwValue)		

		objService\Release()
	EndIf
	objLocator\Release()
EndIf
The error : "Interface method not found: ConnectServer."
However "ConnectServer" is a method of SWbemLocator object. Should I proceed in a different way ?
Windows 10 Pro x64
PureBasic 6.04 x64
infratec
Always Here
Always Here
Posts: 6866
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: COMatePLus and request on remote host

Post by infratec »

Use

Code: Select all

objLocator\Invoke("ConnectServer(" + "'" + hostname + "', '" + "root\CIMV2" + "', '" + login + "', '" + password + "')")
Debug COMate_GetLastErrorDescription()
To see what's the reason.
infratec
Always Here
Always Here
Posts: 6866
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: COMatePLus and request on remote host

Post by infratec »

Code: Select all

EnableExplicit

XIncludeFile "COMatePLUS.pbi"

Define.l dwValue
Define.i HKEY_LOCAL_MACHINE
Define Hostname$, login$, password$, strKeyPath$
Define.COMateObject objLocator, objService

Hostname$ = "192.168.0.1"
login$ = "Administrator"
password$ = "XXXXXX"
HKEY_LOCAL_MACHINE = $80000002
strKeyPath$ = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"


objLocator = COMate_CreateObject("WbemScripting.SWbemLocator")
If objLocator
  Debug "objLocator ok"
  
  If objLocator\Invoke("ConnectServer(" + "'" + Hostname$ + "', '" + "root\CIMV2" + "', '" + login$ + "', '" + password$ + "')") = #S_OK
    Debug COMate_GetLastErrorDescription()
    
    objService = COMate_GetObject("winmgmts:\\.\root\default:StdRegProv", "")
    If objService
      Debug "objService ok"
      
      objService\Invoke("EnumKey(" + Str(HKEY_LOCAL_MACHINE) + ", '" + strKeyPath$ + "', '" + Str(@dwValue))
      If COMate_GetLastErrorCode() = 0
        Debug PeekS(dwValue, -1, #PB_Unicode)   
        SysFreeString_(dwValue)
      Else
        Debug COMate_GetLastErrorDescription()
      EndIf
      
      objService\Release()
    EndIf
  Else
    Debug COMate_GetLastErrorDescription()
  EndIf
  objLocator\Release()
EndIf
Last edited by infratec on Wed Sep 08, 2021 7:46 am, edited 1 time in total.
tatanas
Enthusiast
Enthusiast
Posts: 204
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: COMatePLus and request on remote host

Post by tatanas »

Ok, so I should use Invoke method.

Using your code, I replaced the EnumKey method by GetStringValue :

Code: Select all

EnableExplicit

XIncludeFile "COMatePLUS.pbi"

Define.l dwValue
Define.i HKEY_LOCAL_MACHINE
Define Hostname$, login$, password$, strKeyPath$
Define.COMateObject objLocator, objService

Hostname$ = "x.x.x.x"
login$ = "Administrator"
password$ = "adminpass"
HKEY_LOCAL_MACHINE = $80000002
strKeyPath$ = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"


objLocator = COMate_CreateObject("WbemScripting.SWbemLocator")
If objLocator
	Debug "objLocator ok"
	
	If objLocator\Invoke("ConnectServer(" + "'" + Hostname$ + "', '" + "root\CIMV2" + "', '" + login$ + "', '" + password$ + "')") = #S_OK
		Debug COMate_GetLastErrorDescription()
		
		objService = COMate_GetObject("winmgmts:\\.\root\default:StdRegProv", "")
		If objService
			Debug "objService ok"
			
			objService\Invoke("GetStringValue(" + Str(HKEY_LOCAL_MACHINE) + ", '" + strKeyPath$ + "\VLC media player" + "', '" + "InstallLocation"  + "', " + Str(@dwValue) + " BYREF)")
			If COMate_GetLastErrorCode() = 0
				Debug PeekS(dwValue, -1, #PB_Unicode)   
				SysFreeString_(dwValue)
			Else
				Debug COMate_GetLastErrorDescription()
			EndIf
			
			objService\Release()
		EndIf
	Else
		Debug COMate_GetLastErrorDescription()
	EndIf
	objLocator\Release()
EndIf
Error message : "Type mismatch occurred" from objService\Invoke("GetStringValue...

EDIT : I found this post viewtopic.php?p=312528#p312528 from SFSxOI. His code seemed to work in 2010 but I have the same error now.

EDIT2 : I just realize that I should replace the '.' after "winmgmts:\\" with the hostname/@ip, but if I do that i've got an denied access error...
Windows 10 Pro x64
PureBasic 6.04 x64
tatanas
Enthusiast
Enthusiast
Posts: 204
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: COMatePLus and request on remote host

Post by tatanas »

I modified the ConnectServer part because I have to connect to "root\default:StdRegProv" not "root\CIMv2".
The second problem is the return of ConnectServer. It should be a SWbemServices object, how can I get it through "Invoke" ?

Code: Select all

XIncludeFile "COMatePLUS.pbi"

Define.l dwValue
Define.l HKEY_LOCAL_MACHINE
Define Hostname$, login$, password$, strKeyPath$
Define.COMateObject objLocator, objService

Hostname$ = "x.x.x.x"
login$ = "Administrator"
password$ = "adminpass"
HKEY_LOCAL_MACHINE = $80000002
strKeyPath$ = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"


objLocator = COMate_CreateObject("WbemScripting.SWbemLocator")

If objLocator
	Debug "objLocator ok"
	
	If objLocator\Invoke("ConnectServer(" + "'" + Hostname$ + "', '" + "root\default:StdRegProv" + "', '" + login$ + "', '" + password$ + "')") = #S_OK
		Debug COMate_GetLastErrorDescription()

; 		If objService
; 			Debug "objService ok"
	
			objService\Invoke("GetStringValue(" + Str(#HKEY_LOCAL_MACHINE) + ", '" + strKeyPath$ + "\VLC media player" + "', '" + "InstallLocation"  + "', " + Str(@dwValue) + " BYREF)")
			If COMate_GetLastErrorCode() = 0
				Debug PeekS(dwValue, -1, #PB_Unicode)   
				SysFreeString_(dwValue)
			Else
				Debug COMate_GetLastErrorDescription()
			EndIf
			
			objService\Release()
; 		Else
; 			Debug COMate_GetLastErrorDescription()
; 		EndIf
	Else
		Debug COMate_GetLastErrorDescription()
	EndIf
	objLocator\Release()
EndIf
Windows 10 Pro x64
PureBasic 6.04 x64
tatanas
Enthusiast
Enthusiast
Posts: 204
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: COMatePLus and request on remote host

Post by tatanas »

Finally get it to work in 32bits... (got an error in 64bits) :

Code: Select all

XIncludeFile "COMatePLUS.pbi"

Define.s Hostname, login, password, strKeyPath, strValueName
Define.COMateObject objLocator, objService, objReg

Hostname = "PCNAME"
login = "Administrator"
password = "password"
hkey = #HKEY_LOCAL_MACHINE
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\VLC media player"
strValueName = "InstallLocation"

objLocator = COMate_CreateObject("WbemScripting.SWbemLocator")

If objLocator
	Debug "objLocator ok"
	objService = objLocator\GetObjectProperty("ConnectServer(" + "'" + Hostname + "', '" + "root\default" + "', '" + login + "', '" + password + "')")
	If objService

		objReg = objService\GetObjectProperty("Get('StdRegProv')")
		If objReg

			If objReg\Invoke("GetStringValue(" + Str(hkey) + ", '" + strKeyPath + "', '" + strValueName  + "', " + Str(@dwValue) + " BYREF)") = #S_OK
				Debug PeekS(dwValue, -1, #PB_Unicode)   
				SysFreeString_(dwValue)
			Else
				Debug "invoke error : " + COMate_GetLastErrorDescription()
			EndIf
			objReg\Release()
		Else
			Debug "objReg erreur"
		EndIf
		objService\Release()
	Else
		Debug "objService erreur"
	EndIf
	objLocator\Release()
EndIf
Windows 10 Pro x64
PureBasic 6.04 x64
infratec
Always Here
Always Here
Posts: 6866
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: COMatePLus and request on remote host

Post by infratec »

Your code still returns 0 for dwValue
And VLC is installed on the target PC.
tatanas
Enthusiast
Enthusiast
Posts: 204
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: COMatePLus and request on remote host

Post by tatanas »

You get 0 even if vlc is installed ? It may be a problem with "SOFTWARE\WOW6432Node" path.
Try with another key like this one "SYSTEM\CurrentControlSet\services\NetBT\Parameters" and this value "NbProvider".
For me, it returns "_tcp" if compiled in 32bits.
Windows 10 Pro x64
PureBasic 6.04 x64
infratec
Always Here
Always Here
Posts: 6866
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: COMatePLus and request on remote host

Post by infratec »

You are right, this works.
So I will double check the path.
tatanas
Enthusiast
Enthusiast
Posts: 204
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: COMatePLus and request on remote host

Post by tatanas »

New difficulty :
It's great to be able to read a key but I would like to enumerate the subkeys.
There is a method named Enumkey (https://docs.microsoft.com/en-us/previo ... stdregprov) but the last parameter is an array of strings passed by reference. I don't know how to declare and what kind of variable I have to pass to this method.
Any idea ?

Code: Select all

objReg\Invoke("EnumKey(" + Str(hkey) + ", '" + strKeyPath + "', " + Str(@myarr(0)) + " BYREF)")
EDIT : I found a snippet in VB where variables are declared as variant type. I know it is possible in Purebasic but I don't know how to use it.

Code: Select all

Option Explicit

Private Sub Form_Load()
    Dim Registry As Object, varKey As Variant, varKeys As Variant
    Set Registry = GetObject("winmgmts:\\.\root\default:StdRegProv")
    Registry.EnumKey &H80000001, "software\microsoft\windows\currentversion\unreadmail", varKeys
    For Each varKey In varKeys
        Debug.Print varKey
    Next
End Sub
Windows 10 Pro x64
PureBasic 6.04 x64
tatanas
Enthusiast
Enthusiast
Posts: 204
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: COMatePLus and request on remote host

Post by tatanas »

Another unsuccessful attempt (E_INVALIDARG error) :

Code: Select all

XIncludeFile "COMatePLUS.pbi"

Define.COMateObject oReg

hkey.i = #HKEY_LOCAL_MACHINE
strKeyPath.s = "SYSTEM\CurrentControlSet\Services"


oReg = COMate_GetObject("winmgmts:\\.\root\default:StdRegProv", "")
If oReg

		If oReg\Invoke("EnumKey(" + Str(hkey) + ", '" + strKeyPath + "', " + Str(@safeArray) + " BYREF)") = #S_OK

			; Retrieve the strings from the safearray
			SafeArrayGetLBound_(safeArray, 1, @lBound)
			SafeArrayGetUBound_(safeArray, 1, @uBound)
			For i = lBound To uBound
				ret = SafeArrayGetElement_(safeArray, @i, @temp)
				If ret = #S_OK
					Debug temp
					If temp
						Debug PeekS(temp, -1, #PB_Unicode)
					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
			
			;Destroy the array.
			SafeArrayDestroy_(safeArray)

		Else
			Debug "invoke EnumKey error"
			Debug COMate_GetLastErrorDescription()
		EndIf


;    If oReg\Invoke("GetStringValue(" + Str(hkey) + ", '" + strKeyPath + "', '" + strValueName + "', " + Str(@dwValue) + " BYREF)") = #S_OK
;       sValue$ = PeekS(dwValue, -1, #PB_Unicode)
;       SysFreeString_(dwValue)
;       Debug "registry value = " + sValue$
;    Else
;       Debug "GetStringValue error : " + COMate_GetLastErrorDescription()
;    EndIf

   oReg\Release()
Else
   Debug "objet error"
EndIf

uBound variable seems to get the exact number of sub keys but I can't get the text associated.
Windows 10 Pro x64
PureBasic 6.04 x64
Justin
Addict
Addict
Posts: 830
Joined: Sat Apr 26, 2003 2:49 pm

Re: COMatePLus and request on remote host

Post by Justin »

You have to pass the array as variant by reference, the array elements are variants too, this worked:

Code: Select all

XIncludeFile "COMatePLUS\COMatePLUS.pbi"


Define.COMateObject oReg
Define.i safeArray
Define.i hst
Define.s command
Define.VARIANT varNamesArr, varName

hkey.l = #HKEY_LOCAL_MACHINE
strKeyPath.s = "SYSTEM\CurrentControlSet\Services"


oReg = COMate_GetObject("winmgmts:\\.\root\default:StdRegProv", "")
If oReg
	command = "EnumKey(" + Str(hkey) + ", '" + strKeyPath + "', " + Str(@varNamesArr) + " AS variant BYREF)"
      If oReg\Invoke(command) = #S_OK
				safeArray = varNamesArr\parray
         ; Retrieve the strings from the safearray
         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
                  Debug PeekS(varName\bstrVal, -1, #PB_Unicode)
                  SysFreeString_(varName\bstrVal)
                  varName\bstrVal = 0
               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
         
         ;Destroy the array.
         SafeArrayDestroy_(safeArray)

      Else
         Debug "invoke EnumKey error"
         Debug COMate_GetLastErrorDescription()
      EndIf


;    If oReg\Invoke("GetStringValue(" + Str(hkey) + ", '" + strKeyPath + "', '" + strValueName + "', " + Str(@dwValue) + " BYREF)") = #S_OK
;       sValue$ = PeekS(dwValue, -1, #PB_Unicode)
;       SysFreeString_(dwValue)
;       Debug "registry value = " + sValue$
;    Else
;       Debug "GetStringValue error : " + COMate_GetLastErrorDescription()
;    EndIf

   oReg\Release()
Else
   Debug "objet error"
EndIf
tatanas
Enthusiast
Enthusiast
Posts: 204
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: COMatePLus and request on remote host

Post by tatanas »

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
Last edited by tatanas on Mon Dec 14, 2020 11:27 am, edited 1 time in total.
Windows 10 Pro x64
PureBasic 6.04 x64
Justin
Addict
Addict
Posts: 830
Joined: Sat Apr 26, 2003 2:49 pm

Re: COMatePLus and request on remote host

Post by Justin »

hkey is a long(4 bytes), you did not declare it and it defaults to integer wich is 8 bytes in 64 bit so it was wrong, also use variant by ref as the return type.

It is better to use always enableexplicit and declare all the correct types.

This worked in 64 bit, i removed the hostname, user, pwd to use the local machine:

Code: Select all

XIncludeFile "COMatePLUS\COMatePLUS.pbi"

EnableExplicit


Define.s Hostname, login, password, strKeyPath, strValueName
Define.COMateObject objLocator, objService, objReg
Define.VARIANT varValue
Define.i value
Define.l hkey

Hostname = ""
login = ""
password = ""
hkey = #HKEY_LOCAL_MACHINE
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\VLC media player"
strValueName = "InstallLocation"

objLocator = COMate_CreateObject("WbemScripting.SWbemLocator")

If objLocator
   Debug "objLocator ok"
   objService = objLocator\GetObjectProperty("ConnectServer(" + "'" + Hostname + "', '" + "root\default" + "', '" + login + "', '" + password + "')")
   If objService

      objReg = objService\GetObjectProperty("Get('StdRegProv')")
      If objReg

         If objReg\Invoke("GetStringValue(" + Str(hkey) + ", '" + strKeyPath + "', '" + strValueName  + "', " + Str(@varValue) + " AS variant BYREF)") = #S_OK
            If varValue\vt = #VT_BSTR And varValue\bstrVal
            	Debug PeekS(varValue\bstrVal, -1, #PB_Unicode)   
            	SysFreeString_(varValue\bstrVal)
            EndIf 
         Else
            Debug "invoke error : " + COMate_GetLastErrorDescription()
         EndIf
         objReg\Release()
      Else
         Debug "objReg erreur"
      EndIf
      objService\Release()
   Else
      Debug "objService erreur"
   EndIf
   objLocator\Release()
EndIf
tatanas
Enthusiast
Enthusiast
Posts: 204
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: COMatePLus and request on remote host

Post by tatanas »

Thank you very much. It works like a charm !

Here is the code to list all installed sofwares from a remote computer :

Code: Select all

EnableExplicit

XIncludeFile "COMatePlus\COMatePLUS.pbi"

Define.s Hostname, login, password, strKeyPath, strKeyPath32, strValueName
Define.COMateObject objLocator, objService, objReg
Define hkey.l
Define.i lBound, uBound, i, ret

Hostname = "RemotePC"
login = "Administrator"
password = "password"
hkey = #HKEY_LOCAL_MACHINE
strKeyPath = "Software\Microsoft\Windows\CurrentVersion\Uninstall\"
strKeyPath32 = "Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
strValueName = "DisplayName"
; "UninstallString", QuietUninstallString

Define.COMateObject oReg
Define.i safeArray
Define.VARIANT varNamesArr, varName, dwValue
Define.s subkeyname


objLocator = COMate_CreateObject("WbemScripting.SWbemLocator")
If objLocator

   objService = objLocator\GetObjectProperty("ConnectServer(" + "'" + Hostname + "', '" + "root\default" + "', '" + login + "', '" + password + "')")
   If objService

      objReg = objService\GetObjectProperty("Get('StdRegProv')")
      If objReg

	
			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) + " AS variant BYREF)") = #S_OK
				            If dwValue\vt = #VT_BSTR And dwValue\bstrVal ; 8 = #VT_BSTR, 1 = #VT_NULL
				               Debug PeekS(dwValue\bstrVal, -1, #PB_Unicode)   
				               SysFreeString_(dwValue\bstrVal)
				            EndIf
							Else
								Debug "GetStringValue error : " + COMate_GetLastErrorDescription()
							EndIf

						EndIf
					Else
						If ret = #DISP_E_BADINDEX : Debug "error #DISP_E_BADINDEX" : EndIf
						If ret = #E_INVALIDARG : Debug "error #E_INVALIDARG" : EndIf
						If ret = #E_OUTOFMEMORY : Debug "error #E_OUTOFMEMORY" : EndIf
					EndIf
				Next
				
				SafeArrayDestroy_(safeArray)
				
			Else
				Debug "invoke EnumKey error"
				Debug COMate_GetLastErrorDescription()
			EndIf

Debug "-----------------------------------------------------------------------------"

			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) + " AS variant BYREF)") = #S_OK
				            If dwValue\vt = #VT_BSTR And dwValue\bstrVal ; 8 = #VT_BSTR, 1 = #VT_NULL
				               Debug PeekS(dwValue\bstrVal, -1, #PB_Unicode)   
				               SysFreeString_(dwValue\bstrVal)
				            EndIf
							Else
								Debug "GetStringValue error : " + COMate_GetLastErrorDescription()
							EndIf

						EndIf
					Else
						If ret = #DISP_E_BADINDEX : Debug "error #DISP_E_BADINDEX" : EndIf
						If ret = #E_INVALIDARG : Debug "error #E_INVALIDARG" : EndIf
						If ret = #E_OUTOFMEMORY : Debug "error #E_OUTOFMEMORY" : EndIf
					EndIf
				Next
				
				SafeArrayDestroy_(safeArray)
				
			Else
				Debug "invoke EnumKey error"
				Debug COMate_GetLastErrorDescription()
			EndIf



			objReg\Release()

		Else
			Debug "objReg error"
		EndIf

	Else
		Debug "objService error"
	EndIf
Else
	Debug "objLocator error"
EndIf
Windows 10 Pro x64
PureBasic 6.04 x64
Post Reply