vbs Variablen dynamisch erzeugen

ghostadmin

Grand Admiral Special
Mitglied seit
11.11.2001
Beiträge
25.179
Renomée
184
Standort
Dahoam Studios
Ich würde gerne bei einem .vbs Script einige Variablen dynamisch erzeugen, dass funktioniert glaube ich nur über Array und dort einen Hexwert speichern. Wenn der Hexwert von 0-9 ist dann soll er 00-09 draus machen. Ich bekomme mit dem Code unten allerdings immer einen Typenkonflikt! Was läuft falsch?

Code:
Set re = new regexp
re.Pattern = "^\d$"
dim arrvendor(11)
for n=7 to 11
arrvendor(n) = Hex(arrVendorSpecific(n))
if re.Test(arrvendor(n)) Then
arrvendor(n) = "0" & arrvendor(n)
End If
next

oder

Code:
Set objRegExpr = New regexp
objRegExpr.Pattern = "^\d$"
for n=7 to 11
set colmatches = objRegExpr.Execute(arrVendorSpecific(n))
arrvendor(n) = Hex(arrVendorSpecific(n))
For Each objMatch in colMatches
arrvendor(n) = "0" & arrvendor(n)
Next
Next
 
...
Ich bekomme mit dem Code unten allerdings immer einen Typenkonflikt! Was läuft falsch?

Code:
...
arrvendor(n) = Hex(arrVendorSpecific(n))
...
Code:
...
arrvendor(n) = Hex(arrVendorSpecific(n))
...


Im ersten Codeschnippsel vergisst du 'arrVendorSpecific' zu definieren. Im zweiten vergisst du 'arrvendor' zu definieren.
 
Sollte nicht die Kovertierung mit Hex() schon den gewünschten Effekt haben (ein Byte ist immer ein Byte, und 0x09 ist immer 0x09)? Für die Ausgabe müsstest Du den Hex-Wert wieder in einen Chr-Wert konvertieren.
 
Nein, das gibt leider nur z.B. 9->9 aus nach der Umwandlung nach Hex statt 09. Beim Hex Command habe ich auch keine Parameter gesehen die die Ausgabe ändern.

Es geht um das auslesen der Smartparameter die in mehreren Spalten als Dezimalwert gespeichert sind. Diese müssen erst einzeln in Hex umgewandelt werden, dann werden die Hexwerte aller Spalten als String zusammengesteckt und anschließend kann man daraus wieder nen Dezimalwert machen.

Das Problem was ich habe das also z.B. nicht 801A801A9 angezeigt wird sondern 81A81A9 weil die Nuller fehlen.

Ich habe auch schon überall ein CStr davor gesetzt damit es als String gespeichert wird aber das brachte auch nichts.

Ohne For würde es so auch einwandfrei funktionieren:
Code:
Set re = new regexp
				re.Pattern = "^\d$"
				
				arrvendor7 = Hex(arrVendorSpecific(7))
				if re.Test(arrvendor7) Then
					arrvendor7 = "0" & arrvendor7
				End If
 
Zuletzt bearbeitet:
Sorry, aber da ist VBS scheinbar total behindert was die Datentypen angeht. Meine Erfahrung damit ist schon zu lange her um Dir auf Anhieb weiter zu helfen, sagt mir aber Du solltest vielleicht eine Sprache mit besserer Datentyp-Behandlung suchen.
 
Kategorie Hobbyentwickler. Ist nicht schön aber funktioniert.
daran liegt es nicht
Hast du es ausprobiert?

Wenn man nicht genau weiß unter welchen Bedingungen ->
... Variablen dynamisch erzeugen, dass funktioniert glaube ich nur über Array ...
<-
das funktioniert.
Dann solltest du nur mal zum Spass die Definition einfügen.
Im ersten Codeschnippsel vergisst du 'arrVendorSpecific' zu definieren. Im zweiten vergisst du 'arrvendor' zu definieren.


Code:
...
for n=7 to 11
arrvendor(n) = Hex(arrVendorSpecific(n))
...
Code:
...
for n=7 to 11
...
arrvendor(n) = Hex(arrVendorSpecific(n))
Überlege dir mal was die dynamische Speicherallokation hier machen soll. Gibt es einen ArrayLength default?
Was passiert beim 1. Schleifendurchlauf ... beim x. Schleifendurchlauf?
Falls tatsächlich neu allokiert wird wird der vorherige Inhalt kopiert? Oder wird das Array tatsächlich dynamisch vergrößert?
 
