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

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

2014-05-21 14:31 495 查看


一、方案

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

主键HKEY_LOCAL_MACHINE,Software\Microsoft\Windows\CurrentVersion\Run下。

主键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
源码:
猛击我!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: