线程无法正常工作c#

时间:2016-02-19 20:55:09

标签: c# multithreading

我正在编写一个小程序来读取游戏中的统计数据,比如健康,法力等等......我想在未来制作一个工具,以便稍后计算统计数据。我来到程序读取Health的部分,但是经过一段时间后,标签中的值将变为0,我必须重新启动程序才能再次正确显示,我做错了什么?

这是我的代码,以我的主要形式:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace RMBot
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        static bool botrunning = false;
        private void OnOff_Click(object sender, EventArgs e)
        {
            if (botrunning == false)
            {
                OnOff.Text = "STOP";
                botrunning = true;
                //Thread t = new Thread(new ThreadStart(CombatInit));
                //t.Start();
                Thread b = new Thread(new ThreadStart(stats));
                b.Start();

            }
            else {
                OnOff.Text = "START";
                botrunning = false;
            }
        }

        private void SetText(Control control, string text)
        {
            if (control.InvokeRequired)
                this.Invoke(new Action<Control>((c) => c.Text = text), control);
            else
                control.Text = text;
        }

        /*STATS*/
        public void stats()
        {
            while (botrunning == true) {

                // update label approximately 10 times every second
                Thread.Sleep(100);

                HPLabel.BeginInvoke(new Action(() =>   
                {
                    HPLabel.Text = string.Format(Memory.SetCurrentHP());
                }));

            }

        }

    }

这是我的记忆课:

public static string SetCurrentHP()
{
    return Convert.ToString(ReadInt32(gameBaseAddress + HpAdr, Handle));
    //return "WORKING";
}

添加了我的记忆课:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;


namespace RMBot
{


    class Memory
    {

        [DllImport("kernel32.dll")]
        public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);

        public static byte[] ReadBytes(IntPtr Handle, Int64 Address, uint BytesToRead)
        {
            IntPtr bytesRead;
            byte[] buffer = new byte[BytesToRead];
            ReadProcessMemory(Handle, new IntPtr(Address), buffer, BytesToRead, out bytesRead);
            return buffer;
        }



        /* READ INT */
        public static int ReadInt32(Int64 Address, IntPtr Handle)
        {
            return BitConverter.ToInt32(ReadBytes(Handle, Address, 4), 0);
        }


        /* READ STRING */
        public static string ReadString(long Address, IntPtr Handle, uint length = 32)
        {
            return ASCIIEncoding.Default.GetString(ReadBytes(Handle, Address, length)).Split('\0')[0];
        }




        public static void GetClient()
        {
            Process Aion = Process.GetProcessesByName("aion.bin")[0];
            UInt32 winBase = (UInt32)Aion.MainModule.BaseAddress.ToInt32();

            //seznam vseh modulov
            ProcessModuleCollection myProcessModuleCollection = Aion.Modules;
            //iskani modul
            ProcessModule myProcessModule;
            UInt32 gameBase = 0;

            for (int x = 0; x < myProcessModuleCollection.Count; x++)
            {
                myProcessModule = myProcessModuleCollection[x];
                if (myProcessModuleCollection[x].ModuleName == "Game.dll")
                {
                    gameBase = (UInt32)myProcessModule.BaseAddress.ToInt32();
                    //Console.WriteLine("The moduleName is " + myProcessModule.ModuleName);
                    //Console.WriteLine("The " + myProcessModule.ModuleName + "'s File Name is: " + myProcessModule.FileName);
                    //Console.WriteLine("The " + myProcessModule.ModuleName + "'s base address is: " + myProcessModule.BaseAddress);
                    //Console.WriteLine("For " + myProcessModule.ModuleName + " Entry point address is: " + myProcessModule.EntryPointAddress);
                }
            }

            IntPtr Handle = Aion.Handle;
            //Console.WriteLine("Base Address : " + Convert.ToString(gameBase));


            /*OFFSETS*/
            //Current HP
            //UInt32 HpAdr = 0xEB5AB0;
            //String Hp = Convert.ToString(ReadInt32(gameBase + HpAdr, Handle));

            //Console.WriteLine("Health: " + Convert.ToString(ReadInt32(gameBase + HpAdr, Handle)));
            //Console.ReadLine();

        }


        //Gets the base address of the game
        public static int GetGameBase()
        {
            Process Aion = Process.GetProcessesByName("aion.bin")[0];
            UInt32 winBase = (UInt32)Aion.MainModule.BaseAddress.ToInt32();

            //seznam vseh modulov
            ProcessModuleCollection myProcessModuleCollection = Aion.Modules;
            //iskani modul
            ProcessModule myProcessModule;
            UInt32 gameBase = 0;

            for (int x = 0; x < myProcessModuleCollection.Count; x++)
            {
                myProcessModule = myProcessModuleCollection[x];
                if (myProcessModuleCollection[x].ModuleName == "Game.dll")
                {
                    gameBase = (UInt32)myProcessModule.BaseAddress.ToInt32();
                    //Console.WriteLine("The moduleName is " + myProcessModule.ModuleName);
                    //Console.WriteLine("The " + myProcessModule.ModuleName + "'s File Name is: " + myProcessModule.FileName);
                    //Console.WriteLine("The " + myProcessModule.ModuleName + "'s base address is: " + myProcessModule.BaseAddress);
                    //Console.WriteLine("For " + myProcessModule.ModuleName + " Entry point address is: " + myProcessModule.EntryPointAddress);
                }
            }
            IntPtr Handle = Aion.Handle;

            return Convert.ToInt32(gameBase);
        }


        //Gets the game handle ptr
        public static IntPtr GetGameHandle()
        {
            Process Aion = Process.GetProcessesByName("aion.bin")[0];
            UInt32 winBase = (UInt32)Aion.MainModule.BaseAddress.ToInt32();

            //seznam vseh modulov
            ProcessModuleCollection myProcessModuleCollection = Aion.Modules;
            //iskani modul
            ProcessModule myProcessModule;
            UInt32 gameBase = 0;

            for (int x = 0; x < myProcessModuleCollection.Count; x++)
            {
                myProcessModule = myProcessModuleCollection[x];
                if (myProcessModuleCollection[x].ModuleName == "Game.dll")
                {
                    gameBase = (UInt32)myProcessModule.BaseAddress.ToInt32();
                    //Console.WriteLine("The moduleName is " + myProcessModule.ModuleName);
                    //Console.WriteLine("The " + myProcessModule.ModuleName + "'s File Name is: " + myProcessModule.FileName);
                    //Console.WriteLine("The " + myProcessModule.ModuleName + "'s base address is: " + myProcessModule.BaseAddress);
                    //Console.WriteLine("For " + myProcessModule.ModuleName + " Entry point address is: " + myProcessModule.EntryPointAddress);
                }
            }
            IntPtr Handle = Aion.Handle;

            return Handle;
        }

        /*OFFSETS*/
        //Current HP
        static UInt32 HpAdr = 0xEB5AB0;
        static int gameBaseAddress = GetGameBase();
        static IntPtr Handle = GetGameHandle();
        String Hp = Convert.ToString(ReadInt32(gameBaseAddress + HpAdr, Handle));


        public static string SetCurrentHP()
        {
            var hpValue = ReadInt32(gameBaseAddress + HpAdr, Handle);
            Trace.WriteLine(hpValue.ToString());

            return Convert.ToString(hpValue);
            //return Convert.ToString(ReadInt32(gameBaseAddress + HpAdr, Handle));
            //return "WORKING";
        }
        //Console.WriteLine("Health: " + Convert.ToString(ReadInt32(gameBase + HpAdr, Handle)));
        //Console.ReadLine();





    }
}

1 个答案:

答案 0 :(得分:1)

使用您的SetText方法确保在UI线程上进行更新。

/*STATS*/
public void stats()
{
  while (botrunning == true) {
    Thread.Sleep(100);

    SetText(HPLabel, Memory.SetCurrentHP());
  }
}

此外,也许某些东西会覆盖其他地方的内存值。就像评论中提到的人一样:

public static string SetCurrentHP()
{
  var hpValue = ReadInt32(gameBaseAddress + HpAdr, Handle);
  Trace.WriteLine(hpValue.ToString());

  return Convert.ToString(hpValue);
}