[gelöst]StringList->bat-Datei - Problem mit Umlauten und BOM

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
hubblec4
Beiträge: 341
Registriert: Sa 25. Jan 2014, 17:50

[gelöst]StringList->bat-Datei - Problem mit Umlauten und BOM

Beitrag von hubblec4 »

Hallo an alle

Ich habe diemal ein paar sorgen beim erstellen einer bat/cmd Datei welche Umlaute in den Parametern hat.

Ich habe Onkel Google und hier im Forum auch einiges zu diesem Thema gefunden nur halt nicht das passende.
Das Problem mit den Umlauten bezieht sich nur auf die Parameter in der bat datei, welche dann von dem ausführenden Programm fehlinterpretiert werden.

Im prinzip ganz simple nach zu stellen, so dass man in dem normalen windows Texteditor eine bat bearbeitet und dort einen Pfad mit umlauten eingibt.
Wenn ich diese bat datei in Notpad++ einlese und bei "Sprachen" auf MS Dos Stil umstelle, sieht man wie sich die ä,ö,ö ..usw ändern.
schreibt man nun ein ä,ü,ö -> speichern, dann funktioniert auch das programm, und im normalen Texteditor sieht man statt den ä,ü,ö ander Zeichen.

In Lazarus gibts ja ne menge Umcodierungs Funktionen. Ich habe UTF8toAnsi, UTF8toSys, UTF8toConsole ausprobiert aber es stehen entweder ä,ü,ö drin oder andere Zeichen, aber nicht die Zeichen welche ich mittels Notepad++ habe.


Code: Alles auswählen

function F_Mux_bat_erzeugen(output,filename:string):string;
var mkvmerge,paras:string; bat: TStringList;
begin
  Result:='';
  // mkvmerge pfad ermitteln
  mkvmerge:='C:\mkvmerge.exe'
 
  // 1.und 2. para
  paras:='"'+mkvmerge+'" -o';
 
  // 3. para - output file name
  paras:=paras + ' "' +UTF8ToConsole(output+filename) +'.mkv"';
 
  
  // bat list init
  bat:=TStringList.Create;
  bat.Add(paras);
 
  // den code speichern
  bat.SaveToFile(Utf8ToAnsi(output+filename)+'_mux.bat')
 
  bat.Free;
 
  // mit memo
  with Memo do
  begin
   Clear;
   Lines.Add(paras);
   Lines.SaveToFile(output+filename+'_mux.bat');
  end;
  Result:='ok';
 
end;               


Das erstellen ist alles kein Problem, aber welche Codierung muss ich verwenden, damit die Parameter stimmig sind?

Das andere Problem ist wegen dem BOM.
ich hatte die Funktion geschrieben, und gleich ausprobiert und dann meckerte mkvmerge wegen den falschen parametern, und man sah in der Console auch dieses Spezielle sonderzeichen für das BOM, ebenso sah man es im Hex editor. Erstellt TStringList immer eine Datei mit BOM?
Hatte dazu auch was gefunden, allerdings nur für Delphi (StringList.WriteBOM:=false).


hubblec4
Zuletzt geändert von hubblec4 am Fr 14. Aug 2015, 10:44, insgesamt 1-mal geändert.

Martin V
Beiträge: 142
Registriert: Sa 30. Jan 2010, 19:35
OS, Lazarus, FPC: Linux64, Wiindows32, MacOS, Lazarus 1.8.2
CPU-Target: xxBit

Re: StringList-->.bat-Datei - Problem mit Umlauten und BOM

Beitrag von Martin V »

Leider werden Umlaute bei Lazarus ständig anders behandelt. Ein paar Erkenntnisse aus meiner Arbeit mit Lazarus und Umlauten:

1. Seit einiger Zeit werden die Quelltexte in Ansi und nicht mehr in UTF8 abgespeichert. Das ist ziemlich wichtig für Strings mit Umlauten in 'Apostrophzeichen'.

2. Wenn man ein lcl .Caption oder ein .Text oder ein Listbox.Add usw. bestücken will, muß man es vorher von Ansi in UTF8 umwandeln. Das mache ich mit OutStr (Code siehe unten).

3. Umgekehrt wenn man Controls auslesen will, verwende ich Utf82Ansi (siehe unten).

