Problem beim Auslesen von ini-files

fredlllll

Erfahrenes Mitglied
Guten Morgen. :p

Bastle grad an meinem i rum und habe aus VB6 den Code fürs Lesen von ini-Files übernommen. Musste 2 Variablen ändern, danach sollte Er eigentlich funktionieren. In gewisser Weise tut Er dies auch. Beim dritten Mal bekomm ich jedoch einen Überlauf und weiß nicht wieso. Hier mal die relevanten Code-ausschnitte:

das ist das Modul mit den Funktionen
Visual Basic:
Module inireadwrite
    Private Declare Function WritePrivateProfileString Lib "kernel32.dll" Alias "WritePrivateProfileStringA" ( _
    ByVal lpApplicationName As String, _
    ByVal lpKeyName As String, _
    ByVal lpString As String, _
    ByVal lpFileName As String) As Long

    Private Declare Function GetPrivateProfileString Lib "kernel32.dll" Alias "GetPrivateProfileStringA" ( _
        ByVal lpApplicationName As String, _
        ByVal lpKeyName As String, _
        ByVal lpDefault As String, _
        ByVal lpReturnedString As String, _
        ByVal nSize As Integer, _
        ByVal lpFileName As String) As Long

    Public Sub iniWrite(ByVal Eigenschaft As String, ByVal Kategorie As String, ByVal Wert As String, ByVal Pathname As String) 'schreiben in ini
        Dim retval As Long
        retval = WritePrivateProfileString(Kategorie, Eigenschaft, Wert, Pathname)
    End Sub

    Public Function iniRead(ByVal Eigenschaft As String, ByVal Kategorie As String, ByVal Pathname As String) As String 'lesen aus ini
        Dim defaultstr As String  ' going to receive the value read from the INI file
        Dim slength As Long  ' going to receive length of the returned string
        defaultstr = Space(255)  ' provide enough room for the function to put the value into the buffer
        slength = GetPrivateProfileString(Kategorie, Eigenschaft, "Error applied reading INI-File", defaultstr, Len(defaultstr), Pathname)
        defaultstr = Mid(defaultstr, 1, slength)
        iniRead = defaultstr
    End Function
End Module

Dann hier die Loc(alized) Funktion in der die ini-read/write aufgerufen wird.
Visual Basic:
Public Function loca(ByVal strick As String) As String
        loca = iniRead(strick, "Loc", Application.StartupPath & "\game\Lang.ini")
    End Function

Und hier der Bereich wo ich die Loc-Funktion mehrmals aufrufe um meine anwendung in mehreren Sprachen zur Verfügung zu stellen

Visual Basic:
 Private Sub frmSub_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.BackgroundImage = New Bitmap(Application.StartupPath & "\game\images\backgrounds\login.bmp")
        Label1.Text = loca("Benutzername")
        Label2.Text = loca("Passwort")
        CheckBox1.Text = loca("loginmerk")
        cmd_login.Text = loca("loginbtn")
'.......usw.usw....

Hierbei gehen die ersten beiden Aufrufe ohne Probleme (habe das schrittweise durchgespielt). Beim dritten Aufruf aber schießt die Variable slength aus dem Modul ins unendliche. Warum weiß ich nicht. Es gibt wie gesagt keinen Ersichtlichten Grund. Ich bekomme lediglich die Fehlermeldung "Die arithmetische Operation hat einen Überlauf verursacht.". Als lösung bietet er mir "Dividieren sie nicht durch 0 an"

Die ini-datei sieht wiefolgt aus:

Code:
[loc]
Benutzername=Benutzername:
Passwort=Passwort:
loginmerk=haha
regbtn=Registrieren
loginbtn=Login
usw....usw...

das haha wird sogar ausgelesen(man sieht den Anfang des Strings im debug). jedoch ist eben das slength viel zu hoch.
Hat irgendwer ne Ahnung warum das so läuft? in vb6 läuft der Code 1A. Musste für vb.net lediglich den typ von lpKeyName von Any auf String stellen und den Typ von nsize von Long auf Integer.

Hat wer ne idee :confused:
 
