IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

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

    lincyang发表于 2014-05-21 14:31:09
    love 0
    

    一、方案

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

    1. 主键HKEY_LOCAL_MACHINE,Software\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)打开注册表

    LONG Open( 
       HKEY hKeyParent,         //主键
       LPCTSTR lpszKeyName,     //子键名称
       REGSAM samDesired = KEY_READ | KEY_WRITE //操作权限,默认是读写
    ) throw( );

    2)保存键值

    LONG SetStringValue(
       LPCTSTR pszValueName,    //key名称
       LPCTSTR pszValue,        //值
       DWORD dwType = REG_SZ    //字符串类型,REG_SZ是字符串,REG_MULTI_SZ多字符串
    ) throw( );


    3)删除

    LONG DeleteValue( 
       LPCTSTR lpszValue      // Specifies the value field to remove.其实就是对应上面的pszValueName
    ) throw( );

    4)查询

    LONG QueryStringValue( 
       LPCTSTR pszValueName,   //key名称
       LPTSTR pszValue,        //返回查询此key的值
       ULONG* pnChars          //pszVaule的size,这个我也不是特别明了
    ) throw( );

    5)关闭

    LONG Close( ) throw( );

    2、获取当前exe路径

         CString path;
         GetModuleFileName(NULL,path.GetBufferSetLength(MAX_PATH+1),MAX_PATH);
         path.ReleaseBuffer();

    三、实现

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

    1、add

    void CAutoStart2Dlg::ClickCbAdd()
    {
        //HKEY_CURRENT_USER
        CRegKey myKey; 
        if(myKey.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run") != ERROR_SUCCESS) 
            AfxMessageBox(L"error open reg key!!!"); 
        else 
        {  
            TCHAR s[MAX_PATH];  
            DWORD len = MAX_PATH;  
            CString value;
            
            if(myKey.QueryStringValue(L"linc", s, &len) == ERROR_SUCCESS)
            {
                value = s; 
                AfxMessageBox(L"query success!! VALUE IS "+value); 
            }
            else
            {
                AfxMessageBox(L"query error!"); 
                CString path;
                GetModuleFileName(NULL,path.GetBufferSetLength(MAX_PATH+1),MAX_PATH);
                path.ReleaseBuffer();
    
                if(myKey.SetStringValue(L"linc", path) != ERROR_SUCCESS)
                {
                    AfxMessageBox(L"error SET VALUE!!!"); 
                }
                else
                {
                    AfxMessageBox(L"Add register success!");
                }
            }
    
        } 
        myKey.Close();
    }


    2、delete

    void CAutoStart2Dlg::ClickCbDelete()
    {
        //KEY_READ|KEY_WRITE|KEY_WOW64_64KEY//special
        CRegKey myKey; 
        if(myKey.Open(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run") != ERROR_SUCCESS) 
            AfxMessageBox(L"error open reg key!!!"); 
        else 
        {  
            CString result;
            LONG lRES = myKey.DeleteValue(L"linc");
            result.Format(L"error is :%d",lRES);
            if(lRES != ERROR_SUCCESS)
            {
                AfxMessageBox(L"error delete register!!!\n"+result); 
            }
            else
            {
                AfxMessageBox(L"delete register success!");
            }
        } 
        myKey.Close();
    }

    参考:

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

    源码:

    猛击我!








沪ICP备19023445号-2号
友情链接