afankhauser
Goto Top

Binarys mit vbs lesen und schreiben

(genauer gehts um ne HTA)

ich möchte eigentlich eine Datei (.ico) in mein script einbetten. Nun habe ich aber das problem, dass all meine Versuche daran scheitern, dass die NULen nicht eingelesen bzw. geschrieben werden.

habe auch einmal versucht den ganzen Quelltext als String einzubetten. Funktioniert zwar soweit. Aber in der Ausgabe fehlen natürlich wieder die NULen face-sad

hier noch der betroffene Ausschnitt aus Meinem Script
pfad1 = "C:\meinPfad\main.ico"  
set d = fso.opentextfile(pfad1, 2, 1)
d.write ""  '<-- Was soll ich hier blos machen?  
d.close
set d = Nothing

Habs auch schon mit einlesen und direkt schreiben versucht --> wieder negativ

ist sowas überhaupt möglich?
Oder könnte man diese Dateien auch irgendwie "binär" öffnen?

Content-Key: 129914

Url: https://administrator.de/contentid/129914

Ausgedruckt am: 28.03.2024 um 18:03 Uhr

Mitglied: 76109
76109 21.11.2009 um 11:33:26 Uhr
Goto Top
Hallo aFrankhauser!

Wenn Du mit FileSystemObject Binary-Dateien lesen und schreiben willst, dann müssen die Zeichen einzeln gelesen und geschrieben werden.

Beispiel Ico-Datei Binary einlesen und wieder Schreiben (Test.Bin), zusätzlich Hex-Dump schreiben (Test.Txt) in etwa so:
Const IcoPath = "X:\Test\Test.Ico"  
Const BinPath = "X:\Test\Test.Bin"  
Const HexPath = "X:\Test\Test.Txt"  

Dim Fso, IcoFile, BinFile, HexFile, BinText, HexText, c, h, i
    
Set Fso = CreateObject("Scripting.FileSystemObject")  

Set IcoFile = Fso.OpenTextFile(IcoPath)
    
i = 0
    
Do Until IcoFile.AtEndOfStream
    c = IcoFile.Read(1):  BinText = BinText & c
    h = Right("0" & Hex(Asc(c)), 2):  HexText = HexText & h & " "  
    i = i + 1
    If i = 16 Then i = 0:  HexText = HexText & vbCrLf
Loop
    
IcoFile.Close
    
Set BinFile = Fso.CreateTextFile(BinPath)
    
For i = 1 To Len(BinText)
    BinFile.Write Mid(BinText, i, 1)
Next
    
BinFile.Close
    
Set HexFile = Fso.CreateTextFile(HexPath)
    
HexFile.Write HexText
    
HexFile.Close

Gruß Dieter
Mitglied: bastla
bastla 21.11.2009 um 12:20:29 Uhr
Goto Top
@76109
Ich bevorzuge zwar das Einlesen am Stück - also etwa
BinText = IcoFile.ReadAll
For j = 1 To Len(BinText)
    h = Right("0" & Hex(Asc(Mid(BinText, j, 1))), 2):  HexText = HexText & h & " "  
    i = i + 1
    If i = 16 Then i = 0:  HexText = HexText & vbCrLf
Next
aber speziell bei Dateien in der Größe eines .ico-Files wird das wohl kaum einen größeren Unterschied machen ...

[Edit] Wohl doch face-sad - die Hex-Umwandlung erfolgt allerdings noch korrekt - strange ...

Bei Deiner Einlese-Variante sollte es aber zumindest im Gegenzug möglich sein, das Schreiben ohne Schleife abzuwickeln:
BinFile.Write BinText
[/Edit]

Grüße
bastla
Mitglied: 76109
76109 21.11.2009 um 14:00:13 Uhr
Goto Top
Hallo bastla!

Die Hex-Konvertierung stimmt beim Gesamt-Einlesen auch nicht mehr mit der Binary-Datei überein.