Zuletzt bearbeitet:
Ich konnte deinen Fehler bei mir zwar nicht reproduzieren, aber dafür einen anderen erzeugen. :confused:
Probier daher mal lpReturnedString als StringBuilder zu deklarieren, das hat bei mir geholfen:
Code:
Private Declare Function GetPrivateProfileString Lib "kernel32.dll" Alias "GetPrivateProfileStringA" ( _
ByVal lpApplicationName As String, _
ByVal lpKeyName As String, _
ByVal lpDefault As String, _
ByVal lpReturnedString As System.Text.StringBuilder, _
ByVal nSize As Integer, _
ByVal lpFileName As String) As Integer
Code:
Dim sb As New System.Text.StringBuilder(255)
Dim result As Integer = GetPrivateProfileString("blah", "bli", "blubb", sb, sb.Capacity, "C:\meine\datei.ini")
Messagebox.Show(sb.ToString)
Davon abgesehen würde ich dir aber empfehlen, dir eine Alternative zu ini-files zu suchen (zum Beispiel XML). Vor allem wenn es darum geht, deine Anwendung zu lokalisieren, denn hierfür bietet .Net den sehr hübschen ResourceManager. Schaue dir dazu mal das hier an: Lokalisieren von Windows Forms!
 
Danke
Scheint in der Tat zu funktionieren =)
Hat mein Projekt gerettet

Das mit dem ini zeug brauch ich aber auch noch an deren Stellen und da erscheinen mir die inis einfacher. Danke aber für den Tipp
 
Ich würde empfehlen eine eigene Ini Read/Write Klasse zu erstellen (Art Manager)

Der Ini Aufbau ist ja relativ Simpel

Code:
[Sektion]
Key1=Value
Key2=Value
[Section2]
Key1=Value
...

So lernst du auch gleich mit Dateien zu arbeiten.

Aber das nur mal am Rande.
 
ich würde die datei beim schreiben, einmal komplett auslesen, meine Section oder Key+Wert anfügen und reinschreiben (ohne Append, immer komplett schreiben).
Sprich bei jedem Zugriff eigentlich komplett neu lesen, so wäre gewährleistet das jedes Programm das drauf zugreift die aktuelslten Werte bekommt.

Wobei ich eigentlich vorallem beim schreiben eher die geringeren Probleme sehen würde.
 
mit den dlls geht es einfacher und warscheinlich auch schneller :p
ich will ja nich üben ich will schaffen. und in dem projekt kommen noch genug probleme wofür es keine dlls gibt =/
 
Meinte ja auch nur am Rande :D

Hätte sonst wie Shakie auch XML empfohlen oder Serilization.
Aber das ist ein Thema für eine andere Frage.
 
Hallo, ich habe genau das gleiche Problem wie der Thread-Ersteller, nur leider hat StringBuilder nichts geholfen.

Mein Code sieht aus wie folgt:

Code:
Public Declare Function GetPrivateProfileString Lib "kernel32" _
  Alias "GetPrivateProfileStringA" ( _
  ByVal lpApplicationName As String, _
  ByVal lpKeyName As String, _
  ByVal lpDefault As String, _
  ByVal lpReturnedString As String, _
  ByVal nSize As Long, _
  ByVal lpFileName As String) As Long

Und der Aufruf:

Code:
Dim sValue As String
Dim lResult As Long
 
 
sValue = Space$(255)
lResult = GetPrivateProfileString("Abschnitt", "Schlüssel", _
  "Standardwert", sValue, Len(sValue), myIniFile)
 
sValue = Microsoft.VisualBasic.Left(sValue, lResult)

Auch ich erhalte eine Disivion durch 0, lResult wächst auch bis ins unendliche... Eine umstellugn auf StringBuilder ergibt das gleiche....

Danke für eure Hilfe!
 
Hast du exakt Shakie's Code verwendet?
(Seine Parameter und Rückgabewert ist anders wie bei dir)

Was mich zum Beispiel irritiert Space$, das geht doch nur in VB aber nicht VB.Net :confused:
 
Zurück