Ich brauche keine Fragen, ich brauche Antworten.
Ich versuch es mal damit, auch wenn ich deine Aufgabenstellung noch nicht völlig klar begriffen habe.
Irgendwie seien arrVendorSpecific irgendwelche Zahlen (Zahlentyp unbekannt, Zahlenbereich unbekannt) die Spaltenweise angegeben wurden.
Die Zahlen sollen in Hexadezimalzeichenfolgen umgewandelt werden. Falls der Hexcode einer einzelnen Zahl einstellig ist soll eine 0 vorne angefügt werden.
Die einzelnen Hexadezimalzahlen sollen ohne Trennzeichen zu einer Zeichenfolge zusammen gefügt werden.
Ich habe für die unbekannten Angaben ein paar annahmen getroffen, so dass der code nicht zu Umfangreich wird.
Hoffe es klappt und schönes Wochenende! ;-)
Code:
Dim ResultString, myRegExp
Set myRegExp = New RegExp
myRegExp.Global = True
myRegExp.Pattern = "^([0-9a-fA-F]{1}?)$"

arrVendorSpecific = Array(8,1,168,1,169)
Dim arrVendor()
ReDim arrVendor(UBound(arrVendorSpecific))
I = 0
For Each num In arrVendorSpecific
 arrVendor(I) = myRegExp.Replace(Hex(num), "0$1")
 I = I + 1
Next
MsgBox Join(arrVendor,"")
 
Da ich auch gerade dieses check_smartwmi entdeckt habe und das für mich angepasst habe (Übersetzung in AutoIt sowie kompletter Umbau unter Nutzung von Arrays, wie es sich gehört und ein paar kleine Erweiterungen), kann ich dazu etwas beisteuern: Diese Umwandlung in Hex ist IMO überflüssig. Es genügt völlig, den Wert aus der letzten Spalte mit 256 zu multiplizieren und den der vorletzten Spalte zu addieren. Mal ein Code-Beispiel (ohne jeglichen Anspruch auf syntaktische Korrektheit, denn VBS is nix für mich):
Code:
readerrorrate = arrVendorSpecific(i9)*256 + arrVendorSpecific(i8)
Diese Vorgehensweise hat zudem den unglaublichen Vorteil, dass das Skript auf einmal die Werte korrekt ausgibt (unter Vergleich mit diversen SMART-Programmen) und die Werte auch nicht mehr hin- und herspringen; die beiden Sachen sind mir nämlich sofort aufgefallen, als ich das Skript das erste Mal gestartet habe. Dass es nebenbei noch den Code erheblich vereinfacht statt zu verkomplizieren, ist ebenfalls ganz nett.

MfG Dalai
 
Zuletzt bearbeitet:
Ich hab die Berechnung mittlerweile auch komplett geändert. Zumindest hoffe ich das die Ausgabe von Crystaldiskinfo korrekt ist.

wmismart.exe gibt z.B. aus bei ID3: 144,1,169,1,8 jeweils dec = hex 90,01,A9,01,08
Ausgabe Crystaldiskinfo: 000801A90190 = 34387591568

Gut dann könnte man das Hexzeug weglassen wenn man einfach 16^2, 16^3 etc. nimmt
 
Ach jetzt verstehe ich erst was hier mit SMART gemeint war. :-)
Ich dachte ständig es geht um irgendwelchen Müll von einer einer Smartcard.
 
hmm also ich hab noch mal bißchen rumprobiert, dass mit dem 16^2 und 16^3 etc. funktioniert wohl denke ich auch nur wenn die Zahlen einstellig sind.

Beispiel: 15 hexadezimal entspricht z. B. 21 dezimal (1*16^1+5*16^0)
 
Schau dir mal dieses AutoIt-Skript an (stammt nicht von mir), speziell Zeilen 288 bis 292. Es sind nur die beiden letzten Spalten des Arrays relevant, und natürlich ist es völlig egal, wieviele Stellen diese Zahlen haben. In Hex liegen davon übrigens keine vor, jedenfalls ist es mir noch nicht begegnet; liegt ggf. daran, dass das in der Datenstruktur des WMI schon in Dezimal umgerechnet wurde.

MfG Dalai
 
Da ist halt die Frage, was ist richtig. Die einen Tools rechnen so, die anderen so. Ist im Grunde eh nur ein Schönheitsfehler denn im Grunde sind die Fehler bereits bei einer einzigen Spalte schon kritisch sobald > 0.
Smartctl scheint oft auch nur 2 Spalten zu nehmen (zumindest bei ID3,194) während es bei den Windows Tools fast alle sind.
Während ich bei smartctl aber auch eine Disk habe die 810725 load cycles hat, mit nur 2 Spalten kommt man nicht auf einen so hohen Wert.
Bei Temperatur dagegen reicht schon eine einzige Spalte.
Sind aber übrigens nicht die 2 letzten Spalten sondern die 8. und 9. von 12.
 