Und beim Schreiben am Stück funktioniert es auch nicht face-wink

Gruß Dieter
Mitglied: bastla
bastla 21.11.2009 um 14:55:48 Uhr
Goto Top
@76109
Die Hex-Konvertierung stimmt beim Gesamt-Einlesen auch nicht mehr mit der Binary-Datei überein.
Na dann bin ich ja wieder beruhigt ... face-wink

Das Bearbeiten von Daten mit einem Werkzeug, das nicht dafür gedacht ist, auch noch zwischen Tür und Angel erledigen zu wollen (wie es leider bei meinem Versuch oben der Fall war), ist definitv keine gute Idee face-sad - insofern meinen Kommentar bitte wohlwollend zu ignorieren ...

Grüße
bastla
Mitglied: 76109
76109 21.11.2009 um 15:08:49 Uhr
Goto Top
Hallo bastla!

Naja, ich hatte es ja vorher nach Deiner Methode auch probiert und nach der Verunsicherung durch Dich dann halt nochmal probiertface-smile

Das FileSystemObject ist eben nur für Text-Dateien gedacht.

Gruß Dieter
Mitglied: aFankhauser
aFankhauser 22.11.2009 um 15:47:05 Uhr
Goto Top
@ @76109:

Habe zum testen mal die Pfade angepasst.
ich staunte nicht schlecht als das alles schon beim ersten Versuch klappte. face-smile

Ich versuch jetzt mal die Funktion in mein Script einzubauen und dessen Funktionsweise zu verstehen.

Dank dir für die schnelle - und erst noch äusserst hilfreiche - Antwort
Mitglied: 76109
76109 22.11.2009 um 19:58:00 Uhr
Goto Top
Hallo aFrankhauser!

Zitat von @aFankhauser:
ich staunte nicht schlecht als das alles schon beim ersten Versuch klappte. face-smile
Wow, dann hast es wohl geschafft, die Pfade gleich beim 1. Versuch richtig anzugebenface-smile

Ich versuch jetzt mal die Funktion in mein Script einzubauen und dessen Funktionsweise zu verstehen.
Falls Du noch Fragen hast? Kein Problemface-wink

Gruß Dieter
Mitglied: aFankhauser
aFankhauser 22.11.2009 um 23:36:59 Uhr
Goto Top
Hab das script nun meinen bedürfnissen angepasst. Und habe noch zwei drei Dinge umgebaut. Das Ganze arbeitet nun wie folgt:
script 1:
Set Fso = CreateObject("Scripting.FileSystemObject")  
titel = fso.getBaseName(wscript.scriptname)
input = "C:\mein Pfad\main.ico"  
output = "C:\mein Pfad\temporär Ascii von main.ico.txt"  

'nur zur Sicherheit  
if Not MsgBox("Wirklich ausführen?" & vbLf & "Dateien werden eventuell überschrieben!",32+1,titel)=vbOK Then wscript.quit  

'jetzt gehts los  
set oD1 = fso.openTextFile(input, 1)
set oD2 = fso.openTextFile(output, 2, 1)

Do Until oD1.atEndOfStream
 a1 = oD1.read(1)
 a2 = Asc(a1)
 oD2.write Right("00" & a2, 3)  
loop

MsgBox "Fertig",,titel  
dies ist das vorbereitungsScript. Es schreibt mir die ascii werte aller Zeichen (immer 3-Stellig) direkt aneinander in eine neue Datei.

Dann kann ich den ganzen dateiQuelltext Kopieren, und als String in meinem 2ten Script einfügen.
Script 2 (codeSchnipsel):
'hier den code an "ascCode" zuweisen (Beispiel)  
ascCode = "077097120"  '77 97 120 -->Max  
Const IcoTargetPath = "C:\mein zielPfad\main.ico"  

Set BinFile = Fso.CreateTextFile(IcoTargetPath)

