玩转VC++实现程序开机运行及注册表修改

时间:2022-09-04 22:41:08

目录(?)[+]



一、方案

要实现Windows程序开机运行,需要在注册表中相关位置加入键值。所谓的键可以是你程序的名称,值就是你程序的所在目录。所谓的相关位置有两处:

  1. 主键HKEY_LOCAL_MACHINESoftware\Microsoft\Windows\CurrentVersion\Run下。

  2. 主键HKEY_CURRENT_USER, Software\Microsoft\Windows\CurrentVersion\Run下。

区别就是前者针对机器上所有用户,而后者只针对当前用户。

在编程中对主键HKEY_CURRENT_USER的修改并不需要很高的权限,而修改HKEY_LOCAL_MACHINE就需要admin权限。此时需要在VS中配置一下即可:项目(右键)--->属性--->配置属性--->链接器--->清单文件,UACExecution Level设成requireAdministrator

二、技术点

1、编辑注册表

我用ATL的CRegKey类实现成功,就谈谈这个类。官方文档在这里

我们将会使用5个函数,Open,SetStringValue,DeleteValue,QueryStringValue,Close。

1)打开注册表

[cpp]  view plain copy 玩转VC++实现程序开机运行及注册表修改 玩转VC++实现程序开机运行及注册表修改
  1. LONG Open(   
  2.    HKEY hKeyParent,         //主键  
  3.    LPCTSTR lpszKeyName,     //子键名称  
  4.    REGSAM samDesired = KEY_READ | KEY_WRITE //操作权限,默认是读写  
  5. throw( );  

2)保存键值

[cpp]  view plain copy 玩转VC++实现程序开机运行及注册表修改 玩转VC++实现程序开机运行及注册表修改
  1. LONG SetStringValue(  
  2.    LPCTSTR pszValueName,    //key名称  
  3.    LPCTSTR pszValue,        //值  
  4.    DWORD dwType = REG_SZ    //字符串类型,REG_SZ是字符串,REG_MULTI_SZ多字符串  
  5. throw( );  


3)删除

[cpp]  view plain copy 玩转VC++实现程序开机运行及注册表修改 玩转VC++实现程序开机运行及注册表修改
  1. LONG DeleteValue(   
  2.    LPCTSTR lpszValue      // Specifies the value field to remove.其实就是对应上面的pszValueName  
  3. throw( );  

4)查询

[cpp]  view plain copy 玩转VC++实现程序开机运行及注册表修改 玩转VC++实现程序开机运行及注册表修改
  1. LONG QueryStringValue(   
  2.    LPCTSTR pszValueName,   //key名称  
  3.    LPTSTR pszValue,        //返回查询此key的值  
  4.    ULONG* pnChars          //pszVaule的size,这个我也不是特别明了  
  5. throw( );  

5)关闭

[cpp]  view plain copy 玩转VC++实现程序开机运行及注册表修改 玩转VC++实现程序开机运行及注册表修改
  1. LONG Close( ) throw( );  

2、获取当前exe路径

[cpp]  view plain copy 玩转VC++实现程序开机运行及注册表修改 玩转VC++实现程序开机运行及注册表修改
  1. CString path;  
  2. GetModuleFileName(NULL,path.GetBufferSetLength(MAX_PATH+1),MAX_PATH);  
  3. path.ReleaseBuffer();  

三、实现

下面的代码只是作为测试用,并不十分文雅,只是为大家展示一下解决方案,特此声明。
我在MFC的对话框中加两个按钮,一个是增加键值,另一个删除键值。增加键值也就是设置好开机启动,删除就是取消开机启动。
代码如下: 

1、add

[cpp]  view plain copy 玩转VC++实现程序开机运行及注册表修改 玩转VC++实现程序开机运行及注册表修改
  1. void CAutoStart2Dlg::ClickCbAdd()  
  2. {  
  3.     //HKEY_CURRENT_USER  
  4.     CRegKey myKey;   
  5.     if(myKey.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run") != ERROR_SUCCESS)   
  6.         AfxMessageBox(L"error open reg key!!!");   
  7.     else   
  8.     {    
  9.         TCHAR s[MAX_PATH];    
  10.         DWORD len = MAX_PATH;    
  11.         CString value;  
  12.           
  13.         if(myKey.QueryStringValue(L"linc", s, &len) == ERROR_SUCCESS)  
  14.         {  
  15.             value = s;   
  16.             AfxMessageBox(L"query success!! VALUE IS "+value);   
  17.         }  
  18.         else  
  19.         {  
  20.             AfxMessageBox(L"query error!");   
  21.             CString path;  
  22.             GetModuleFileName(NULL,path.GetBufferSetLength(MAX_PATH+1),MAX_PATH);  
  23.             path.ReleaseBuffer();  
  24.   
  25.             if(myKey.SetStringValue(L"linc", path) != ERROR_SUCCESS)  
  26.             {  
  27.                 AfxMessageBox(L"error SET VALUE!!!");   
  28.             }  
  29.             else  
  30.             {  
  31.                 AfxMessageBox(L"Add register success!");  
  32.             }  
  33.         }  
  34.   
  35.     }   
  36.     myKey.Close();  
  37. }  


2、delete

[cpp]  view plain copy 玩转VC++实现程序开机运行及注册表修改 玩转VC++实现程序开机运行及注册表修改
  1. void CAutoStart2Dlg::ClickCbDelete()  
  2. {  
  3.     //KEY_READ|KEY_WRITE|KEY_WOW64_64KEY//special  
  4.     CRegKey myKey;   
  5.     if(myKey.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run") != ERROR_SUCCESS)   
  6.         AfxMessageBox(L"error open reg key!!!");   
  7.     else   
  8.     {    
  9.         CString result;  
  10.         LONG lRES = myKey.DeleteValue(L"linc");  
  11.         result.Format(L"error is :%d",lRES);  
  12.         if(lRES != ERROR_SUCCESS)  
  13.         {  
  14.             AfxMessageBox(L"error delete register!!!\n"+result);   
  15.         }  
  16.         else  
  17.         {  
  18.             AfxMessageBox(L"delete register success!");  
  19.         }  
  20.     }   
  21.     myKey.Close();  
  22. }  

参考:

http://blog.csdn.net/chain2012/article/details/5565806
http://blog.csdn.net/weiwenhp/article/details/9381717

源码:

猛击我!