http://hi.baidu.com/859729391/blog/item/58a4f21285a43a876438dbfd.html
大家都知道C#对底层的支持是非常不好....但是我们还是可以通过一些方法来读PID
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Diagnostics;//我们可以通过此类来查找进程pid,比通过API的来的简单的许多. using System.Management;
namespace ok { public partial class Form1 : Form { public Form1() { InitializeComponent();
public class getpid//定义取得pid的类
{ public string pid;//为了省事,我直接声明一个公共字段了,当然你也可以写属性写构造啦!
System.Diagnostics.Process[] processes = Process.GetProcesses(); //获得当前所有进程列表 ,注意是个数组,除非你的电脑只有一个进程 foreach (Process a in processes) //遍历每一个进程 ,如果出错请声明一下a { if(a.ProcessName.ToString()=="xxx.exe")//如果进程名等于xxx.exe,可以用资源管理器查看
{
pid= a.Id.ToString();//就输出他的pid,这样就可以获得pid了
//当然Process a的属性还有很多,总之很强大,例如 a.MachineName.ToString();//获取关联进程机器名 // a.MainWindowTitle.ToString();//获取主窗口的窗口名
//红色部分可以任意替换,如果你不知道进程名,知道窗口名,就用a.MainWindowTitle.ToString()="记事本"
}
} } }
//这样,我们就获得了进程的pid了,下面我们来修改内存...还是得调用API..下面我们来写个内存读写类.
//呵呵,说来说去还是要用API
public class read_and_write//定义一个类,类名随便你写....我就通俗点了,直接用read_and_write
{ const uint PROCESS_ALL_ACCESS = 0x001F0FFF; const uint KEYEVENTF_EXTENDEDKEY = 0x1; const uint KEYEVENTF_KEYUP = 0x2; const uint KBC_KEY_CMD = 0x64; const uint KBC_KEY_DATA = 0x60;
[DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName );
//得到窗体句柄的函数,FindWindow函数用来返回符合指定的类名( ClassName )和窗口名( WindowTitle )的窗口句柄 [DllImport("user32.dll")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
//取得pid的一种函数,我们上面已经获得pid了,所以这里用不到了.
[DllImport("kernel32.dll")] static extern bool ReadProcessMemory(uint hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, uint nSize, ref uint lpNumberOfBytesRead); //读取进程内存的函数,非常重要 [DllImport("kernel32.dll")] static extern bool WriteProcessMemory(uint hProcess, IntPtr lpBaseAddress, uint[] lpBuffer, uint nSize, ref uint lpNumberOfBytesWritten); //写入进程内存函数,更重要 [DllImport("kernel32.dll")] public static extern uint OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId); //得到目标进程句柄的函数 //上面是调用一些API函数,不用记,COPY就行了,不记得就百度一下
public void write(string pid,IntPtr address,int wordin)//定义写内存的方法 { byte[] vBuffer = new byte[4]; IntPtr vBytesAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 得到缓冲区的地址
uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, Convert.ToInt32(pid));
//这个大家很熟悉了..获得进程句柄,并且得到绝对控制权限,3个参数(绝对控制,总是false,pid注意是int类型) uint[] PinballScoreWrite = new uint[] { Convert.ToUInt32(wordin) };//定义欲写入 //写入的值,,注意是个数组,不是数组能不能我也不清楚,你可以试试 WriteProcessMemory(hProcess, address, PinballScoreWrite, (uint)vBuffer.Length, ref hProcess); //这个就是写入内存了,参数列表(进程句柄,地址(注意其类型),写入的值,长度,ref hProcess)
//注意最后一个参数是引用传递..可能可以填0.
CloseHandle(hProcess);//养成良好习惯,关闭句柄
}
public string read(string pid,IntPtr address,int wordin)//定义读内存的方法,既然是读就有返回值
{
byte[] vBuffer = new byte[4]; IntPtr vBytesAddress = Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0); // 同上
uint hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, Convert.ToInt32(pid));//同上
uint[] PinballScoreWrite = new uint[] { Convert.ToUInt32(wordin) };//同上 if(ReadProcessMemory(hProcess, address, PinballScoreWrite, (uint)vBuffer.Length, ref hProcess);)
//假如读的出,这是个bool型判断,就就是true,则执行
{
CloseHandle(hProcess);//关闭句柄
return Convert.Tostring( Marshal.ReadInt32(address));//返回address地址存放的值,就可以调用了
else//否则什么都不做,只关闭句柄
{
CloseHandle(hProcess);
}
}
} }
//这样我们就可以调用了...小记(3)则写一个如何调用read_and_write的类..^ ^
|
请发表评论