For i = 1 To Len(ascCode) step 3
 a = Mid(ascCode, i, 3)
 BinFile.Write chr(a)
Next

BinFile.Close
set BinFile = Nothing
script 2 liest dann immer 3 Zeichen, und schreibt immer dessen Charakter (Chr()) in die Zieldatei.
So funktionierts wie ich es mir vorgestellt habe.

nun habe ich aber doch noch bedenken...
Was nun wenn ich einmal eine Datei, die zB 10GB gross ist verarbeiten möchte.
werden sooo lange Strings überhaupt gespeichert?
gibt es da eine "obergrenze"?
Mitglied: 76109
76109 23.11.2009 um 10:32:43 Uhr
Goto Top
Hallo aFrankhauser!

Du kannst ja direkt lesen und schreiben und musst nicht mit Strings arbeiten. Diese Methode ist aber auch nur in einem angemessenem Rahmen 10-50 KB gerade noch zu gebrauchen. Bei größeren Dateien kannst Du das vergessen und musst andere Möglichkeiten in Betracht ziehen. Temporäre Batch, sowas in der Art. Eventuell fällt bastla etwas dazu einface-smile

BinToAscii:
    Set oD1 = Fso.OpenTextFile(IcoPath)
    Set oD2 = Fso.CreateTextFile(TxtPath)
    
    Do Until oD1.AtEndOfStream
        oD2.Write Right("00" & Asc(oD1.Read(1)), 3)  
    Loop
    
    oD1.Close:  oD2.Close

AsciiToBin:
    Set oD2 = Fso.OpenTextFile(TxtPath)
    Set oD3 = Fso.CreateTextFile(BinPath)
    
    Do Until oD2.AtEndOfStream
        oD3.Write Chr(CInt(oD2.Read(3)))
    Loop
    
    oD2.Close:  oD3.Close

Gruß Dieter
Mitglied: aFankhauser
aFankhauser 23.11.2009 um 17:52:53 Uhr
Goto Top
Stimmt eigentlich schon.
Mein Ziel ist es aber, ein Installationsprogramm zu schreiben, welches als einzelne Datei funktioniert. (also nicht wie zb auf einer CD, sondern eher wie ein Installer-Paket.)
Aus diesem Grund muss ich alle dateien "includen". (Darum die ZeichenKette)

Als Fan von Freeware, möchte ich Freeware online zur verfügung stellen.
(zwar nur Scripte und eben nicht immer so sinnvolle)

hier noch der Link dorthin: http://www.hiddenalpha.ch/index.php > Downloads (ganz unten in der Navi-Leiste)
Das entsprechende Script wäre dann: Speed-Rechner version 0.2.12
Mitglied: 76109
76109 23.11.2009 um 19:12:16 Uhr
Goto Top
Hallo aFrankhauser!

Also, ich habe Deinen Speedrechner mal getestet und leider festgestellt, dass die Umrechnung nicht stimmt.

Gegeben:
100 Meter
12 Sekunden

Ergebnis = 300 Km/h -- Sollte sein 30 Km/h (Kopfrechnung)

Gruß Dieter
Mitglied: aFankhauser
aFankhauser 23.11.2009 um 20:30:31 Uhr
Goto Top
Zitat von @76109:
Also, ich habe Deinen Speedrechner mal getestet und leider
festgestellt, dass die Umrechnung nicht stimmt.

???????????????????????
versteh ich jetzt nicht. bei mir rechnet er das richtig.
hast du geprüft ob du wirkich keinen Tippfehler drinnhast
(zB. 1000 anstatt 100)
sonst kann ich mir das nicht erklären???
Mitglied: 76109
76109 23.11.2009 um 22:19:40 Uhr
Goto Top
Hallo aFrankhauser!

Also, ich habe es jetzt noch mal eingegeben und er zeigt mir immer noch das gleiche Ergebnis. Allerdings habe ich nur den Online-Rechner getestet.

Gegeben: 100 Meter in 12 Sekunden