Zuletzt bearbeitet:
Da ist halt die Frage, was ist richtig. Die einen Tools rechnen so, die anderen so. Ist im Grunde eh nur ein Schönheitsfehler denn im Grunde sind die Fehler bereits bei einer einzigen Spalte schon kritisch sobald > 0.
Naja, es ist schonmal kein Schönheitsfehler, wenn der Wert eines Attributs zwischen ganz hohen und niedrigen Zahlen hin- und her springt. Und nein, es sind zwar einige Attribute kritisch, wenn größer 0, aber bei Weitem nicht alle; bei Write Error Rate und UDMA CRC ist es z.B. nicht notwendigerweise kritisch (gerade Seagate-Platten haben oft hohe UDMA CRCs, laufen aber dennoch einwandfrei).

Sind aber übrigens nicht die 2 letzten Spalten sondern die 8. und 9. von 12.
Ups, stimmt.
 
Hab oben nochmal was editiert das es nicht immer nur 2 Spalten sein können.
Also ich kenne zumindest keinen Raw Wert wo man einen Alarm setzen könnte wenn der Wert von 100000 auf 20000 steigt, dafür gibts die normalized Values (welche aber auch nur bei bestimmten IDs wichtig sind).

CRC sind eigentlich Kabelfehler die behoben werden konnten, sollten aber trotzdem eigentlich nicht auftauchen.
Write Error Rate ID200 sollte es doch eigentlich nur bei Fujitsu geben und ist kritisch?

Mit smartctl kann man sich auch die Werte anzeigen lassen aus denen der angezeigte Wert errechnet wird z.B.
smartctl -a -v 193,raw8 bringt bei mir:
0 0 0 12 94 229 = C 5E E5 = 810725

also 12 x 65536 + 94 x 256 + 229
 
Zuletzt bearbeitet:
CRC sind eigentlich Kabelfehler die behoben werden konnten, sollten aber trotzdem eigentlich nicht auftauchen.
Ich werde nochmal genau nachschauen morgen; hab momentan keine Seagate griffbereit. Ich meine mich aber zu erinnern, dass meine frühere HDD im Arbeitsrechner (Seagate 7200.11 mit 500 GB) immer hohe UDMA CRC Werte hatte, aber trotzdem einwandfrei lief. Will nicht ausschließen, dass hier ein anderes Attribut einen hohen Wert hatte (ich werd auch langsam alt ;D).

Write Error Rate ID200 sollte es doch eigentlich nur bei Fujitsu geben und ist kritisch?
Meine Fujitsu im Laptop hat relativ hohe Werte (momentan 22085), funktioniert aber seit dem Einbau einwandfrei (bislang 376 Betriebsstunden, 525 Power Cycles & 2806 Load Cycles).

Hier mal zusammenfassend ein Bild meiner Fujitsu im Laptop, auf dem man sehr gut sieht, dass auch die üblichen Tools teilweise absoluten Schrott anzeigen:

Zum Vergleich das von mir umgebaute AutoIt-Skript:

Das "Raw" ist nicht so ganz ernstzunehmen, denn die Werte sind ja bereits berechnet. Außerdem werden analog zu oben verlinktem AutoIt-Skript nur bestimmte Werte errechnet (die die "Count" enthalten oder eine bestimmte ID haben), die anderen werden auf 0 gesetzt. Der Wert von ID195/C3 schwankt übrigens bei dieser HDD nach oben und unten, wie die Platte gerade Lust hat, unabhängig vom Programm.

MfG Dalai
 
Und was zeigt smartctl an? Insbesondere mit den oben erwähnten -v Parametern? Woher weißt du welche Werte richtig sind?

Einige Hersteller halten sich auch schlicht nicht an die Normen siehe z.B.:
http://smartmontools.sourceforge.net/man/smartctl.8.html

Wie gesagt, das bei allen IDs nur 2 Felder verwendet werden, ist nicht möglich. Und wenn die Werte dann höher sind als 999 * 256 + 999 dann fängt es wieder bei 0 an!

Und dein Crystaldiskview ist auch extrem alt und nicht auf Hexanzeige eingestellt.
 
Zuletzt bearbeitet:
Und was zeigt smartctl an? Insbesondere mit den oben erwähnten -v Parametern?
Muss ich nachschauen.

Woher weißt du welche Werte richtig sind?
Nun, Werte, die über 2^32 hinausgehen, sind unsinnig, oder nicht?

Und dein Crystaldiskview ist auch extrem alt und nicht auf Hexanzeige eingestellt.
Ich weiß, das ist Absicht (alle Versionen ab 4.x verwenden nicht abschaltbares ClearType). Es spielt auch keine Rolle, ob nun Hex oder Dez angezeigt wird, nur die Darstellung ist eine andere - aber der Mensch liest aber nunmal kein Hex sondern Dez (oder vergleichst du Hex direkt mit Dez inkl. Umrechnung im Kopf?).

