Hallo zusammen,
ich komme eigentlich aus der Java-Ecke habe damit aber jetzt schon seit zwei Jahren nicht mehr ernsthaft gearbeitet.
Seit zwei Wochen probiere ich mich jetzt erst an C#, für DAU-Fehler entschuldige ich mich daher jetzt schonmal.
So nun zu meinem Problemchen.
Ich habe um mal ein bischen mit dem Arbeitsspeicher zu spielen eine mini Windows Forms Anwedung gebastelt, mit der ich per Klick den Score von Windows Pinball um 1Mio erhöhe.
In textBox1 wird mit Hilfe eines Timers alle 0,2 Sekunden der aktuelle Score ausgegeben. Klicke ich jetzt mehrmals relativ flott auf button1 wird dieser Timer gestoppt bzw textBox1 nicht mehr aktualisiert...
Der Score wird trotzdem weiterhin erhöht.
Woran könnte das liegen?
Gruß und Danke schonmal im Vorraus
private int ReadMem() {
IntPtr hWnd = FindWindow(null, "3D-Pinball für Windows - Space Cadet");
UInt32 pid;
UInt32 tid = GetWindowThreadProcessId(hWnd, out pid);
hWnd = OpenProcess(PROCESS_VM_READ, false, pid);
if((int)pid == 0) {
return -1;
}
uint size = 4;
uint vNumberOfBytesRead = 0;
byte[] vBuffer = new byte[size];
ReadProcessMemory(hWnd, (IntPtr)0xC1AEBA, vBuffer, vBuffer.Length, ref vNumberOfBytesRead);
return BitConverter.ToInt32(vBuffer, 0);
}
private void WriteMem(int i) {
IntPtr hWnd = FindWindow(null, "3D-Pinball für Windows - Space Cadet");
UInt32 pid;
UInt32 tid = GetWindowThreadProcessId(hWnd, out pid);
hWnd = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, pid);
uint size = 4;
uint vNumberOfBytesRead = 0;
byte[] vBuffer = new byte[size];
vBuffer = BitConverter.GetBytes(i);
WriteProcessMemory(hWnd, (IntPtr)0xC1AEBA, vBuffer, vBuffer.Length, ref vNumberOfBytesRead);
}
private void TimerHandler(object state) {
int iWert = ReadMem();
string sMsg;
if(iWert == 0 && !bProgStatus) {
button1.Invoke(new MethodInvoker(delegate() { button1.Enabled = true; }));
bProgStatus = true;
sMsg = "-";
textBox3.Invoke(new MethodInvoker(delegate() { textBox3.Text = textBox3.Text+"Programm gestartet\r\n"; }));
}
else {
sMsg = iWert.ToString();
}
if(iWert == -1) {
button1.Invoke(new MethodInvoker(delegate() { button1.Enabled = false; }));
bProgStatus = false;
sMsg = "-";
if(!bMsgsended) {
textBox3.Invoke(new MethodInvoker(delegate() { textBox3.Text = textBox3.Text + "Pinball starten\r\n"; }));
bMsgsended = true;
}
}
textBox1.Invoke(new MethodInvoker(delegate() { textBox1.Text = sMsg; }));
}
private void StartTimer() {
TimerCallback handler = new TimerCallback(TimerHandler);
string state = "...";//sinnlos
System.Threading.Timer timer = new System.Threading.Timer(handler, state, 0, 200);
}
private void Form1_Load(object sender, EventArgs e){
textBox3.Text = "Moin moin\r\n------\r\n";
StartTimer();
}
private void button1_Click(object sender, EventArgs e){
WriteMem(ReadMem() + 1000000);
}
Hrm, mach mal nen Invoke rein bei WriteMem oder beim button1_Click wo WriteMem aufrufst.
Bei WriteMem brauchst für as Invoke natürlich ein neues delegate:
private delegate void WriteMemDelegate(int i);
Du rufst zwar in der Methode WriteMem keine GUI Elemente auf, aber da dir ja das Handle des Fensters holst und via WriteProcessMemory könnte es dadurch zu Problemen kommen und der Thread vom Timer schmiert irgendwo zwischendrinnen ab, davon bekommst ja so direkt nichts mit, ausser evtl. im "Output" ("Ausgabe" in deutschen VS glaube ich) das der Trhead XY beendet wurde.
Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(
Hi & welcome!
Äh, die zündende Idee zum Prob habich eignt lcih nich - kannes sein, daß häufiges Klicksen einen Fehler im ReadMem erzeugt, im Nebenthread?
Daraufhin verabschiedet sich der Timer, und die Fehlermeldung fliegt ins Nirvana, weil Nebenthread.
Kriegst du auch im Ausgabefenster keine Fehlermeldung?
Also am ReadMem würdich mal herumdebuggen, Debug-Meldungen einbauen, TryCatch dranmachen und so.
Der frühe Apfel fängt den Wurm.