Bei m/s = 8,333 stimmt
Bei Km/s = 8,333 stimmt nicht
Bei Km/h = 300 stimt nicht

Gruß Dieter
Mitglied: 76109
76109 24.11.2009 um 09:08:23 Uhr
Goto Top
Hallo aFrankhauser!

Wäre eventuell noch zu überlegen, ob Du anstatt dem 3-stelligen Ascii-Format nicht lieber das 2-stellige Hex-Ascii-Format verwendest. Das spart immerhin 1/3 an Dateigröße.

BinToHexAscii
    Set oD1 = Fso.OpenTextFile(IcoPath)
    Set oD2 = Fso.CreateTextFile(TxtPath)
    
    Do Until oD1.atEndOfStream
        oD2.Write Right("0" & Hex(Asc(oD1.Read(1))), 2)  
    Loop
    
    oD1.Close:  oD2.Close
HexAsciiToBin
    Set oD2 = Fso.OpenTextFile(TxtPath)
    Set oD3 = Fso.CreateTextFile(BinPath)
    
    Do Until oD2.atEndOfStream
        oD3.Write Chr(CInt("&H" & oD2.Read(2)))  
    Loop
    
    oD2.Close:  oD3.Close

Gruß Dieter
Mitglied: aFankhauser
aFankhauser 24.11.2009 um 19:35:56 Uhr
Goto Top
aaha! Da wird mir einiges klar. --> Online
habe auch den mal schnell aktualisiert. Er sollte jetzt stimmen.

Danke für den Hinweis.
Mitglied: 76109
76109 24.11.2009 um 20:00:18 Uhr
Goto Top
Hallo aFrankhauser!

Yep, dass funktioniert jetztface-smile

Sorry, habe leider einen neuen Fehler gefunden (Online)face-sad

Gegeben: 50 m und 6 Sek = 30 Km/h stimmt
Gegeben: 50 m und 5,6 Sek = 3,21.. Km/h stimmt nicht

Gruß Dieter
Mitglied: aFankhauser
aFankhauser 24.11.2009 um 23:50:25 Uhr
Goto Top
???
seh ich jetzt nicht. Bei mir funktionierts wie es sollte (zumindest dein Beispiel)
Mitglied: 76109
76109 25.11.2009 um 05:42:25 Uhr
Goto Top
Ich will ja nicht nerven, aber bisher keine Veränderung (Online).

50m in 5,6 sekunden sind immer noch 3,2142... Km/h anstatt 32,142... Km/h
Mitglied: aFankhauser
aFankhauser 26.11.2009 um 17:50:18 Uhr
Goto Top
versteh ich immer noch nicht.
wo sollte denn der Fehler versteckt sein? hier mal Code mit Kommentare. vielleicht findest du ja was.

der betroffene ScriptTeil:
(wäre VbScript)
Sub geschw_Click
 vS = Replace(document.all.distanz.value,",",".") 'Komma mit Punkt ersetzen  
 vT = Replace(document.all.zeit.value,",",".") 'Komma mit Punkt ersetzen  

 vSType = document.all.distanzType.value    'Einheit der Strecke  
 vTType = document.all.zeitType.value    'Einheit der Zeit  
 vVSType = document.all.geschwType1.value    'StreckenEinheit der Geschwindigkeit  
 vVTType = document.all.geschwType2.value    'ZeitEinheit der Geschwindigkeit  

'überprüfung  
 if vS = "" Then MsgBox "Keine Distanz angegeben",48,"Fehler" : document.all.distanz.select() : Exit Sub  
 if vT = "" Then MsgBox "Keine Zeit angegeben",48,"Fehler" : document.all.zeit.select() : Exit Sub  
 if Not IsNumeric(vS) Then MsgBox """" & vS & """ ist keine gültige Zahl",48,"Fehler" : document.all.distanz.select() : Exit Sub  
 if Not IsNumeric(vT) Then MsgBox """" & vT & """ ist keine gültige Zahl",48,"Fehler" : document.all.zeit.select() : Exit Sub  

