um es gleich vorweg zu nehmen; LS Anfänger haben hier keine Chance.
Habe heute noch ein wenig rumgebastelt. Es geht darum, die auf einem Rechner installierte Software auszulesen und z.B. an ein HelpDesk zu übermitteln. Alternativ soll es aber auch möglich sein, von einem Rechner mit Adminrechten die Software remote auszulesen.
Grundüberlegung dabei ist, daß die allermeisten installierten Programme ihre Spuren im Registry Key
Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\ hinterlassen.
Also brauchen wir ein Stück Code, welches die in diesem Key enthaltenen SubKeys ausliest.
Hat man den Subkey, kann man über den Wert DisplayName im Klartext auslesen, um welches Programm es sich handelt.
Ich habe da mal flott eine Klasse zusammengebaut, welches die Subkeys eines gegebenen Keys ausliest. Das funktioniert sowohl local als auch remote ( Wert in thisServer kann ein DNS Name oder eine IP Adresse sein ).
Dummerweise liefert mir die Funktion. GetValue immer einen Leerstring zurück, obwohl lpData korrekt die Länge des zu erwartenden Strings ausgibt.
Mit dem dem Notes eigenen Befehl zum Auslesen der Registry funktioniert des Auslesen leider nur local.
RegConnectRegistry(thisServer, eHKEY_LOCAL_MACHINE, lhRemoteRegistry)
liefert in lhRemoteRegistry zwar ein Handle auf den remote host zurück, aber das kann ich leider nicht an
@RegQueryValue
übergeben.
HKEY_LOCAL_MACHINE im macro mit lhRemoteRegistry zu ersetzen bringt irgendwie nix.
Möglicherweise hat ja jemand Lust, sich durch den Code durchzuwuseln. ( ich darf ja das LapTop nicht mit in den Urlaub nehmen
)
Hier der Code für den Test Buhtong
Use "lib.appl.registry"
Sub Click(Source As Button)
'Dim dummy As variant
Dim Registry As New clsRegistry
Dim ret As String
Dim thisKey As String
Dim thisServer As String
Dim macro As String
Dim i As Integer
i = 0
thisKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
thisServer = "192.168.123.122"
If Registry.KeyExists (eHKEY_LOCAL_MACHINE, thisKey, thisServer) Then
Do
ret = Registry.ListSubKey(eHKEY_LOCAL_MACHINE, thisKey, i , thisServer)
If ret ="" Then Exit Do
' lReturnCode = RegConnectRegistry(thisServer, eHKEY_LOCAL_MACHINE, lhRemoteRegistry)
' macro = |"HKEY_LOCAL_MACHINE";| & |"| & thisKey & ret & |";| & |"DisplayName"|
' dummy = Evaluate (|@RegQueryValue(| & macro & |)|)
If ret = "" Then
Else
Msgbox ret
End If
i = i +1
Loop Until ret = ""
End If
End Sub
und hier der Code der Klasse
'lib.appl.registry:
Option Public
Option Declare
'Use "lib.appl.functions"
Const ERROR_SUCCESS = 0
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_OPTION_NON_VOLATILE = 0
Const REG_SZ = 1
Const SYNCHRONIZE = &H100000
Const STANDARD_RIGHTS_ALL = &H1F0000
Const KEY_CREATE_LINK = &H20
Const KEY_CREATE_SUB_KEY = &H4
Const KEY_ENUMERATE_SUB_KEYS = &H8
Const KEY_NOTIFY = &H10
Const KEY_QUERY_VALUE = &H1
Const KEY_SET_VALUE = &H2
Const KEY_ALL_ACCESS = ((STANDARD_RIGHTS_ALL Or KEY_QUERY_VALUE Or KEY_SET_VALUE Or KEY_CREATE_SUB_KEY Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY Or KEY_CREATE_LINK) And (Not SYNCHRONIZE))
Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
Const eHKEY_CLASSES_ROOT = &H80000000
Const eHKEY_CURRENT_USER = &H80000001
Const eHKEY_LOCAL_MACHINE = &H80000002
Const eHKEY_USERS = &H80000003
Const eHKEY_PERFORMANCE_DATA = &H80000004
Const eHKEY_CURRENT_CONFIG = &H80000005
Const eHKEY_DYN_DATA = &H80000006
Declare Function RegOpenKeyEx Lib "advapi32.dll" _
Alias "RegOpenKeyExA" _
(Byval hKey As Long, Byval lpSubKey As String, _
Byval ulOptions As Long, Byval samDesired As Long, _
phkResult As Long) As Long
Declare Function RegConnectRegistry Lib "advapi32.dll" _
Alias "RegConnectRegistryA" _
(Byval lpMachineName As String, _
Byval hKey As Long, _
phkResult As Long) As Long
Declare Function RegCloseKey Lib "advapi32.dll" _
(Byval hKey As Long) As Long
Declare Function RegQueryValueEx Lib "advapi32.dll" _
Alias "RegQueryValueExA" (Byval hKey As Long, _
Byval lpValueName As String, Byval lpReserved As Long, _
lpType As Long, lpData As Any, _
lpcbData As Long) As Long
Declare Function RegQueryValueExString Lib "advapi32.dll" _
Alias "RegQueryValueExA" (Byval hKey As Long, _
Byval lpValueName As String, Byval lpReserved As Long, _
lpType As Long, lpData As String, _
lpcbData As Long) As Long
Declare Function RegEnumKeyEx Lib "advapi32.dll" _
Alias "RegEnumKeyExA" _
(Byval hKey As Long, Byval dwIndex As Long, _
Byval lpName As String, lpcbName As Long, _
Byval lpReserved As Long, Byval lpClass As String, _
lpcbClass As Long, _
lpftLastWriteTime As FILETIME) As Long
Declare Function RegEnumValue Lib "advapi32.dll" _
Alias "RegEnumValueA" _
(Byval hKey As Long, _
Byval dwIndex As Long, _
Byval lpValueName As String, _
lpcbValueName As Long, _
Byval lpReserved As Long, _
lpType As Long, _
lpData As Byte, _
lpcbData As Long) As Long
Class clsRegistry
Public Sub new()
'constructor
End Sub
Public Function ListSubKey(Byval PredefinedKey As Long, Byval KeyName As String, Byval Index As Long, ComputerName As String) As String
Dim GetHandle As Long
Dim hKey As Long
Dim dwIndex As Long
Dim lpName As String
Dim lpcbName As Long
Dim lpReserved As Long
Dim lpftLastWriteTime As FILETIME
Dim i As Integer
Dim lReturnCode As Long
Dim lhRemoteRegistry As Long
If Left$(KeyName, 1) = "\" Then
KeyName = Right$(KeyName, Len(KeyName) - 1)
End If
If ComputerName = "" Then
GetHandle = RegOpenKeyEx(PredefinedKey, KeyName, 0, KEY_ALL_ACCESS, hKey)
Else
lReturnCode = RegConnectRegistry(ComputerName, PredefinedKey, lhRemoteRegistry)
GetHandle = RegOpenKeyEx(lhRemoteRegistry, KeyName, 0, KEY_ALL_ACCESS, hKey)
End If
If GetHandle = ERROR_SUCCESS Then
lpcbName = 255
lpName = String$(lpcbName, Chr(0))
GetHandle = RegEnumKeyEx(hKey, Index, lpName, lpcbName, lpReserved, Null, 0, lpftLastWriteTime)
If GetHandle = 234 Then
ListSubKey = Left$(lpName, lpcbName)
Else
ListSubKey = ""
End If
RegCloseKey hKey
End If
End Function
Public Function KeyExists(Byval PredefinedKey As Long, Byval KeyName As String, ComputerName As String) As Boolean
Dim hKey As Long
Dim GetHandle As Long
Dim lhRemoteRegistry As Long
Dim lReturnCode As Long
If Left$(KeyName, 1) = "\" Then
KeyName = Right$(KeyName, Len(KeyName) - 1)
End If
If ComputerName = "" Then
GetHandle = RegOpenKeyEx(PredefinedKey, KeyName, 0, KEY_ALL_ACCESS, hKey)
Else
lReturnCode = RegConnectRegistry(ComputerName, PredefinedKey, lhRemoteRegistry)
GetHandle = RegOpenKeyEx(lhRemoteRegistry, KeyName, 0, KEY_ALL_ACCESS, hKey)
End If
If GetHandle = ERROR_SUCCESS Then
KeyExists = True
Else
KeyExists = False
End If
End Function
Function GetValue(Byval PredefinedKey As Long, Byval KeyName As String, Byval ValueName As String, ComputerName As String) As Variant
Dim GetHandle As Long
Dim hKey As Long
Dim lpData As String
Dim lpDataDWORD As Long
Dim lpcbData As Long
Dim lpType As Long
Dim lReturnCode As Long
Dim lhRemoteRegistry As Long
If Left$(KeyName, 1) = "\" Then
KeyName = Right$(KeyName, Len(KeyName) - 1)
End If
If ComputerName = "" Then
GetHandle = RegOpenKeyEx(PredefinedKey, KeyName, 0, KEY_ALL_ACCESS, hKey)
Else
lReturnCode = RegConnectRegistry(ComputerName, PredefinedKey, lhRemoteRegistry)
GetHandle = RegOpenKeyEx(lhRemoteRegistry, KeyName, 0, KEY_ALL_ACCESS, hKey)
End If
If GetHandle = ERROR_SUCCESS Then
lpcbData = 255
lpData = String(lpcbData, Chr(0))
GetHandle = RegQueryValueEx(hKey, ValueName, 0, lpType, Byval lpData, lpcbData)
If GetHandle = ERROR_SUCCESS Then
Select Case lpType
Case REG_SZ
GetHandle = RegQueryValueExString(hKey, ValueName, 0, lpType, Byval lpData, lpcbData)
If GetHandle = 0 Then
GetValue = Left$(lpData, lpcbData - 1)
Else
GetValue = ""
End If
Case REG_DWORD
GetHandle = RegQueryValueEx(hKey, ValueName, 0, lpType, lpDataDWORD, lpcbData)
If GetHandle = 0 Then
GetValue = Clng(lpDataDWORD)
Else
GetValue = 0
End If
Case REG_BINARY
GetHandle = RegQueryValueEx(hKey, ValueName, 0, lpType, lpDataDWORD, lpcbData)
If GetHandle = 0 Then
GetValue = Cbyte(lpDataDWORD)
Else
GetValue = 0
End If
End Select
End If
RegCloseKey hKey
End If
End Function
End Class