Umlaute-Problem beim Verzeichnis per DIR einlesen

Anfängerfragen zum Programmieren mit PureBasic.
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Umlaute-Problem beim Verzeichnis per DIR einlesen

Beitrag von bin_neu_hier »

Hallo Leute,

ich würde gerne Verzeichnisse per DIR-Befehl einlesen. Sieht ungefähr so aus:

Code: Alles auswählen

compstring$ = "/c dir "
compstring$ + #DQUOTE$ + GetGadgetText(sg1) + #DQUOTE$ ; Verzeichnis
compstring$ + GetGadgetText(sg2) + " "   ;Suchmaske wie z. B. "*.p*"
;evtl. weitere Parameter für Attribute etc.
compstring$ + "/s /b"   ;inkl. Unterverzeichnisse und Format der Ausgabe

err = RunProgram(GetEnvironmentVariable("COMSPEC"),compstring$,"", #PB_Program_Open | #PB_Program_Read | #PB_Program_Hide | #PB_Program_UTF8)
            ClearList(foundfiles$())
            If err
              While ProgramRunning(err)
                If AvailableProgramOutput(err)                  
                  AddElement(foundfiles$())
                  foundfiles$() = ReadProgramString(err)
                EndIf
              Wend
              CloseProgram(err)
            EndIf
..., weil ich die Wildcard-Suche per DIR-Befehl so praktisch finde. Der Haken an der Sache ist, dass Dateinamen mit Umlauten falsch eingelesen werden, ä und ö werden durch "Chinesen" ersetzt, das ü verschwindet komplett, ...

Habe schon mit #PB_Program_UTF8 bzw. #PB_Program_ASCII rumexperimentiert oder mit CharToOem_ oder OemToChar_, hab's aber nicht hingekriegt. Kann mich da jemand kräftig in die richtige Richtung schubsen? Oder ist das eh' sowas wie ein totes Pferd reiten wollen?
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Benutzeravatar
Macros
Beiträge: 1361
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Re: Umlaute-Problem beim Verzeichnis per DIR einlesen

Beitrag von Macros »

Bei grad daheim angekommen und habe daher kein Windows zur Hand um das nachzuvollziehen.

Aber... aus deiner Beschreibung weiß ich noch nicht weshalb du den dir-Befehl nutzen willst.
Examinedirectory kann Patterns und spart dir einerseits das herumhantieren mit der API, andererseits läuft dein Code dann auch unter Linux und Max.

Du könntest auch die Einträge mit einer RegEx filtern und hast noch viel mehr Möglichkeiten.

Die Übung Programmausgaben zu lesen schadet trotzdem nie :wink:

Falls du auch rekursiv arbeiten willst, geht das mit Rekursion im Programm.
Sehr ausführlich hier: https://github.com/SicroAtGit/PB-CodeAr ... ntries.pbi

oder kurz und knackig hier:

Code: Alles auswählen

EnableExplicit
Define directory$="Pfad"
Define pattern$="*.*"

Procedure.s ListDir(path$,pattern$, lenbasedir=0)
  Define dir, name$, out$
  If lenbasedir=0
    lenbasedir=Len(path$)+1
  EndIf
  
  dir = ExamineDirectory(#PB_Any,path$,pattern$)
  If dir
    While NextDirectoryEntry(dir)
      name$=DirectoryEntryName(dir)

      If name$="." Or name$=".."
        Continue ; So kommen wir in keine Endlosschleife
      EndIf
    
      ; Wir schneiden den ursprünglichen Pfad mit mid() ab
      out$+Mid(path$,lenbasedir)+DirectoryEntryName(dir)+#LF$ 
      If DirectoryEntryType(dir)=#PB_DirectoryEntry_Directory
        out$+ListDir(path$+DirectoryEntryName(dir)+"/",pattern$,lenbasedir)
      EndIf
    Wend
    FinishDirectory(dir)
  EndIf

  ProcedureReturn out$
EndProcedure

Debug ListDir(directory$,pattern$)
Für Windows kannst du die Forward Slashes "/" in Backward Slashes "\" ändern, damit die Pfade normaler aussehen.
Bild
Benutzeravatar
HeX0R
Beiträge: 3040
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Umlaute-Problem beim Verzeichnis per DIR einlesen

Beitrag von HeX0R »

Du kannst auch /U hinzufügen, dann sollte der output von COMSPEC Unicode sein (nicht! UTF-8!)
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Re: Umlaute-Problem beim Verzeichnis per DIR einlesen

Beitrag von bin_neu_hier »

Hallo Macros und Hexor!

Warum den DIR-Befehl? Habe eine ganze Reihe von Code-Beispielen hier und im englischen Forum ausprobiert. Warum auch immer, in vielen Beispielen wollte die Auswahl der Suchmaske (z. B. "*.p*") nicht funktionieren. Es ist immer wieder darauf hinausgelaufen, erstmal alle Dateien in eine Liste zu laden, um dann auszusortieren. Bin irgendwann über die Möglichkeit gestolpert, über den DIR-Befehl die Daten abzurufen - hat mir gefallen, wollte dabei bleiben. Ja, rekursive Dateisuche wäre wünschenswert, habe aber nichts Brauchbares gefunden, dass einerseits das kann, was ich brauche, andererseits auch von mir verstanden wird. Das wirklich ausführliche Beispiel https://github.com/SicroAtGit/PB-CodeAr ... ntries.pbi geht weit über meinen Anfängerhorizont hinaus. Wenn ich den Code nicht verstehe, kann ich den auch nicht an meine Bedürfnisse anpassen. Soll nicht heißen, dass ich nicht bereit wäre, mich in Dinge hineinzufuchsen, aber die Umstände lassen nicht das eingehende Studium zu, das erforderlich wäre. Ich werde nie über ein Anfängerstadium hinauskommen und für mich ist das auch OK. Wie andere Anfänger auch profitiere ich davon, dass die Profis in Foren wie diesem ihr Fachwissen zur Verfügung stellen. Herzlichen Dank an alle!

@ Hexor: Dein Tipp mit "/U" funzt bestens zusammen mit dem "#PB_Program_Unicode"-Flag bei RunProgram. Besten Dank!
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Umlaute-Problem beim Verzeichnis per DIR einlesen

Beitrag von H.Brill »

Oder laß es doch gleich mit DIR mittels Umleitung in eine Datei schreiben :
dir "*.p*" /s >dateien.txt
/s bezieht alle Unterordner mit ein.
Da in dateien.txt ja noch mehr drin steht, brauchst du ja nur (am besten mit regex)
die Dateinamen rausfiltern. Das sind alle Zeilen der dateien.txt, die mit Datum und Zeit
anfangen (16 Zeichen). Der Rest ist ja dann einfach.
PB 6.10
bin_neu_hier
Beiträge: 105
Registriert: 06.03.2019 21:52

Re: Umlaute-Problem beim Verzeichnis per DIR einlesen

Beitrag von bin_neu_hier »

Hallo Leute,

hilft ja alles nix, Macros' Argumente sind nicht von der Hand zu weisen. Habe rumgesucht und einen Code gefunden, den ich inhaltlich einigermaßen verstehe und bei dem ich mir zutraue, die eine oder andere erforderliche Anpassung hinzubekommen. Nämlich den hier:
http://forums.purebasic.com/english/vi ... p?t=24887

Code: Alles auswählen

Procedure SearchDirectory(dir$, pattern$, List dList.s(), level.l = 0)
  Protected eName$
  NewList Dirs.s()
  
  If (level = 0)
    ClearList(dList())
  EndIf
  
  If Right(dir$, 1) <> "\"
    dir$ + "\"
  EndIf
  
  If ExamineDirectory(0, dir$, "")
    While NextDirectoryEntry(0)
      If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory
        eName$ = DirectoryEntryName(0)
        If (eName$ <> ".") And (eName$ <> "..")
          AddElement(Dirs())
          Dirs() = eName$ + "\"
        EndIf
      EndIf
    Wend
    FinishDirectory(0)
   
    If ExamineDirectory(0, dir$, pattern$)
      While NextDirectoryEntry(0)
        eName$ = DirectoryEntryName(0)
        If (eName$ <> ".") And (eName$ <> "..")
          AddElement(dList())
          dList() = dir$ + eName$
          If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory
            dList() + "\"
          EndIf
        EndIf
      Wend
      FinishDirectory(0)
    EndIf
  EndIf
 
  If ListSize(Dirs())
    ForEach Dirs()
      SearchDirectory(dir$ + Dirs(), pattern$, dList(), level + 1)
    Next
  EndIf
 
  If (level = 0)
    ForEach dList()
      dList() = Mid(dList(), Len(dir$) + 1, Len(dList()))
    Next
    SortList(dList(), 2)
  EndIf
EndProcedure

NewList FilesAndFolders.s()
SearchDirectory("C:\WINDOWS", "sys*", FilesAndFolders())
Debug "Found " + Str(ListSize(FilesAndFolders())) + " object(s)"
ForEach FilesAndFolders()
  Debug FilesAndFolders()
Next
End
Wenn ein User als Laufwerk "C:\" angibt und als Suchmaske "*.*", dann rödelt die Maschine u. U. eine quälend lange Zeit, bis alles gefunden wurde. Ich brauche also so etwas wie einen "Not-Ausschalter". Habe aber nur eine viel zu vage Vorstellung davon, wie das mit den Events abläuft.
Wenn ich einen Button hätte, der eine (globale) Variable entsprechend setzt und bei jedem neu gefundenen Unterverzeichnis diese Variable abgefragt werden würde, würde das funktionieren? Oder wird der Buttonklick erst bearbeitet, wenn die Routine fertig abgearbeitet ist? Würde man mit einen "kleinen" Delay Zeit für die Eventabfrage schaffen, ohne die Suchroutine zu sehr zu verzögern?
Bin mit 21 erstmals mit Computern in Kontakt gekommen und konnte mich daher in meiner Jugend ganz auf den Alkohol konzentrieren. Bin nun seit fast 40 Jahren programmiertechnisch konstant auf Anfänger-Level, konnte jedoch beim Thema Alkohol eine gewisse Virtuosität erreichen.
Irgendwas muss man ja gut können.
Benutzeravatar
H.Brill
Beiträge: 496
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Umlaute-Problem beim Verzeichnis per DIR einlesen

Beitrag von H.Brill »

Ich würde die Suche dann in einem Thread laufen lassen.
PB 6.10
Benutzeravatar
mk-soft
Beiträge: 3844
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Umlaute-Problem beim Verzeichnis per DIR einlesen

Beitrag von mk-soft »

Siehe Beispiel 4 von
Link: Mini Thread Control
Um es noch etwas Schneller zu machen, kannst du im MyThreadGetFiles das Delay von 5 ms auf 1 ms umstellen.

Eine deutsche Beschreibung von Mini Thread Control (Ohne Beispiel 4) findest du hier: viewtopic.php?t=31581
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Axolotl
Beiträge: 265
Registriert: 31.12.2008 16:34

Re: Umlaute-Problem beim Verzeichnis per DIR einlesen

Beitrag von Axolotl »

Moin,
also als "Not-Ausschalter" würde ich meine Vorschläge nicht bezeichnen, aber man kann durch einfachen Tastendruck beliebige Schleifen verlassen.
Einfach den Dreizeiler innerhalb eine Schleife "richtig" einbauen. (Windows only)

Code: Alles auswählen

  
If GetAsyncKeyState_(#VK_ESCAPE) & $8000 
  Break ; get out -- escape the loop  
EndIf 

Je nachdem wie "professionel" die App aussehen soll, kann auch ein Button als Schleifen-Abbruch eingebaut werden....
Ich habe dafür mal eine häufig gesehene/verwendete "FlushMessages()" procedure erweitert.

Code: Alles auswählen

Procedure FlushMessages(Gadget = 0) 
  While WindowEvent() 
    If IsGadget(Gadget) And EventGadget() = Gadget
      ProcedureReturn #True 
    EndIf 
  Wend  
  ProcedureReturn #False 
EndProcedure 
Du solltest allerdings bedenken, dass du hiermit die Nachrichtenschlange von Windows abfragst und alle Nachrichten, die nicht dem Gadget entsprechen verloren gehen. D.h. diese Nachrichten tauchen nicht mehr in der Hauptschleife auf.
Für die "professionelle Version" haben die Pros ja schon die Thread Lösungen ins Spiel gebracht.
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Antworten