4. Die Übergabeparameter (paramstr) und Dateinamen bei findfirst sollten Ansi sein, bin aber nicht 100% sicher, ob das bei allen OS so ist. Das müßte man ausprobieren.

5. Kommandozeile ist eine eigene Geschichte. Bei Windows stammt diese von DOS, und deshalb gilt bis heute in der Windows Kommandozeile der IBM Zeichensatz 850 und nicht der sonst einheitlich gültige Ansi 1252. Bei Unix gilt UTF8. Textausgabe in Kommandozeile siehe unten.

Code: Alles auswählen

 
Kommandozeilen-Ausgabe:
      {$ifdef windows}
      St := ConvertEncoding(St,'cp1252','cp850');
      //oder alternativ eine Umrechnungstabelle siehe unten
      System.write (St);
      {$endif}
      {$ifdef unix}  //incl. MacOSX
      System.write (OutStr(St));
      {$endif}
 
function Utf82Ansi (St : string) : string;
  begin
      {$ifdef unix}
      result := ConvertEncoding(St,EncodingUTF8,'cp1252')
      {$else}
      result := UTF8toAnsi(St)
      {$endif}
  end;
 
function OutStr (St : string) : string;
  begin
      {$ifdef unix}
      result := ConvertEncoding(St,'cp1252',EncodingUTF8)
      {$else}
      result := AnsiToUTF8(St)
      {$endif}
  end;
 
Alternative Umrechnung:
 
