[C#] 窗体穿透效果、禁用任务管理器、键盘钩子
December 19, 2015也许你碰巧需要写个恶搞程序来整整室友呢?
先说说要的效果.让别人的电脑出现灰蒙蒙的样子,但是又能使用鼠标键盘且还算正常的使用电脑,却又不能关掉这个程序.
没错.就是这么的贱.
使用 VS2015+Windows10
分成几块来做
- 达到灰蒙蒙的界面效果且鼠标键盘能用.
- 让用户不能关掉程序.
- 留个可以偷偷关掉程序的后门.
- 或许可以放别人电脑上设置开机自启动(小心被砍)
首先窗口虽然灰色,但是期待的效果应该是鼠标键盘都可用.但是任务栏上不能看到这个正在运行的程序,这点很容易办到.
1. 灰色界面效果
1.关键API:
SetWindowLong
和GetWindowLong
SetWindowLong
函数,该函数用于为指定的窗口设置信息.
声明如下:
[DllImport("user32", EntryPoint = "SetWindowLong")]
private static extern uint SetWindowLong(IntPtr hwnd, int nIndex, uint dwNewLong);
参数说明
- hwnd: IntPtr,为其取得消息的窗口的句柄.
- nIndex: int类型,准备取回的信息,其常数说明自行Google.
- dwNewLong: uint类型,由nIndex制定的窗口信息的新值.
- 返回值: uint类型,制定数据的前一个值.
GetWindowLong
函数,和上面一个相反,用于从指定窗口的结构中取得信息.且
语法如下:
[DllImport("user32", EntryPoint = "GetWindowLong")]
private static extern uint GetWindowLong(IntPtr hwnd, int nIndex);
参数说明参考上一个函数.
2.窗体部分.
- 新建窗口,FromBorderStyle属性设置为None. (无边框)
- 添加NotifyIcon控件,设置提示信息.
2.任务栏取消显示
取消在任务栏显示很容易办到.只需要设置窗体的ShowInTaskbar
属性为false即可
另外,我们还需要让窗体始终在其他窗体之上. 需设置窗体的 TopMost
为true.
第一步的代码写在了源码的窗体类中,加上第二部的代码,在窗体初始化时只需做如下初始化.
方法写在了主窗体的类中.在窗体初始化时,直接调用即可.
private void Frm_Main_Load(object sender, EventArgs e)
{
this.ShowInTaskbar = false;//窗体不出现在Windows任务栏中
CanPenetrate();
this.TopMost = true;//使窗体始终在其它窗体之上
}
步骤1的几个方法源码:
private void CanPenetrate()
{
uint intExTemp = GetWindowLong(this.Handle, GWL_EXSTYLE);
uint oldGWLEx = SetWindowLong(this.Handle, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);
}
#endregion
#region 设置颜色和透明度的状态
/// <summary>
/// 设置颜色和透明度的状态
/// </summary>
private void SetEstate(Form Frm, object sender)
{
Var_genre = ((ToolStripMenuItem)sender).Name;
string Tem_Str = Var_genre;
if (Var_genre.IndexOf('_') >= 0)
{
Var_genre = Tem_Str.Substring(0, Tem_Str.IndexOf('_'));
}
switch (Var_genre)
{
case "ToolColor":
{
Color Tem_Color=Color.Gainsboro;
switch (Convert.ToInt32(((ToolStripMenuItem)sender).Tag.ToString()))
{
case 1: Tem_Color = Color.Gainsboro; break;
case 2: Tem_Color = Color.DarkOrchid; break;
case 3: Tem_Color = Color.RoyalBlue; break;
case 4: Tem_Color = Color.Gold; break;
case 5: Tem_Color = Color.LightGreen; break;
}
Frm.BackColor = Tem_Color;
break;
}
case "ToolClarity":
{
double Tem_Double = 0.0;
switch (Convert.ToInt32(((ToolStripMenuItem)sender).Tag.ToString()))
{
case 1: Tem_Double = 0.1; break;
case 2: Tem_Double = 0.2; break;
case 3: Tem_Double = 0.3; break;
case 4: Tem_Double = 0.4; break;
case 5: Tem_Double = 0.5; break;
case 6: Tem_Double = 0.6; break;
case 7: Tem_Double = 0.7; break;
case 8: Tem_Double = 0.8; break;
case 9: Tem_Double = 0.9; break;
}
Frm.Opacity = Tem_Double;
break;
}
case "ToolAcquiescence":
{
Frm.BackColor = Color.Gainsboro;
Frm.Opacity = 0.6;
break;
}
case "ToolClose":
{
Close();
break;
}
}
}
#endregion
private void ToolColor_Glass_Click(object sender, EventArgs e)
{
SetEstate(this, sender);
}
上面三部分代码加起来的效果:
有个很明显的问题任务栏是看不到程序了,但是任务管理器可以直接结束掉。。。所以继续看。
3.为了不让用户关掉程序,需要禁用任务管理器。
传统的方法是检测任务管理器的进程
taskmgr
。隔一掉段时间检查一遍,发现就强制关掉,造成任务管理器不能用的假象。但是指标不治本。查阅了资料找到了另外一种方法,修改注册表HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System
中的DisableTaskmgr
键值。键值为1时,任务管理器不可用。
private void forbidTaskManager(int arg)
{
RegistryKey currentUser = Registry.CurrentUser;
RegistryKey system = currentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);
if (system == null)
{
system = currentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System");
}
system.SetValue("DisableTaskmgr", arg, RegistryValueKind.DWord);
currentUser.Close();
}
直接在Frm_Main_Load
中调用forbidTaskManager
方法即可.传入1禁用任务管理器.
到这一步请先别急着测试.因为修改注册表需要首先给程序获取管理员权限.用管理员权限运行EXE文件之后.你怎么关掉呢?别坑了自己.所以,得留个后门.请继续看.
4.全局监控按键,为程序留个关闭的小后门.
关于C#全局键盘的监听请参考: C#全局键盘监听(Hook)
这里我不再多赘述.
如何使用:
将文章中的KeyboardHook类
放在源码项目中.
然后安装键盘钩子.将下面三行代码 写在Frm_Main_Load
中
k_hook = new KeyboardHook();
k_hook.KeyDownEvent += new KeyEventHandler(hook_KeyDown);//钩住键按下
k_hook.Start();//安装键盘钩子
并在主窗体中添加下面的函数.参考文章有说明.
private void hook_KeyDown(object sender, KeyEventArgs e)
{
//判断按下的键(Alt + A)
if (e.KeyValue == (int)Keys.A && (int)Control.ModifierKeys == (int)Keys.Alt)
{
//System.Windows.Forms.MessageBox.Show("按下了指定快捷键组合");
forbidTaskManager(0);//设置任务管理器为可用.
Application.Exit();//关闭程序
}
} 上面的代码是 不管何时当监听到按下(Alt + A)时,设置任务管理器可用,退出程序.
这时可以以管理员身份运行exe文件了.
运行程序后,界面变成灰色,鼠标键盘可用,且任务栏没有程序名,任务管理器不可用便无法关闭这个程序.
按下alt+A后恢复正常.
5.拓展
只是心血来潮看到一本书时弄的这个小程序,怎么用呢?复制到室友电脑上并且设置开机启动,然后…
设置开机启动请参考:设置开机启动的方法
其实还有很多不足的地方,比如说管理员权限的问题,包括win7以后的版本,增加了这个权限机制,修改注册表的时候,需要管理员权限.如何让程序自身取得权限是个问题,毕竟手动设置还要修改属性多点几下鼠标.
另外,整整室友只是说说而已,我并没有那么做也没有这个必要,只是学习C#啦 : )