Hamster 2.1.0.11 l�uft als Service unter Windows Vista
Hier der Trace, ich habe den API-Kommentar zur besseren �bersicht wieder
eingef�gt:
2009.11.18 21:12:11 I {340} [FallBack.hsc:15]: varset ($buf1, "01234567890123456789012345678901234567890123456789")
2009.11.18 21:12:11 I {340} [FallBack.hsc:16]: varset ($buf2, "01234567890123456789012345678901234567890123456789")
# void WINAPI GetSystemTime(__out LPSYSTEMTIME lpSystemTime)
# lpSystemTime [out]
# A pointer to a SYSTEMTIME structure to receive the current system date and time.
# The lpSystemTime parameter must not be NULL.
# Using NULL will result in an access violation.
2009.11.18 21:12:11 I {340} [FallBack.hsc:23]: varset ($ApiGetSystemTime, "kernel32.dll|GetSystemTime|v|n")
# BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)
# lpPerformanceCount [out]
# Pointer to a variable that receives the current performance-counter value, in counts.
2009.11.18 21:12:11 I {340} [FallBack.hsc:29]: varset ($ApiQueryPerformanceCounter, "kernel32.dll|QueryPerformanceCounter|n|n")
2009.11.18 21:12:11 I {340} [FallBack.hsc:31]: var ($lastError1, $lastError2, $rc1, $rc2)
2009.11.18 21:12:11 I {340} [FallBack.hsc:33]: $rc2 = DLLCall ($ApiQueryPerformanceCounter, MemVarPtr ($buf2))
2009.11.18 21:12:11 d {340} DynDll: Load temp. library kernel32.dll
2009.11.18 21:12:11 d {340} DynDll: Free temp. library kernel32.dll
2009.11.18 21:12:11 I {340} [FallBack.hsc:34]: $lastError2 = DLLLastError
2009.11.18 21:12:11 I {340} [FallBack.hsc:36]: DLLCall ($ApiGetSystemTime, MemVarPtr ($buf1))
2009.11.18 21:12:11 d {340} DynDll: Load temp. library kernel32.dll
2009.11.18 21:12:11 d {340} DynDll: Free temp. library kernel32.dll
2009.11.18 21:12:11 I {340} [FallBack.hsc:37]: $lastError1 = DLLLastError
2009.11.18 21:12:11 I {340} [FallBack.hsc:39]: dump
2009.11.18 21:12:11 I {340} > dump follows:
2009.11.18 21:12:11 I {340} > .context: (global)
2009.11.18 21:12:11 I {340} > .var: ->$ApiGetSystemTime="kernel32.dll|GetSystemTime|v|n"
2009.11.18 21:12:11 I {340} > .var: ->$ApiQueryPerformanceCounter="kernel32.dll|QueryPerformanceCounter|n|n"
2009.11.18 21:12:11 I {340} > .var: ->$buf1="01234567890123456789012345678901234567890123456789"
2009.11.18 21:12:11 I {340} > .var: ->$buf2="2�� B 890123456789012345678901234567890123456789"
2009.11.18 21:12:11 I {340} > .var: ->$lastError1=40001
2009.11.18 21:12:11 I {340} > .var: ->$lastError2=0
2009.11.18 21:12:11 I {340} > .var: ->$rc1=(unassigned)
2009.11.18 21:12:11 I {340} > .var: ->$rc2=1
Wie zu erkennen ist, wird buf2 von QueryPerformanceCounter bef�llt,
buf1 aber nicht von GetSystemTime.
Zum zugeh�rigen Fehler 40001 finde ich nur sql-bezogenes.
Irgendwelche Hinweise von Auskennern, was ich da verkehrt mache?
Eins noch: wenn das Script ohne Debug l�uft, ist auch Lasterror2 40001,
obwohl die Funktion unver�ndert 1 (OK) zur�ckgibt.
--
lg georg
Hamster 2.1.0.11 l�uft als Service unter Windows Vista
Hier der Trace, ich habe den API-Kommentar zur besseren �bersicht wieder
eingef�gt:
>21:12:11 I {340} [FallBack.hsc:15]: varset ($buf1, "01234567890123456789012345678901234567890123456789")
>21:12:11 I {340} [FallBack.hsc:16]: varset ($buf2, "01234567890123456789012345678901234567890123456789")
> # void WINAPI GetSystemTime(__out LPSYSTEMTIME lpSystemTime)
> # lpSystemTime [out]
> # A pointer to a SYSTEMTIME structure to receive the current system date and time.
> # The lpSystemTime parameter must not be NULL.
> # Using NULL will result in an access violation.
>21:12:11 I {340} [FallBack.hsc:23]: varset ($ApiGetSystemTime, "kernel32.dll|GetSystemTime|v|n")
> # BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)
> # lpPerformanceCount [out]
> # Pointer to a variable that receives the current performance-counter value, in counts.
>21:12:11 I {340} [FallBack.hsc:29]: varset ($ApiQueryPerformanceCounter, "kernel32.dll|QueryPerformanceCounter|n|n")
>21:12:11 I {340} [FallBack.hsc:31]: var ($lastError1, $lastError2, $rc1, $rc2)
>21:12:11 I {340} [FallBack.hsc:33]: $rc2 = DLLCall ($ApiQueryPerformanceCounter, MemVarPtr ($buf2))
>21:12:11 d {340} DynDll: Load temp. library kernel32.dll
>21:12:11 d {340} DynDll: Free temp. library kernel32.dll
>21:12:11 I {340} [FallBack.hsc:34]: $lastError2 = DLLLastError
>21:12:11 I {340} [FallBack.hsc:36]: DLLCall ($ApiGetSystemTime, MemVarPtr ($buf1))
>21:12:11 d {340} DynDll: Load temp. library kernel32.dll
>21:12:11 d {340} DynDll: Free temp. library kernel32.dll
>21:12:11 I {340} [FallBack.hsc:37]: $lastError1 = DLLLastError
>21:12:11 I {340} [FallBack.hsc:39]: dump
>21:12:11 I {340} > dump follows:
>21:12:11 I {340} > .context: (global)
>21:12:11 I {340} > .var: ->$ApiGetSystemTime="kernel32.dll|GetSystemTime|v|n"
>21:12:11 I {340} > .var: ->$ApiQueryPerformanceCounter="kernel32.dll|QueryPerformanceCounter|n|n"
>21:12:11 I {340} > .var: ->$buf1="01234567890123456789012345678901234567890123456789"
>21:12:11 I {340} > .var: ->$buf2="2�� B 890123456789012345678901234567890123456789"
>21:12:11 I {340} > .var: ->$lastError1=40001
>21:12:11 I {340} > .var: ->$lastError2=0
>21:12:11 I {340} > .var: ->$rc1=(unassigned)
> Hi, ich experimentiere ein bisschen mit Scripten und deren Performance und
Erz�hl mehr davon. ;-)
> Jetzt will ich auch noch die Funktion GetSystemTime verwenden, doch die
> liefert mir keinen Output, obwohl laut Beschreibung in beide Funktionen ein
> Pointer auf einen Ausgabebereich �bergeben wird.
>> 21:12:11 I {340} [FallBack.hsc:23]: varset ($ApiGetSystemTime, "kernel32.dll|GetSystemTime|v|n")
Der Hamster unterst�tzt keine 'void'-Funktionen. Benutze einfach:
"kernel32.dll|GetSystemTime|n|n"
Damit sollte es funktionieren.
> Zum zugeh�rigen Fehler 40001 finde ich nur sql-bezogenes.
Das ist eine interne Fehlernummer vom Hamster.
> Eins noch: wenn das Script ohne Debug l�uft, ist auch Lasterror2 40001,
> obwohl die Funktion unver�ndert 1 (OK) zur�ckgibt.
Welche 1?
"->$rc2=1" stammt von:
| $rc2 = DLLCall ($ApiQueryPerformanceCounter, MemVarPtr ($buf2))
Und $rc1 wird nicht gesetzt.
HTH
Alfred
--
09881.7
> Es schrieb einmal Georg Gruber:
> Der Hamster unterstützt keine 'void'-Funktionen. Benutze einfach:
Ahja.
Da les ich _einmal_ die Doku und schon bin ich in den Dings gekniffen ;-)
| Ergebnis_Typ muss den Typ des Rügabewerte der Funktion
| widerspiegeln. Folgende Werte sind hierfür zulässig:
|
| n=Integer
| v=kein Rückgabewert vorhanden
> "kernel32.dll|GetSystemTime|n|n"
>
> Damit sollte es funktionieren.
Indeed. Danke!
>> Eins noch: wenn das Script ohne Debug läuft, ist auch Lasterror2 40001,
>> obwohl die Funktion unverändert 1 (OK) zurückgibt.
>
> Welche 1?
> "->$rc2=1" stammt von:
>
>| $rc2 = DLLCall ($ApiQueryPerformanceCounter, MemVarPtr ($buf2))
Genau, aber vom dazugehörenden
$lastError2 = DLLLastError
war nicht zu erwarten, dass es seinen Inhalt abhängig vom trace-Status
ändert.
Ich habe es nochmal ohne Aufruf der void-Funktion ausprobiert, der Effekt
bleibt prinzipiell gleich:
Ohne Trace:
| 09:58:00 Sys {c00} Starte Skript: FallBack.hsc, Warten=0
| 09:58:00 Sys {1840} {script FallBack.hsc} Start
| 09:58:00 I {1840} > dump follows:
| 09:58:00 I {1840} > .context: (global)
| 09:58:00 I {1840} > .var: ->$ApiGetLocalTime="kernel32.dll|GetLocalTime|n|n"
| 09:58:00 I {1840} > .var: ->$ApiQueryPerformanceCounter="kernel32.dll|QueryPerformanceCounter|n|n"
| 09:58:00 I {1840} > .var: ->$buf1="01234567890123456789012345678901234567890123456789"
| 09:58:00 I {1840} > .var: ->$buf2="¾&·Œ// 890123456789012345678901234567890123456789"
| 09:58:00 I {1840} > .var: ->$lastError1=(unassigned)
| 09:58:00 I {1840} > .var: ->$lastError2=2
*************
Win32 - System Error Codes
2 The system cannot find the file
specified. ERROR_FILE_NOT_FOUND
WasfürnFile, passt ja alles?
| 09:58:00 I {1840} > .var: ->$rc1=(unassigned)
| 09:58:00 I {1840} > .var: ->$rc2=1
| 09:58:00 Sys {1840} {script FallBack.hsc} Ende
| 09:58:00 Sys {874} Skript C:\Users\Public\Hamster-Daten\Scripts and Modules\FallBack.hsc beendet.
Mit Trace:
| 09:58:20 Sys {c00} Starte Skript: FallBack.hsc, Warten=0
| 09:58:20 Sys {aa8} {script FallBack.hsc} Start
| 09:58:20 I {aa8} [FallBack.hsc:18]: varset ($buf1, "01234567890123456789012345678901234567890123456789")
| 09:58:20 I {aa8} [FallBack.hsc:19]: varset ($buf2, "01234567890123456789012345678901234567890123456789")
| 09:58:20 I {aa8} [FallBack.hsc:26]: varset ($ApiGetLocalTime, "kernel32.dll|GetLocalTime|n|n")
| 09:58:20 I {aa8} [FallBack.hsc:32]: varset ($ApiQueryPerformanceCounter, "kernel32.dll|QueryPerformanceCounter|n|n")
| 09:58:20 I {aa8} [FallBack.hsc:34]: var ($lastError1, $lastError2, $rc1, $rc2)
| 09:58:20 I {aa8} [FallBack.hsc:36]: $rc2 = DLLCall ($ApiQueryPerformanceCounter, MemVarPtr ($buf2))
| 09:58:20 I {aa8} [FallBack.hsc:37]: $lastError2 = DLLLastError
| 09:58:20 I {aa8} [FallBack.hsc:42]: dump
| 09:58:20 I {aa8} > dump follows:
| 09:58:20 I {aa8} > .context: (global)
| 09:58:20 I {aa8} > .var: ->$ApiGetLocalTime="kernel32.dll|GetLocalTime|n|n"
| 09:58:20 I {aa8} > .var: ->$ApiQueryPerformanceCounter="kernel32.dll|QueryPerformanceCounter|n|n"
| 09:58:20 I {aa8} > .var: ->$buf1="01234567890123456789012345678901234567890123456789"
| 09:58:20 I {aa8} > .var: ->$buf2="Õùß // 890123456789012345678901234567890123456789"
| 09:58:20 I {aa8} > .var: ->$lastError1=(unassigned)
| 09:58:20 I {aa8} > .var: ->$lastError2=0
*************
| 09:58:20 I {aa8} > .var: ->$rc1=(unassigned)
| 09:58:20 I {aa8} > .var: ->$rc2=1
| 09:58:20 I {aa8} [FallBack.hsc:44]: trace (0)
| 09:58:20 Sys {aa8} {script FallBack.hsc} Ende
| 09:58:20 Sys {874} Skript C:\Users\Public\Hamster-Daten\Scripts and Modules\FallBack.hsc beendet.
Seltsam!?
> HTH
Ja, hat es. Funktioniert im Endeffekt einwandfrei, abgesehen von den
Lasterror-Sonderlichkeiten, die mir aber nur so nebenbei aufgefallen sind
und nicht weiter stören sollten(?).
Beim Debug habe ich noch bemerkt, dass kernel32.dll für jeden DLLCall
geladen und wieder freigegeben wird.
Dazu Help:
| Werden die Funktionen einer DLL häufiger benötigt sollte diese aus Performance-Gründen
| permanent mit der Funktion DLLoad in den Arbeitsspeicher geladen werden.
Soweit einsichtig, aber:
| Das Laden der System Bibliotheken (z.B. "kernel32.dll") ist nicht erforderlich und sollte unterbleiben.
Wieso eigentlich?
--
lg georg
> Da les ich _einmal_ die Doku und schon bin ich in den Dings gekniffen ;-)
>| Ergebnis_Typ muss den Typ des R�gabewerte der Funktion
>| widerspiegeln. Folgende Werte sind hierf�r zul�ssig:
>| n=Integer
>| v=kein R�ckgabewert vorhanden
Da hat der Doku-Schreiber mehr gewusst als der Programmierer. ;-)
Das l�sst sich aber angleichen, ohne die Doku �ndern zu m�ssen.
>>| $rc2 = DLLCall ($ApiQueryPerformanceCounter, MemVarPtr ($buf2))
>
> Genau, aber vom dazugeh�renden
> $lastError2 = DLLLastError
> war nicht zu erwarten, dass es seinen Inhalt abh�ngig vom trace-Status
> �ndert.
Kann ich hier nicht nachvollziehen.
Vermutlich ist das ein alter Fehlerstatus. Kannst Du DLLLastError schon
mal vorher abfragen?
Es ist leider keine M�glichkeit vorgesehen, den Status zu l�schen.
> Beim Debug habe ich noch bemerkt, dass kernel32.dll f�r jeden DLLCall
> geladen und wieder freigegeben wird.
>| Das Laden der System Bibliotheken (z.B. "kernel32.dll") ist nicht erforderlich und sollte unterbleiben.
> Wieso eigentlich?
"Laden" ist in diesem Fall irref�hrend. Die System-Bibliotheken liegen
ohnehin permanent im Speicher. Sie mit DLLLoad erneut zu /laden/, erh�ht
nur den Verwaltungsaufwand.
Alfred
--
09884.4
Beim Aufruf von DLLCall erfolgen eigentlich 5 Schritte: zuerst wird die
betreffende DLL von der Festplatte gelesen und in den Hauptspeicher
geladen, dann wird sie in das Programm (in dem Fall den Hamster)
eingebunden, anschlieᅵend die angegebene Operation ausgefᅵhrt,
schlieᅵlich die Verbindung wieder gelᅵst und abschlieᅵend die DLL im
Hauptspeicher freigegeben.
Wenn allerdings die DLL schon durch einen anderen Prozess (egal ob durch
das gleiche Programm oder ein anderes) im Hauptspeicher vorhanden ist,
entfallen der erste und der letzte Schritt, was den Overhead und
insbesondere die Festplattenzugriffe aus dem 1. Schritt betrᅵchtlich
reduziert. In diesem Fall wird nur ein Zᅵhler hochgezᅵhlt bzw.
heruntergesetzt, welcher beschreibt, wie viele Prozesse die DLL aktuell
eingebunden haben. Nur wenn dieser Zᅵher auf 0 fᅵllt, wird die DLL im
Hauptspeicher freigegeben.
Genau ein solches Hochzᅵhlen bewirkt das Laden und Freigeben ᅵber DLLoad
/ DLLFree. Einige DLLs, wie etwa die Systembiblitheken, /sind/ aber
schon permanent geladen, nᅵmlich vom Betriebssystem, deswegen macht das
bei denen keinen Sinn.
Wolfgang
--
> Es schrieb einmal Georg Gruber:
>> Alfred Peters tat kund:
>>> Es schrieb einmal Georg Gruber:
>>
>>> Der Hamster unterst�tzt keine 'void'-Funktionen. Benutze einfach:
>
>> Da les ich _einmal_ die Doku und schon bin ich in den Dings gekniffen ;-)
>>| Ergebnis_Typ muss den Typ des R�gabewerte der Funktion
>>| widerspiegeln. Folgende Werte sind hierf�r zul�ssig:
>>| n=Integer
>>| v=kein R�ckgabewert vorhanden
>
> Da hat der Doku-Schreiber mehr gewusst als der Programmierer. ;-)
So qanz ignoriert wird void ja nicht, die Implementierung ist nur ein wenig
unvolls�ndig (um das rauszufinden, reichts bei mir soeben), aber der
Workaround ist ohnehin ausreichend.
> Kann ich hier nicht nachvollziehen.
> Vermutlich ist das ein alter Fehlerstatus. Kannst Du DLLLastError schon
> mal vorher abfragen?
Done -> 0.
Anscheinend tritt der Fehler nur beim 1. DLLCall auf.
Beim 2. DLLCall ist die Konstellation anders, denn wenn der 1. Call
fehlerhaft war, bleibt dessen Fehlercode auch nach dem 2. Aufruf bestehen.
Vertauschen der DLLCalls �ndert nichts am Effekt, der d�rfte aber sowieso
vernachl�ssigbar sein, weil �berhaupt keine weiteren Auswirkungen zu sehen
sind.
>>| Das Laden der System Bibliotheken (z.B. "kernel32.dll") ist nicht erforderlich und sollte unterbleiben.
>> Wieso eigentlich?
Danke f�r die Klarstellung zum Preload an dich und Wolfgang!
--
lg georg
Was siehst Du denn da? Da passiert nichts (au�er dass Deine
'v|n'-Funktion abgelehnt wird). :-)
>> Kann ich hier nicht nachvollziehen.
>> Vermutlich ist das ein alter Fehlerstatus. Kannst Du DLLLastError schon
>> mal vorher abfragen?
> Done -> 0.
Ups, das ist leider irrelevant - Mein Fehler. Die Hamster-Funktion
DLLLastError liefert den Wert einer internen variablen zur�ck. diese setzt
der Hamster aber erst, wenn das Script eine DLL-Funktion aufruft. Klar,
das sie dann vorher immer 0 ist.
Gesetzt wird diese Variable aus der Betr�bssystem-Funktion GetLastError.
Diese hat wiederum die Eigenschaft, solange den letzten Fehlerstatus zu
liefern, bis jemand �ber SetLastError einen anderen Status
setzt (z.B.: 0).
Wenn bei DLLCall kein Fehler auftritt, kann Dein komischer Fehlerstatus
von sonstwoher stammen.
Alfred
--
09887.4
> Es schrieb einmal Georg Gruber:
>>
>> So qanz ignoriert wird void ja nicht,
>
> Was siehst Du denn da? Da passiert nichts (au�er dass Deine
> 'v|n'-Funktion abgelehnt wird). :-)
>
Doch, 'v|v' und 'n|v' wird behandelt?
>> Done -> 0.
>
> Ups, das ist leider irrelevant - Mein Fehler. Die Hamster-Funktion
> DLLLastError liefert den Wert einer internen variablen zur�ck. diese setzt
> der Hamster aber erst, wenn das Script eine DLL-Funktion aufruft. Klar,
> das sie dann vorher immer 0 ist.
Alles klar, Aufpassen beim Einsatz von DLL-Funktionen.
--
lg georg
Es gibt f�r alles eine nat�rliche Erkl�rung:
Das Script ist ein von scratch aufgesetztes Notfall-Script,
da hat es nichtmal f�r ein #!load hamster.hsm gelangt,
und das dort enthaltene return(0) stellt offenbar einen definierten Zustand
nach dem Laden des Scriptes her - in den Tiefen des runscript-Codes kann ja
viel passieren, wo ein Code 2 ganz normal ist.
--
lg georg
>>> Die Hamster-Funktion
>>> DLLLastError liefert den Wert einer internen variablen zur锟絚k. diese setzt
>>> der Hamster aber erst, wenn das Script eine DLL-Funktion aufruft. Klar,
>>> das sie dann vorher immer 0 ist.
> Es gibt f锟絩 alles eine nat锟絩liche Erkl锟絩ung:
AOL ;-)
Der 'LastError'-Wert scheint tats锟絚hlich durch die 'trace'-Funktion
beeinflusst zu werden. Ich habe vor Deine Beispiel-Calls noch:
| $rc0 = DLLCall ("kernel32.dll|SetLastError|n|n", 42 )
| $lastError0 = DLLLastError
gesetzt. Damit bekomme ich ohne 'trace':
| .var: ->$lastError0=42
| .var: ->$lastError1=42
| .var: ->$lastError2=42
Und mit 'trace':
| .var: ->$lastError0=42
| .var: ->$lastError1=0
| .var: ->$lastError2=0
W锟絟rend der Log-Funktion wird der Wert also irgendwo zur锟絚kgesetzt.
> nach dem Laden des Scriptes her - in den Tiefen des runscript-Codes kann ja
> viel passieren, wo ein Code 2 ganz normal ist.
Der vorherige Aufruf von:
DLLCall ("kernel32.dll|SetLastError|n|n", 0 )
sollte dem Spuk ein Ende bereiten.
HTH
Alfred
--
09889.3
Aber die umst�ndliche Unterscheidung die dort gemacht wird ist unn�tig.
Das eine 'void'-Funktion keinen g�ltigen R�ckgabewert hat, sollte doch
klar sein.
Alfred
--
09889.3
't�rlich. Aber was les ich auch Sekund�rliteratur aka Manual ;-)
Ich w�rde das 'v' einfach wie 'n' durchlaufen lassen und nur zur Draufgabe
am Ende f�r 'v' Result=0 setzen.
Pretty quick, not even dirty.
--
lg georg
"Ich weiss, dass das die Rechts-Gruppe ist, bitte entschuldigt meine
Ratschlaege eher praktischer Natur." - Otto A. in agr 7.8.09
Dazu hatte ich ja schon etwas geschrieben.
Anders als der R�ckgabewert ist die Anzahl der Parameter sehr wohl
wichtig. Wenn das nicht passt, schreibt der Hamster anschlie�end munter
auf dem Stack herum. Ein Wunder, dass er dabei nicht abst�rzt.
> Ich w�rde das 'v' einfach wie 'n' durchlaufen lassen und nur zur Draufgabe
> am Ende f�r 'v' Result=0 setzen.
Zu sp�t. Das ist doch schon l�ngst /drin/. Aber wegen obigem Bug muss ich
das noch mal komplett umschreiben. <seufz>
Gut, dass Du gemeckert hast, sonst w�re das nie aufgefallen.
Alfred
--
09889.7
> Gut, dass Du gemeckert hast, sonst w�re das nie aufgefallen.
Ich nehme "gemeckert" in mein Synonym-W�rterbuch f�r "konstruktiven Beitrag
geleistet" auf :-)
--
lg georg
Hamster 2.1.0.11 unter Windows Vista Home Premium SP 1