Ergänzung: CrystalDiskInfo 5.6.2 zeigt genau dieselben Mondwerte an (HD Tune übrigens ebenfalls), insofern ist das egal - ich dachte mir das bereits, denn die Platte ist ja nun auch nicht gerade neu.

MfG Dalai
 
Zuletzt bearbeitet:
Nun, Werte, die über 2^32 hinausgehen, sind unsinnig, oder nicht?

wie kommst du auf 2^32 ?

In den Spalten stehen doch imho nur Werte bis FF = 255 und 255*256+256 ist jetzt nicht gerade besonders hoch.

Hast auch vielleicht mein Posting oben nicht richtig gelesen.
smartctl zeigt bei mir auf ID193 den Wert: 810725
mit -v 193,raw8: 0 0 0 12 94 229
Und smartctl vertraue ich bei den Werten noch am ehesten.

Bei Crystaldiskinfo könnte sich ja auch die Errechnung in den Versionen geändert haben, nur um das auszuschließen (6 ist aktuell)
 
wie kommst du auf 2^32 ?
Die Werte, die CrystalDiskInfo und übrigens auch smartmontools ausgeben, gehen darüber hinaus. Ich hätte auch 1 Mio schreiben können, das spielt keine Rolle. Der Punkt ist, dass absurd hohe Werte Unfug sind. Hier mal noch ein Screenshot der Fujitsu mit smartmontools:

(Die Werte der Seagate werde ich nachreichen, ich hab es nicht vergessen.)

MfG Dalai
 
Siehst du, Smartctl zeigt auch Werte über 65k an.
Das Autoit script ist genauso wenig korrekt wenn es überall nur 2 Spalten verwendet wie Crystaldiskinfo etc. das überall alle 5 verwendet.
Die Wahrheit liegt dazwischen und man muss jedes Attribut individuell behandeln!
Und man sieht auch das Fujitsu sich nicht um Standards schert z.B. bei POH. Wobei ich bei deiner Disk eher die Anzeige in Minuten vermute.

btw. kannst du mir mal von smartctl die 5 Felder von ID5 und 196 geben? Da scheinen wohl noch Hidden Remaps gespeichert zu sein?
 
Zuletzt bearbeitet:
Siehst du, Smartctl zeigt auch Werte über 65k an.
Ja eben. Was sagen solche Werte denn aus? Dass über 190k Fehler beim Lesen passiert sind (Read Error Rate)? Wohl kaum.

Das Autoit script ist genauso wenig korrekt wenn es überall nur 2 Spalten verwendet wie Crystaldiskinfo etc. das überall alle 5 verwendet.
Ja, hab ich mittlerweile auch gemerkt. Wobei es schon nicht falsch ist, sich auf die wesentlichen Attribute zu konzentrieren.

Die Wahrheit liegt dazwischen und man muss jedes Attribut individuell behandeln!
Ja, und das ist recht einfach, wenn man ordentliche Arrays verwendet, wie ich das mittlerweile getan habe ;D.

Und man sieht auch das Fujitsu sich nicht um Standards schert z.B. bei POH. Wobei ich bei deiner Disk eher die Anzeige in Minuten vermute.
Es gibt bei SMART keine Standards, jedenfalls nicht in dem Sinne. Dass die meisten Hersteller in POH (ID9) dennoch Stunden angeben, ist halt so, aber nirgendwo vorgegeben, weshalb Fujitsu eben einen eigenen Weg geht und Sekunden-Intervalle benutzt.

btw. kannst du mir mal von smartctl die 5 Felder von ID5 und 196 geben? Da scheinen wohl noch Hidden Remaps gespeichert zu sein?
There you go:


Hier die versprochenen Werte der ST3500320AS:
Von links nach rechts: CrystalDiskInfo, HD Tune, check_smartwmi2 und smartmontools:

Das check_smartwmi2 ist inzwischen etwas überarbeitet, so dass für einige Attribute alle 5 Spalten benutzt werden; ich hab die Attribute mit den absurd hohen Werten einfach von der Berechnung mit den weiteren Spalten ausgenommen. Damit komme ich sowohl an die (sinnvollen) Werte von CrystalDiskInfo als auch die der smartmontools ran. Übrigens sind die weiteren Spalten nicht 16^n+1 sondern 16^n+2, also konkret 16^4, 16^6 und 16^8.

Ergänzung: Ich hatte das offenbar doch falsch in Erinnerung: die Seagate hat nicht bei UDMA CRC absurd hohe Werte sondern bei Hardware ECC Recovered, Temperature und Command Timeout, Seek Error Rate und Read Error Rate.

MfG Dalai
 
Zuletzt bearbeitet:
Zurück
Oben Unten