您的位置:首页 > 其它

MFC实现程序开机自动运行

2010-07-17 22:51 267 查看
话说,最近在搞windows编程(地球人都知道啦!哪个地球人?哈哈!)……
在做一个备忘录这样的小工具,希望它能够每次开机自动启动,真正做到备忘的功能(汗,我就怕自己忘记打开)~
废话少说,入正题!!!
一点背景:
1、实现程序在windows启动时自动运行大概有以下途径:
详情可以参考这个链接 http://topic.csdn.net/t/20050615/20/4085135.html
自启动目录;
win.ini启动;
修改注册表的键值(一般软件都是这么干的,这里给出的方式也是这么干的,不过也是最明显,最容易被发现的方式);
如果想绕过杀毒软件或者其他监控软件的侦测……
可以把程序写成一个系统服务;
或者干脆写驱动;
至于什么用Hook、应用rootkit技术这么邪恶的东西,我最讨厌了啦!!!(虽然我不是身价4K绿坝娘,哈哈!)

2、通过在注册表中创建键值和修改键值达到windows启动时程序自动运行的目的:
代码基本思路(假设已经知道如何通过手动的方式,打开注册表,修改键值,自动启动一个程序):
第一步:写一个函数( void function(void);),在函数体内,对注册表进行操作,从中写入相关键值,达到目的。

第二步:定义这个函数,实现流程如下:
1 获取当前运行程序的文件名(注:这里的文件名是指程序的完整路径加上exe本身带扩展名的名字,例如:C:/run.exe)
2 创建一个与当前程序相关联的注册表键值,利用RegOpenKeyEx函数;
3 设置该键值,实现程序随windows启动自动运行,利用RegSetValueEx函数;
4 释放该键值的句柄,利用RegCloseKey函数,请别忽略和忘记这步;

第三步:寻找相应的API函数或者方法,编码

注:以下列出的几个主要函数都可以在msdn中查找得出,为了节省时间,我会列出它们并且简要说说它们的用途:

WINAPI DWORD GetModuleFileName(

HMODULE hModule,

LPWSTR lpFilename,

DWORD nSize

);
获得文件的全文件名;

LPCWSTR GetBufferSetLength(

int nNewLength

) throw (CHeap_Exception);

给对象分配一定字节数的内存空间,返回一个指向该缓冲区的指针。这个函数最好跟ReleaseBuffer方法配合使用;

void ReleaseBuffer(

int nNewLength =
-1

) throw (CHeap_Exception);

与上面的方法配合使用,释放多余的内存空间;

如果是刚刚入门windows编程的童鞋,除了围观MSDN之外,还可以参看这个链接http://wenku.baidu.com/view/7c894deae009581b6bd9ebca.html
了解一下这几个方法的用途和区别,以及值得注意的地方。CString类的方法很常用,但是也很容易导致出错。

/////////////////////////////////////贼核心的东东来了/////////////////////////////////////

LONG WINAPI RegOpenKeyEx(

__in HKEY hKey,

__in LPCTSTR lpSubKey,

DWORD ulOptions,

__in REGSAM samDesired,

__out PHKEY phkResult

);
传入一个HKEY类型的句柄,指向存放文件名的字符串的指针,一个必须为0的DWORD值,一个说明权限的REGSAM类型(这不是我们要关心的主要东西),以及一个指向HKEY的指针(指向该句柄的指针),打开/创建一个与当前运行文件相关联的注册表键。
这里有点类似于C++标准文件操作中的,打开文件或者创建文件操作,以下的流程都可以与C++的文件操作进行类比。

LONG WINAPI RegSetValueEx(

__in HKEY hKey,

__in LPCTSTR lpValueName,

DWORD Reserved,

__in DWORD dwType,

__in const BYTE* lpData,

__in DWORD cbData

);

这个函数就是用于设置刚才我们打开的键的键值东东了。参数之类的跟之前的RegOpenKeyEx大同小异,详情可以去看MSDN,某些细节会在代码的注释中有所体现。

LONG WINAPI RegCloseKey(

__in HKEY hKey

);

关闭该键,没啥说的,鬼混完总得回家吧?或者搞完破坏之后要收拾残局?呵呵!

上代码~~~
平台:windows7 Ultimate,集成开发环境:visual studio 2010 Ultimate 以及 Visual Assist X 10.6.1822.0;框架:MFC
以下代码在上述运行环境里编译通过,并成功运行,效果良好,绿色河蟹~

void function( void )
{
//获取包含路径的全文件名
CString sPath;
GetModuleFileName( NULL, sPath.GetBufferSetLength(MAX_PATH + 1), MAX_PATH ); //(MAX_PATH + 1)是为了预留多一个空间给空字符
sPath.ReleaseBuffer(); //如果sPath的长度少于MAX_PATH,则释放多余的空间

//为下面的对注册表进行操作的函数做些初始化工作
LPSTR lpPath = (LPSTR)(LPCTSTR)sPath;
DWORD cbData = MAX_PATH; /*strlen(lpstr)*/;
HKEY hkey; //这里是键的句柄
LONG lIsSuccess; //一个LONG类型,用来接收以下两个函数的返回值,以判断是否成功创建和修改了注册表的键和键值

lIsSuccess = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
_T("SOFTWARE//Microsoft//Windows//CurrentVersion//Run//"),
0, //这个值必须为0
KEY_WRITE,
&hkey );

if( lIsSuccess == ERROR_SUCCESS ) { //运行情况的一些反馈,这里用了MessageBoxW,主要是方便调试,真正应用的时候可以删掉
MessageBoxW( _T("Succeeded in RegOpenKeyEx!"), _T("warning"), NULL );
} else {
MessageBoxW( _T("Fail in RegOpenKeyEx..."), _T("warning"), NULL );
abort(); //如果打开或者创建失败,则异常中断程序
}

lIsSuccess = RegSetValueEx( hkey,
_T("MyMFC"),
0,
REG_SZ,
/*(const unsigned char*)(LPCTSTR)sPath,*/(CONST BYTE *)lpPath, //注释中的内容可以替换没被注释的代码
/*sPath.GetLength()*/cbData ); //利用注释里面的代码,能够节省一点内存空间

if( lIsSuccess == ERROR_SUCCESS ) {
MessageBoxW( _T("Succeeded in RegSetValueEx!"), _T("warning"), NULL );
} else {
MessageBoxW( _T("Fail in RegSetValueEx..."), _T("warning"), NULL );
abort(); //如果打开或者创建失败,则异常中断程序
}

RegCloseKey(hkey); //当然不忘释放句柄
return ;
}

俺很青菜,欢迎各位大牛拍照拍砖。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: