c#游戏进程杀手
我认为写博客还是比较重要的,特别是短时间写出一个含有新知识点的软件。这样总结下这次编程经验和再捋顺一下这次编程思路。首先来谈谈为什么想做这个小程序,一是感觉自己太贪玩想控制一下,二是也锻炼下自己的编程。好,话不多说进入正题吧。
文件源代码在这个https://i.cnblogs.com/Files.aspx?order=1下面。名字是ApplicationControl。不过使用的时候你还是要到子窗体中设置你的游戏库,我这里只有WeGame、LOL登陆程序的进程名称。源码有点乱,见谅。如需改进,请多指教。
首先给大家展示一下程序结果图:
这里的原理很简单,就是写一个监视进程的函数如果发现进程列表中有相同名字的进程则调用process类中的kill方法杀死进程,再设置一个计时器来循环调用该函数即可。
首先我们窗体加载函数中调用一个初始化函数。
Initial函数:
public void Initial()
{
timer1.Enabled = false;
for (int i = ; i < ; i++)
{
Hour.Items.Add(i); //combox控件名称
}
Hour.SelectedIndex = ;
for (int i = ; i < ; i++)
{
Minute.Items.Add(i);
Sceond.Items.Add(i);
}
Minute.SelectedIndex = ;
Sceond.SelectedIndex = ;
LoadTime(); //后面解释说明
string fileName = @"\gamelist.txt"; //后面解释说明 首次加载程序
string dirpath = System.Environment.CurrentDirectory;
string path = dirpath + fileName; if (File.Exists(path))
{
try
{
StreamReader sr = new StreamReader(path, Encoding.UTF8);
string line;
while ((line = sr.ReadLine()) != null)
{
gamename.Add(line);
textBox1.AppendText(line + "\r\n");
}
sr.Dispose();
}
catch { };
} }
其中Hour、Minute、sceond(秒翻译错了,应该是second,哈哈)分别是Combox控件的名称。计时器控件则是Timer1。
之后就可以为启动button写函数了。
private void button3_Click(object sender, EventArgs e)
{
flag = ;
timer1.Enabled = true;
timer1.Interval = ;
h = Convert.ToInt32(Hour.SelectedItem); //用户选择的时间
m = Convert.ToInt32(Minute.SelectedItem);
s = Convert.ToInt32(Sceond.SelectedItem);
TS = new TimeSpan(h, m, s); //设置一个TimeSpan对象来存放时间
}
点击按钮,告诉计时器开始工作,并把用户选择的时间存储起来。
//计时器函数。
private void timer1_Tick(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
GameControl();//调用进程检查函数,如果存在则查杀
string str1 = TS.Hours.ToString() + ":" + TS.Minutes.ToString() + ":" + TS.Seconds.ToString();
time.Text = str1; //设置时间标签
string str2 = TSsum.Hours.ToString() + ":" + TSsum.Minutes.ToString() + ":" + TSsum.Seconds.ToString();
label8.Text = str2; //总时间显示标签
TS = TS.Subtract(new TimeSpan(, , )); //TS 每隔一秒设置时间减一倒计时效果
TSsum = TSsum.Add(new TimeSpan(, , )); //TSsum 每隔一秒总时间加一
if (TS.TotalSeconds < 0.0) //倒计时完毕
{
timer1.Enabled = false;
MessageBox.Show("你离成功又进了一步");
flag = ;
flagtime = ;
LoadTime(); //另外说明
}
}
}
每次调用GameControl去查杀进程。
public void GameControl()
{
List<Process[]> pro = new List<Process[]>(); //进程的泛型集合 因为可能对多个进程进行监视 可以理解为装箱
Process[] gameProcess =Process.GetProcessesByName("Taskmgr"); //防止用任务管理器关闭这个程序
pro.Add(gameProcess);
//gamename是所有游戏进程名字的泛型集合。
for (int i = ; i < gamename.Count; i++)
{
gameProcess = Process.GetProcessesByName(gamename[i].Replace(".exe", "").Trim());
pro.Add(gameProcess);
}
try
{
for (int i = ; i < pro.Count;i++ )
{
Process[] game = pro[i]; //可以理解为拆箱
foreach (Process p in game)
{
p.Kill();
}
}
}
catch (Exception e)
{ }
}
这里用一个trycatch防止程序抛异常。
这样连任务管理器都关不了的程序,怎么办呢,我们还是比较人性化设置一个结束button来提前结束这个程序。只是有很多弹出框。~嘿嘿!
//结束按钮
private void shutdown_Click(object sender, EventArgs e)
{
Thread th = new Thread(ShutDown); //开启一个新线程运行
th.Start();
}
public void ShutDown()
{
if (flag == ) //flag 标识程序是否跑起来了 0--否 1--是 跑起来才有作用
{
DialogResult re = MessageBox.Show("能不能再坚持一会儿?", "提示", MessageBoxButtons.YesNo);
if (re == DialogResult.No)
{
Thread.Sleep(); //选择一次否,休眠5s(给你时间冷静下冲动的大脑)
re = MessageBox.Show("坚持就是胜利,不要放弃!", "提示", MessageBoxButtons.YesNo);
if (re == DialogResult.No)
{
Thread.Sleep();
re = MessageBox.Show("你离成功就差一步了!", "提示", MessageBoxButtons.YesNo);
if (re == DialogResult.No)
{
Thread.Sleep();
re = MessageBox.Show("想一想自己还有没有其他更重要的事做没做!", "提示", MessageBoxButtons.YesNo);
if (re == DialogResult.No)
{
Thread.Sleep();
re = MessageBox.Show("比你牛逼的人还在努力!", "提示", MessageBoxButtons.YesNo);
timer1.Enabled = false; //关闭计时器
flagtime = ;
flag = ; //设置程序状态--关闭
LoadTime(); //将这段时间加到总时间上
}
}
}
}
}
}
这里开启一个新线程运行这个函数是为了防止我们我们主线程休眠。如果不开,就整个程序休眠5s。开了就相当于这个函数休眠5s。
当然呢,任务管理器关不掉那我们可以点击窗口关闭按钮啦(不过NO way~)
//窗体关闭时发生
private void ApplicationControl_FormClosing(object sender, FormClosingEventArgs e)
{
if (flag != ) //判断程序是否运行
{
e.Cancel = true;//取消这个动作
}
}
到这里我们基本已经将这个程序的主要功能做出来了。那我们再做点东西来润色、润色。别看看它只是修饰功能,它的难度一点都不比我们主要功能小。
首先我们不是有个叫“控制总时长”的标签吗:这个是记录我们每次设置时间到结束的总时长。它的原理就是本次程序结束后,生成一个txt文件将这个时间记录时间,如果存在这个文件则覆盖上去,就实现了时间的刷新。当然了,我们每次首先需要在程序加载时,把这个时间读取出来。
//加载、更新总时间
public void LoadTime()
{
string fileName = @"\sumtime.txt"; //生成一个名字为sumtime的文本文件
string str = System.Environment.CurrentDirectory; //程序所在路径
string path = str + fileName; //路径拼接
FileStream fs;
if (!File.Exists(path)) //如果不存在此文件(首次运行该程序)
{
fs = new FileStream(path, FileMode.Create);
}
else if (flagtime == ) //读取时间 窗体加载时完成
{
try
{
StreamReader sr = new StreamReader(path, Encoding.UTF8);
DateTime line;
line = Convert.ToDateTime(sr.ReadLine());
hsum = line.Hour;
msum = line.Minute;
ssum = line.Second;
TSsum = new TimeSpan(hsum, msum, ssum); //记录读取的总时间
label8.Text = line.Hour.ToString() + ":" + line.Minute.ToString() + ":" + line.Second.ToString();
sr.Dispose();
}
catch { };
}
你能看到这个函数有两个功能,一个读取时间、一个写入时间,所以这个函数有两个地方被调用到。
读取:初始化程序时调用了(Initial());
写入:当计时器为0时调用(timer);
当点击结束按钮时,设置时间并未到0(相当于强制关闭)用到了。
好了,这个功能做了。那么我们还有一个功能没做,那就是添加游戏名称到我们gamename泛型集合中,当然你可以手动gamename.add("游戏名称");但是我们能不能更人性化、智能化一点呢,答案肯定是可以的。
那我们要做的就是点击“扫描全盘按钮”。它的原理是点击后开启一个新窗体(子窗体)选择要搜索的分区,如果找到了与我们游戏库(这也是一个泛型集合)中名称相同的就记录返回到我们主窗体中的gamename集合中。
先上图
3个checkbox根据选择状态,返回一个值(C、D、E),点击确定开始搜索。搜索完毕,返回找到的游戏名称。
这里特别说一下checkbox的size要重新设置下,我原来以为它的大小就是那个小方框。其实它要大的多,如果间距设小了,其他的checkbox就被挡住了(效果就是只有一个),我当时做的时候卡在这里半天,我还以为出现了灵异事件,最后问了下老师才知道。
那么有人要问了为什么会是C、D、E,我有F盘呢?别急。我们首先在初始化窗体时遍历一遍盘符、统计。
List<string> gameBase = new List<string>(); //我们的游戏库
//窗体加载
private void ChooseArea_Load(object sender, EventArgs e)
{
int drivesCount = System.IO.Directory.GetLogicalDrives().Length;//获取盘符数
CheckBox[] box=new CheckBox[drivesCount];
int x = ;
for (int i = ; i < drivesCount;i++ )
{
box[i] = new CheckBox();
char abc =Convert.ToChar('C'+i); //从C开始+1,转成(D、E...)
box[i].Text = abc+ "盘"; //checkbox空间名称 生成
box[i].Name=abc.ToString();
box[i].Size = new Size(,);
box[i].Location = new Point(x,);
groupBox1.Controls.Add(box[i]);
x += ;//3个box的横轴间距
}
gameBase.Add("tgp_daemon.exe"); //添加游戏进程名称
gameBase.Add("Client.exe");
}
这样就能生成相应的checkbox数量了。
然后点击确定button,返回有哪些盘被选中再构建路径去磁盘里搜索。
//确定按钮
private void button1_Click(object sender, EventArgs e)
{
List<string> check = new List<string>();//存储选中状态下的checkbox值(C盘、D盘、...)
foreach (Control c in groupBox1.Controls)// 遍历groupbox容器里的控件
{
if (c is CheckBox) //如果类型为Checkbox
{
if (((CheckBox)c).Checked == true) //判断是否为选中状态
{
check.Add(((CheckBox)c).Text);
}
}
}
for (int i = ; i < check.Count; i++)
{
//构建寻找路径(C:\\、D:\\...)
string path = check[].Substring(, )+":\\";
FindFiles(path); //开始搜索
this.Close(); //搜索完毕后,自动关闭子窗口
}
}
其中最重要的一环就是FindFiles(path)函数了。我们怎样将子窗口的搜索到的值返回给我们主窗体呢,那么委托和事件就登场了。
public delegate void GameListDelegate(string str);//声明委托
public event GameListDelegate GameNameUpdate;//声明事件
public void FindFiles(string subpath)
{
FindFile ff = new FindFile(); //新建一个FindFile类
for (int i = ; i < gameBase.Count; i++)
{
ff.getFile(subpath, gameBase[i]); //调用getFile函数,结果会存储在lis集合里。
textBox1.AppendText(ff.lst[i].ToString() + "\r\n");//显示
}
if (GameNameUpdate != null) //判断事件是否被注册
{
GameNameUpdate(textBox1.Text.ToString());
} }
然后GameNameUpdate这个事件在主窗体‘扫描全盘游戏’按钮点击事件里被注册上LoadGame;
private void addGame_Click(object sender, EventArgs e)
{
chooseArea ca = new chooseArea(); //实例化子窗体
ca.GameNameUpdate += LoadGame; //注册LoadGame事件
//ca.GameNameUpdate+=new chooseArea.GameListDelegate(LoadGame);
ca.Show();
}
//LoadGame函数
public void LoadGame(string str)
{
string fileName = @"\gamelist.txt";
string dirpath = System.Environment.CurrentDirectory;
string path = dirpath + fileName;
FileStream fs;
if (!File.Exists(path))
{
try
{
textBox1.Text = str;
Regex regex = new Regex("\r\n"); //因为子窗体传过来的值有换行符"\r\n";这里实例化一个正则表达式 regex类的对象来以字符串"\r\n"的形式进行分割
string[] name = regex.Split(str);
for (int i = ; i < name.Length-; i++)//因为分割后或多出一个""变量;所以长度-1
{
gamename.Add(name[i]); //导入gamename集合中 去查杀
}
fs = new FileStream(path, FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
for (int i = ; i < gamename.Count; i++)
{
sw.WriteLine(gamename[i]);
}
sw.Flush();
sw.Close();
}
catch { };
}
else
{
try
{
StreamReader sr = new StreamReader(path, Encoding.UTF8);
string line;
while ((line=sr.ReadLine()) != null)
{
gamename.Add(line);
textBox1.AppendText(line + "\r\n");
}
sr.Dispose();
}
catch { };
}
}
同样的生成一个文本文件,下次进入程序如果有就不用再扫描全盘了。
再返回我们的子窗体中的FindFiles函数中的FindFile类,它是我们搜索文件的关键。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ChooseArea
{
class FindFile
{
public List<FileInfo> lst = new List<FileInfo>();
public List<FileInfo> getFile(string path, string extName)//创建一个List<FileInfo>类型的函数
{
getdir(path, extName);//传入路径、文件名
return lst;
} private void getdir(string path, string extName)
{
try
{
//获取文件夹列表
string[] dirs = Directory.GetDirectories(path);
DirectoryInfo fdir = new DirectoryInfo(path);
FileInfo[] file = fdir.GetFiles(); //当前目录文件或目录不为空
if (file.Length != || dirs.Length != )
{
foreach (FileInfo f in file)
{
if (extName.ToLower().IndexOf(f.Name.ToLower()) >= ) //匹配上
{
lst.Add(f);
}
}
foreach (string d in dirs)
{
getdir(d, extName);//递归
}
}
}
catch
{ }
} }
}
好,这样一个程序就做成功了。呱唧,呱唧。
c#游戏进程杀手的更多相关文章
- Libgdx slg游戏进程记录
2月16日缩放居中,stage确定点击坐标,背景处理为actor 2月17日地图多次点击 2月19日stage确定点击位置(贝塞尔曲线六边形) 2月24日格式长度,读取xml属性解析btl保存 3月1 ...
- cocos2dx 3.9 微信授权登陆后游戏进程结束解决办法
找到 Cocos2dxActivity.java 文件夹 里面的 onDestroy() 方法 if (mGLSurfaceView != null) { Cocos2dxHel ...
- c#统计代码行数
小编,已经快学了两年编程了.昨天突发奇想,想统计下这些年到底写过多少行代码,于是做了一个这个小程序来统计代码行数.老规矩,先上图. 比较惭愧,写了两年只有2万多行.那我们还是进入下一项吧. 界面搭建我 ...
- 游戏外挂四之利用CE和OD查找被选中怪物和怪物列表
合肥程序员群:49313181. 合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入)Q Q:408365330 E-Mail:egojit@qq.com 这一节我们利 ...
- YY游戏私有云平台实践 (转自InfoQ )
作者 风河 发布于 2016年1月13日 | 讨论 编者按:YY游戏的页游早在2013年就在云平台上运行,其Cloud 1.0已经支撑几十万的同时在线用户.日前,YY游戏云平台进行了Cloud 2 ...
- 一个基于Myeclipse开发的Java打地鼠小游戏(Appletcation)
package javaes.zixue.wangshang.daima; 2 3 import java.awt.Cursor; import java.awt.Image; import java ...
- Java多线程中的进程,线程,并行,并发
2:什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,我们发现只有运行的程序才会出现进程. 进程:就是正在运行的程序. 进程是系统进行资源分配和调用的独立单位.每一个进程都有它自己的内 ...
- [cocos2d-x·解Bug]关于cocos2d-x游戏在android锁屏状态下播放Bgm的解决方法
最近<宠物联萌>在三星App上发布遇到一个问题:如果用户在锁定屏幕时解锁解到一半时取消解锁,这时用cocos2d-x开发的游戏就会出现游戏Bgm会恢复播放,但手机屏幕仍然是锁屏状态的Bug ...
- Java基础知识强化之多线程笔记03:进程与线程 和 多线程的意义
1. 要想了解多线程,必须先了解线程,而要想了解线程,必须先了解进程,因为线程是依赖于进程而存在. 2. 什么是进程? 通过任务管理器我们就看到了进程的存在. 而通过观察,我们发现只有运行的程序才会出 ...
随机推荐
- MAVEN 打包WAR
<build> <finalName>edu-web-boss</finalName> <resources> <resource> < ...
- LeetCode 563. Binary Tree Tilt (二叉树的倾斜度)
Given a binary tree, return the tilt of the whole tree. The tilt of a tree node is defined as the ab ...
- Spring MVC 快捷定义 ViewController
WHY : 为什么我们需要快捷定义 ViewController ? 在项目开发过程中,经常会涉及页面跳转问题,而且这个页面跳转没有任何业务逻辑过程,只是单纯的路由过程 ...
- 关于Python输出时间戳的问题
在我们的程序中,有时候想要知道程序的执行时间或者准确的停止时间,这时候就需要我们自己添加一个时间戳,以便我们做出判断和相应的处理. 下面是我亲测并收集的资料,菜鸟一枚,不全之处大神可给予补充和指正. ...
- 老的工程移植到AndroidStudio需要修改的注意事项
之前老的工程用android-apt编译,如果要在新的AndroidStudio编译至少需要修改一下几部分: 1. 修改project里的build.gradle dependencies { cla ...
- Java企业微信开发_Exception_02_java.security.InvalidKeyException: Illegal key size
今天换了重新装了一个jdk,然后运行昨天还好好的企业微信工程,结果启动的时候就给我报了这么个错: java.security.InvalidKeyException: Illegal key size ...
- 套接字(linux相关)
前言:略 一.前因 一切从tcp.udp开始. 众所周知,网络模型一般有两种模型,一种为OSI概念模型(七层),另一种为tcp/ip网络模型(四层). tcp/ip应用层对应OSI的应用层.显示层.会 ...
- Winsock网络编程笔记(1)----入门
今天第一次接触winsock网络编程,看的资料是Windows网络编程第二版.通过博客记住自己的看书笔记.. 在这里贴出第一个程序,虽然程序什么都没做,但以此作为入门,熟悉其网络编程风格.. #inc ...
- 删除链表中等于给定值val的所有节点。
样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1->2->4->5. /** * D ...
- 磁盘管理 之 parted命令添加swap,文件系统
第1章 磁盘管理 1.1 必须要了解的. 1.1.1 ps aux 命令中 RSS 与VSZ的含义 rss 进程占用的物理内存的大小 单位:kb : vsz 进程占用的虚拟的内存大小(物理内存+swa ...