exe geht - exe geht nicht - eine Idee

olek

Mitglied
Servus an Alle :)

Habe ein kleines VB-Programm (VB 6) geschrieben, das nun als exe vorliegt.
Dieses führe ich auf verschiedenen PCs aus - nun folgt das komische:

Auf einigen PCs rennt die exe tadellos auf andren PCs folgt dieser Error:
35600, index out of bounds

Die PCs auf denen die exe getestet wurde sind alle XP Prof. SP2 Kisten mit Office und anderen normalen Standardprogrammen. (keine VB Umgebung oder ähnliches).
Auf einigen rennt die exe perfekt auf anderen taucht eben dieser Fehler auf.

Woran könnte das liegen ?
Habe schon etliches ausprobiert aber es kann doch nicht sein das ein und diesselbe exe auf einem pc geht und auf dem anderen wieder nicht :-(

Bin für jeden Vorschlag sehr Dankbar!

greets alex
 
Schätzungsweise liegt es daran, dass auf manchen PCs nicht alle benötigten DLLs oder OCX-Dateien installiert sind. Überprüfe mal, welche Dateien dein Programm benötigt und schau nach, ob auf den entsprechenden PCs diese Dateien vorhanden sind.

Zum Nachgucken, welche Dateien benötigt werden kann man den "Verpackungs- und Weitergabe-Assistent" verwenden.
 
Ich lese die Hardware über die Registry aus.
Dabei benötige ich 2 ocx Dateien also bei mir:

MSCOMCTL.OCX
comctl32.ocx

Diese beiden Dateien stehen überall im system32 Ordner auf jedem PC wo ich die exe ausprobiert habe. Trotzdem geht die exe nicht überall.

Übrigens wo finde ich diesen "Verpackungs- und Weitergabe-Assistent" ?
Habe ihn in VB nicht gefunden. Da gibts nur einen Visual Component Manager und einen allgemeinen Component Manager wo ich halt das Hackerl bei "Microsoft Windows Common Controls 6.0 (SP6)

Cya Alex
 
Index out of bounds heisst normalerweise, dass du wenn du mit einem array arbeitest über die grenze hinausschiesst also bei einem array aus 4 elementen auf das 5. zugreifst
oder dass du auf ein Item zugreifst welches es nicht gibt -> Prüfe mal ob du irgendwo eine .Item Methode verwendest.

Gruß bb
 
Wenn es wirklich etwas mit der Grenze zu tun hätte dann würde doch das Programm überhaupt nicht funktionieren oder? ich meine es funkt ja auf einigen PCs. kann doch kein Zufall sein.

Hier einmal der Hauptcode wobei ich nichts falsches erkennen kann:


Private 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
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegEnumKeyEx Lib "advapi32.dll" Alias "RegEnumKeyExA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, lpcbName As Long, lpReserved As Long, ByVal lpClass As String, lpcbClass As Long, lpftLastWriteTime As Any) As Long
Private 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

' Einige RegOpenKeyEx samDesired-Konstanten
Private Const KEY_ENUMERATE_SUB_KEYS = &H8 ' Öffnen zum Enumerieren
Private Const KEY_READ = &H20019 ' Öffnen zum Lesen

' RegEnumValue lpType-Konstanten
Private Const REG_DWORD = 4 ' Ein 32-Bit Integerwert (Little Endian)
Private Const REG_SZ = 1 ' Ein VBNullChar-Zeichen Terminierter String

' Allgemeine (ROOT) hKey-Konstanten für die Registry Funktionen
Private Const HKEY_LOCAL_MACHINE = &H80000002 ' Local Machine Schlüssel

Private Const DevClassPath = "SYSTEM\ControlSet001\Control\DeviceClasses\"
Private Const EnumPath = "System\CurrentControlSet\Enum\"
Private Const ClassPath = "System\CurrentControlSet\Control\Class\"

' API Deklaration: Hostname
Const MAX_COMPUTERNAME_LENGTH = 15
Private Declare Function GetComputerName Lib "kernel32" _
Alias "GetComputerNameA" (ByVal lpBuffer As String, _
nSize As Long) As Long

' Wert eines Eintrags ermitteln (String)
Private Function GetValueStr(ByVal DevicePath As String, ByVal Value As String) As String

Dim hKey As Long, TmpStr As String * 256

' Schlüssel öffnen
Call RegOpenKeyEx(HKEY_LOCAL_MACHINE, DevicePath, 0&, KEY_READ, hKey)
If hKey <> 0 Then

' Eintrag lesen
Call RegQueryValueEx(hKey, Value, 0&, REG_SZ, ByVal TmpStr, 256)
GetValueStr = Left$(TmpStr, InStr(1, TmpStr, vbNullChar) - 1)
RegCloseKey hKey
End If

End Function

' Wert eines Eintrags ermitteln (Long)
Private Function GetValueLng(ByVal DevicePath As String, ByVal Value As String) As Long

Dim hKey As Long, TmpLng As Long

' Schlüssel öffnen
Call RegOpenKeyEx(HKEY_LOCAL_MACHINE, DevicePath, 0&, KEY_READ, hKey)
If hKey <> 0 Then

' Eintrag lesen
Call RegQueryValueEx(hKey, Value, 0&, REG_SZ, TmpLng, 4)
GetValueLng = TmpLng
RegCloseKey hKey
End If

End Function

' Enumerieren aller installierten Geräte
Public Function EnumConntectedDevices()

Dim hKey As Long, TmpStr As String * 256, RegClass As String * 256, i As Integer, Retval As Long

' Schlüssel der installierten Hardwareklassen öffnen
Call RegOpenKeyEx(HKEY_LOCAL_MACHINE, DevClassPath, 0&, KEY_ENUMERATE_SUB_KEYS, hKey)
If hKey <> 0 Then
Do
' Hardwareklassen Enumerieren
Retval = RegEnumKeyEx(hKey, i, TmpStr, Len(TmpStr), ByVal 0&, RegClass, Len(RegClass), ByVal 0&)
If Retval <> 0 Then
Exit Do
End If
i = i + 1

' Hardwaregeräte Enumerieren
Call EnumDevices(DevClassPath & Left$(TmpStr, InStr(1, TmpStr, vbNullChar) - 1) & "\")
Loop
RegCloseKey hKey
End If

End Function

' Geräte einer Klasse Enumerieren
Private Function EnumDevices(ByVal DevicePath As String)

Dim hKey As Long, TmpStr As String * 256, RegClass As String * 256, i As Integer, Retval As Long

' Schlüssel der Geräte öffnen
Call RegOpenKeyEx(HKEY_LOCAL_MACHINE, DevicePath, 0&, KEY_ENUMERATE_SUB_KEYS Or KEY_READ, hKey)
If hKey <> 0 Then
Do
' Geräte der Hardwareklasse Enumerieren
Retval = RegEnumKeyEx(hKey, i, TmpStr, Len(TmpStr), ByVal 0&, RegClass, Len(RegClass), ByVal 0&)
If Retval <> 0 Then
Exit Do
End If
i = i + 1

' Emulierte Netzwekgeräte filtern
If Right$(DevicePath, 39) = "{ad498944-762f-11d0-8dcb-00c04fc3358c}\" Then
If UCase(Left$(TmpStr, 8)) <> "##?#ROOT" And UCase(Left$(TmpStr, 6)) <> "##?#SW" Then
Call EnumSubDevices(DevicePath & Left$(TmpStr, InStr(1, TmpStr, vbNullChar) - 1) & "\")
End If
Else
Call EnumSubDevices(DevicePath & Left$(TmpStr, InStr(1, TmpStr, vbNullChar) - 1) & "\")
End If
Loop
RegCloseKey hKey
End If

End Function

' Instanzen der selben Hardware Enumerieren (z.B. Wave & Midi einer Soundkarte)
Private Function EnumSubDevices(ByVal DevicePath As String)

Dim hKey As Long, TmpStr As String * 256, RegClass As String * 256, i As Integer, Retval As Long
Dim DevInstance As String, DevDesc As String, LI As ListItem, DExist As Boolean, j As Integer

Call RegOpenKeyEx(HKEY_LOCAL_MACHINE, DevicePath, 0&, KEY_ENUMERATE_SUB_KEYS Or KEY_READ, hKey)

For i = 0 To GetValueLng(DevicePath & "Control\", "ReferenceCount")
' Untergerät ermitteln
Retval = RegEnumKeyEx(hKey, i, TmpStr, Len(TmpStr), ByVal 0&, RegClass, Len(RegClass), ByVal 0&)

' Gerät angeschlossen?
If GetValueLng(DevicePath & Left$(TmpStr, InStr(1, TmpStr, vbNullChar) - 1) & "\Control\", "Linked") = 1 Then
' DeviceInstance Pfad ermitteln
DevInstance = GetValueStr(DevicePath, "DeviceInstance")
DevDesc = GetValueStr(EnumPath & DevInstance & "\", "DeviceDesc")
If DevDesc = "" Then DevDesc = GetValueStr(EnumPath & DevInstance & "\", "DeviceDesc")

' Doppelte Einträge?
DExist = False
For j = 1 To ListView1.ListItems.Count
If ListView1.ListItems(j).SubItems(1) = DevInstance Then DExist = True
Next j

' Doppelte, Storage, System und SW Geräte wollen wir nicht!
If Not DExist And UCase(Left$(DevInstance, 2)) <> "SW" And UCase(Left$(DevInstance, 7)) <> "STORAGE" And _
UCase(GetValueStr(EnumPath & GetValueStr(DevicePath, "DeviceInstance"), "Class")) <> "SYSTEM" Then
Set LI = ListView1.ListItems.Add(, , DevDesc)
LI.SubItems(1) = DevInstance
End If
End If
Next i
RegCloseKey hKey

End Function
 
"Verpackungs- und Weitergabe-Assistent" findest du hier: ...Dein-VB-Verzeichnis\Wizards\PDWizard\PDCMDLN.EXE
Überprüfe auch mal die Verwendeten DLLs, dazu in VB auf Menü "Projekt" -->"Verweise" klicken
 
Wenn es wirklich etwas mit der Grenze zu tun hätte dann würde doch das Programm überhaupt nicht funktionieren oder?

Nein da du mit apis arbeitest und nicht alle rechner gleich sind muss das nicht sein
(könnte schon reichen wenn einer weniger speicher hat was ich nicht glaube)

2. ich habe mir deinen Code mal angeschaut: es wäre ganz gut gewesen in welcher reihenfolge du die Funktionen aufrufst aber egal

3. als TIp : bau mal in alle funktionen eine kleine Fehlerbehandlung ein
Bsp:

Private Function GetValueStr(ByVal DevicePath As String, ByVal Value As String) As String
On Error goto GetValueStrErr
Dim hKey As Long, TmpStr As String * 256

' Schlüssel öffnen
Call RegOpenKeyEx(HKEY_LOCAL_MACHINE, DevicePath, 0&, KEY_READ, hKey)
If hKey <> 0 Then

' Eintrag lesen
Call RegQueryValueEx(hKey, Value, 0&, REG_SZ, ByVal TmpStr, 256)
GetValueStr = Left$(TmpStr, InStr(1, TmpStr, vbNullChar) - 1)
RegCloseKey hKey
End If
exit function

GetValueStrErr:

Call MSgbox "Fehler in GetValueStr" & err.number & err.description


End Function



das hilft zumindest soweit das du weisst wo du suchen musst


Gruß bb
 
Ich würde meinen Hintern darauf verwetten, daß die Zeilen

Code:
For j = 1 To ListView1.ListItems.Count
If ListView1.ListItems(j).SubItems(1) = DevInstance Then DExist = True
Next j

den Fehler verursachen, denn das erste ListView-Element hat den Index 0. ;)
 
Negativ! :p Die Einträge im ListView starten im Gegensatz zur ListBox mit Index 1!
Edit: Könnte man den Startindex mit einer Anweisung in "Option Explicit" verändern?
 
Irgendwas mit dem Listview hat das aber sicher zu tun, womöglich ist es nicht gefüllt.

Am besten mittels MZ-Tools mal Zeilennummern einbauen lassen und dann für jede
Sub oder Function eine lückenlose Fehlerbehandlung einbauen. Da erspart man sich viel Zeit bei der Fehlersuche.

z.B.

Code:
10     On Error GoTo Fehler

20     'dein Code

Ausgang:
            
30     Exit Sub
            
Fehler:
         
40     MsgBox "Fehler Sub in Zeile " & Erl & " " & Err.Description
         
50     Resume Ausgang
60     Resume
 
Zurück