'ausrechnung  
 vS = (vS * vSType)    'Strecke in [Meter] umrechnen  
 vT = (vT * vTType)   'Zeit in [Sekunden] umrechnen  
 vV = (vS / vT)    'Geschw. in [Meter pro Sekunde] rechnen  
 vV = (vV / vVSType)    'Geschw. in [Strecke pro Sekunde] umrechnen  
 vV = (vV * vVTType)    'Geschw. in [Strecke pro Zeit] umrechnen  
 document.all.geschw.value = vV    'Ergebnis ausgeben  
End Sub

und hier der Body:
<table>
 <tr>
  <td>
   <a href="#" onclick="vbscript:distanz_Click">Distanz:</a>  
  </td>
  <td>
   <input name="distanz" type="text" tabindex="04" maxlength="6" width="7">  
  </td>
  <td>
   <select name="distanzType" tabindex="05">  
    <option value="0.001">Millimeter</option>  
    <option value="0.01">Zentimeter</option>  
    <option value="0.1">Dezimeter</option>  
    <option value="1" selected>Meter</option>  
    <option value="1000">Kilometer</option>  
    <option value="299797000">Lichtsekunden</option>  
    <option value="17987820000">Lichtminuten</option>  
    <option value="1079269200000">Lichtstunden</option>  
    <option value="9460873807200000">Lichtjahre</option>  
   </select>
  </td></tr>
 <tr>
  <td>
   <a href="#" onclick="vbscript:zeit_Click">Zeit:</a>  
  </td><td>
   <input type="text" name="zeit" width="7" maxlength="6" tabindex="06">  
  </td><td>
   <select name="zeitType" tabindex="07">  
    <option value="1">Sekunden</option>  
    <option value="60">Minuten</option>  
    <option value="3600">Stunden</option>  
    <option value="43200">Tage (12h)</option>  
    <option value="86400">Tage (24h)</option>  
    <option value="31557600">Jahre</option>  
   </select>
  </td></tr><tr><td>
   <a href="#" onclick="vbscript:geschw_Click">Geschwindigkeit:</a>  
  </td><td>
   <input type="text" name="geschw" value="" maxlength="16" tabindex="09">  
  </td><td>
   <select name="geschwType1" tabindex="10">  
    <option value="0.001">mm</option>  
    <option value="0.01">cm</option>  
    <option value="0.1">dm</option>  
    <option value="1">m</option>  
    <option value="1000" selected>km</option>  
    <option value="299797000">Ls</option>  
    <option value="17987820000">Lmin</option>  
    <option value="1079269200000">Lh</option>  
    <option value="9460873807200000">Lj</option>  
   </select> /
   <select name="geschwType2" tabindex="10">  
    <option value="1">s</option>  
    <option value="60">min</option>  
    <option value="3600" selected>h</option>  
    <option value="43200">Tag (12h)</option>  
    <option value="86400">Tag (24h)</option>  
    <option value="31557600">Jahr</option>  
   </select>
  </td>
 </tr>
</table>
die Zahlen, welche in den value stehen, sind die UmrechnungsFaktoren.
zB:
1km = 1000m
1h = 3600s
usw.
Mitglied: 76109
76109 26.11.2009 um 19:50:05 Uhr
Goto Top
Hallo aFrankhauser!

Der Fehler liegt im VB-Script in Zeile 2 und 3face-wink

Zahl: Variable = 5.6
Text: Variable = "5,6" Bei Konvertierung in "5.6" wird daraus 56

Die Punkt-Konvertierung braucht man nur bei englischen Zahlenwerten, weil die anstatt wie wir 5,6 den Wert 5.6 schreiben.

Eine entsprechende Konvertierung in Komma, kannst Du machen, wenn Du auch die Schreibform mit Punkt zulassen willst.

Gruß Dieter