Hooking time unter C#

yurij

Lt. Commander
Registriert
Jan. 2008
Beiträge
1.064
Ich habe lange Zeit nach einer Lösung gesucht um unter C# Zeitverlauf zu kontrollieren (speziell für nativ oder über WebBrowser Component eingebettete AxShockwafeFlash Objekte).
Es gibt eine Handvoll Möglichkeiten unter C# Windows Systemfunktionen umzuleiten (hooking), und keine Beispiele für das was ich vorhatte, deswegen Poste ich hier meine Lösung, vielleicht wird es jemand brauchen.

Man braucht EasyHook (Googlesuche).

Dann
using System.Runtime.InteropServices; // für DllImports
using EasyHook;

Flash verwendet hauptsächlich timeGetTime() aus "Winmm.dll".
Der nachfolgende Code leitet timeGetTime in eigene Funktion um (hooking).
Mit SpeedUp Variable könnt ihr den Zeitverlauf beschleunigen oder verlangsamen.
Der Hook ist lokal (gilt nur für die eigene C# Anwendung).
Wichtig: Wenn der Hook einmal installiert ist, darf es bis zum Ende der Anwendung nicht deinstalliert werden, am sonsten friert Flash Anwendung ein.
Der Hook funktioniert für alle eingebetteten Flash Componenten, egal ob diese direkt über den AxShockwaveFlashObject oder WebBrowser Component eingebettet werden.

Im folgenden Code einfach SetSpeedUp(2.0) aufrufen, und schon läuft die Zeit für Flash doppelt so schnell. Nach dem selben Schema lassen sich auch andere Zeit-Funktionen umleiten: QueryPerformanceCounter, QueryPerformanceFrequency, GetTickCount usw... Ich habe mich nur auf die timeGetTime beschränkt.

Code:
        [DllImport("Winmm.dll")]
        private static extern int timeGetTime();

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Auto, SetLastError = true)]
        delegate int timeGetTimeDelegate();

        public LocalHook timeGetTimeHook = null;
        public static double SpeedUp = 1.0;
        public static int StoredRealTime = 0;
        public static int StoredFakeTime = 0;

        static int timeGetTimeEx()
        {
            int RealTime = timeGetTime();
            if (StoredRealTime == 0 || StoredFakeTime == 0) // Initialize
            {
                StoredRealTime = RealTime;
                StoredFakeTime = RealTime;
            }
            int FakeTime = StoredFakeTime + (int)((RealTime - StoredRealTime) * SpeedUp);
            StoredRealTime = RealTime;
            StoredFakeTime = FakeTime;
            return FakeTime;
        }

        private bool SetSpeedUp(double NewSpeedUp)
        {
            SpeedUp = NewSpeedUp;
            if (timeGetTimeHook == null)
            {
                timeGetTimeHook = LocalHook.Create(LocalHook.GetProcAddress("Winmm.dll", "timeGetTime"), new timeGetTimeDelegate(timeGetTimeEx), this);
                timeGetTimeHook.ThreadACL.SetExclusiveACL(new Int32[0]);
            }
            return true;
        }
 
Zuletzt bearbeitet:
Zurück
Oben