type
  tCharTable = Array[#0..#255] Of Char;
var
  OemToAnsiTable, AnsiToOemTable: tCharTable;
  Ch : char;
 
Einmalige Initialisierung:
 
     For Ch := #0 to #255 Do OemToAnsiTable[Ch] := Ch;
 
     OemToAnsiTable[#213] := #128;
     OemToAnsiTable[#128] := #199;
     OemToAnsiTable[#129] := #252;
     OemToAnsiTable[#130] := #233;
     OemToAnsiTable[#131] := #226;
     OemToAnsiTable[#132] := #228;
     OemToAnsiTable[#133] := #224;
     OemToAnsiTable[#134] := #229;
     OemToAnsiTable[#135] := #231;
     OemToAnsiTable[#136] := #234;
     OemToAnsiTable[#137] := #235;
     OemToAnsiTable[#138] := #232;
     OemToAnsiTable[#139] := #239;
     OemToAnsiTable[#140] := #238;
     OemToAnsiTable[#141] := #236;
     OemToAnsiTable[#142] := #196;
     OemToAnsiTable[#143] := #197;
     OemToAnsiTable[#144] := #201;
     OemToAnsiTable[#145] := #230;
     OemToAnsiTable[#146] := #198;
     OemToAnsiTable[#147] := #244;
     OemToAnsiTable[#148] := #246;
     OemToAnsiTable[#149] := #242;
     OemToAnsiTable[#150] := #251;
     OemToAnsiTable[#151] := #249;
     OemToAnsiTable[#152] := #255;
     OemToAnsiTable[#153] := #214;
     OemToAnsiTable[#154] := #220;
     OemToAnsiTable[#155] := #248;
     OemToAnsiTable[#156] := #163;
     OemToAnsiTable[#157] := #216;
     OemToAnsiTable[#158] := #215;
     OemToAnsiTable[#160] := #225;
     OemToAnsiTable[#161] := #237;
     OemToAnsiTable[#162] := #243;
     OemToAnsiTable[#163] := #250;
     OemToAnsiTable[#164] := #241;
     OemToAnsiTable[#165] := #209;
     OemToAnsiTable[#166] := #170;
     OemToAnsiTable[#167] := #186;
     OemToAnsiTable[#168] := #191;
     OemToAnsiTable[#169] := #174;
     OemToAnsiTable[#170] := #172;
     OemToAnsiTable[#171] := #189;
     OemToAnsiTable[#172] := #188;
     OemToAnsiTable[#173] := #161;
     OemToAnsiTable[#174] := #171;
     OemToAnsiTable[#175] := #187;
     OemToAnsiTable[#181] := #193;
     OemToAnsiTable[#182] := #194;
     OemToAnsiTable[#183] := #192;
     OemToAnsiTable[#184] := #169;
     OemToAnsiTable[#190] := #165;
     OemToAnsiTable[#191] := #172;
     OemToAnsiTable[#198] := #227;
     OemToAnsiTable[#199] := #195;
     OemToAnsiTable[#221] := #166;
     OemToAnsiTable[#207] := #164;
     OemToAnsiTable[#208] := #240;
     OemToAnsiTable[#209] := #208;
     OemToAnsiTable[#210] := #202;
     OemToAnsiTable[#211] := #203;
     OemToAnsiTable[#212] := #200;
     OemToAnsiTable[#214] := #205;
     OemToAnsiTable[#215] := #206;
     OemToAnsiTable[#216] := #207;
     OemToAnsiTable[#222] := #204;
     OemToAnsiTable[#224] := #211;
     OemToAnsiTable[#225] := #223;
     OemToAnsiTable[#226] := #212;
     OemToAnsiTable[#227] := #210;
     OemToAnsiTable[#228] := #245;
     OemToAnsiTable[#229] := #213;
     OemToAnsiTable[#230] := #181;
     OemToAnsiTable[#231] := #254;
     OemToAnsiTable[#232] := #222;
     OemToAnsiTable[#233] := #218;
     OemToAnsiTable[#234] := #219;
     OemToAnsiTable[#235] := #217;
     OemToAnsiTable[#236] := #253;
     OemToAnsiTable[#237] := #221;
     OemToAnsiTable[#238] := #175;
     OemToAnsiTable[#239] := #180;
     OemToAnsiTable[#240] := #173;
     OemToAnsiTable[#241] := #177;
     OemToAnsiTable[#243] := #190;
     OemToAnsiTable[#244] := #182;
     OemToAnsiTable[#245] := #167;
     OemToAnsiTable[#246] := #247;
     OemToAnsiTable[#247] := #184;
     OemToAnsiTable[#248] := #176;
     OemToAnsiTable[#249] := #168;
     OemToAnsiTable[#250] := #183;
     OemToAnsiTable[#251] := #185;
     OemToAnsiTable[#252] := #179;
     OemToAnsiTable[#253] := #178;
    {OemToAnsiTable[#254] := #149;
   FillChar (AnsiToOemTable, sizeof(AnsiToOemTable), #32);
   {fill reveserse table}
   For Ch := #0 To #255 Do
     Begin
       If (AnsiToOemTable[OemToAnsiTable[Ch]] = #32) Or
          (AnsiToOemTable[OemToAnsiTable[Ch]] = OemToAnsiTable[Ch])
         Then AnsiToOemTable[OemToAnsiTable[Ch]] := Ch;
     End;
   AnsiToOemTable[#130] := #39; AnsiToOemTable[#146] := #39;
 
   AnsiToOemTable[#132] := '"';
   AnsiToOemTable[#147] := '"';
 
 

hubblec4
Beiträge: 341
Registriert: Sa 25. Jan 2014, 17:50

Re: StringList-->.bat-Datei - Problem mit Umlauten und BOM

Beitrag von hubblec4 »

Ich bedanke mich für die schnelle Hilfe.

Die Lösung ist in dem Falle folgendes gewesen:

Code: Alles auswählen

ConvertEncoding(St,'utf8','cp850')


Die Pfad und Datei angabe kommt direkt aus Lazarus Komponeten, daher utf8.

Und guterweise ist auch kein BOM mehr in der bat Datei.

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: StringList-->.bat-Datei - Problem mit Umlauten und BOM

Beitrag von theo »

Martin V hat geschrieben:1. Seit einiger Zeit werden die Quelltexte in Ansi und nicht mehr in UTF8 abgespeichert. Das ist ziemlich wichtig für Strings mit Umlauten in 'Apostrophzeichen'.

2. Wenn man ein lcl .Caption oder ein .Text oder ein Listbox.Add usw. bestücken will, muß man es vorher von Ansi in UTF8 umwandeln. Das mache ich mit OutStr (Code siehe unten).

3. Umgekehrt wenn man Controls auslesen will, verwende ich Utf82Ansi (siehe unten).


Wo sind diese "Erkenntnisse" dokumentiert?
Das alles scheint mir extrem unwahrscheinlich. Man "kann" zwar in einer ANSI Codepage speichern, aber seit wann ist das die Standardeinstellung?
Auf Linux sowieso nicht.

Antworten