MFC定时关机程序的实现2-添加启动项到注册表

虽然上一篇实现了的定时关机,但是还不够完善,比如开机自动启动,然后按照配置的时间定时关机,并最小化到任务栏。

先来说开机启动怎么实现,开机启动实现的方法有好几种,比如直接在开始菜单启动项里添加一个程序的快捷方式,路径为

  C:\ProgramData\Microsoft\Windows\Start
Menu\Programs\Startup\

  不过这个路径不同的电脑可能不一样,因为这个路径可以改变,比如说改到D盘

也可以直接写入注册表,这个比较方便,这个开机启动项在注册表中的路径是

  HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run

WIN7
64位的注册表启动位置,这个根键和原来的不一样,路径也不一样。

  HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run

最小化到任务栏的实现需要NOTIFYICONDATA,这个结构体就可以实现我们需要的功能,并可以处理一些事件。

下面详细说说怎么实现。

1.先说注册表的实现

  几个和注册表相关的重要函数

RegOpenKeyEx,RegGetValue,RegSetValueEx,GetModuleFileName,RegDeleteValue,RegCloseKey

打开注册表中的某一项,如果成功就返回ERROR_SUCCESS,否则返回错误值,可在Winerror.h查找错误


1 LSTATUS RegOpenKeyEx(
2 HKEY hKey,//根键
3 LPCTSTR lpSubKey,//子健
4 DWORD ulOptions,//保留参数,必须设置为0
5 REGSAM samDesired,//子健的使用权限
6 PHKEY phkResult//返回的值项的操作对象
7 );

然后就是获取值项的键值,函数成功则返回ERROR_SUCCESS,错误情况参照Winerror.h


1 LONG WINAPI RegGetValue(
2 _In_ HKEY hkey,//根键
3 _In_opt_ LPCTSTR lpSubKey,//子健
4 _In_opt_ LPCTSTR lpValue,//值项的名称
5 _In_opt_ DWORD dwFlags,//值项的限制类型,包括RRF_ANY,这个没有类型限制,可以是下一个参数的任何类型,其他的不多说了
6 _Out_opt_ LPDWORD pdwType,//值项的数据类型,包括主要的四种,REG_BINARY,REG_DWORD,REG_SZ,DEFAULT
7 _Out_opt_ PVOID pvData,//获取的字符串
8 _Inout_opt_ LPDWORD pcbData//字符串结构的大小
9 );

打开启动路径后我们首先检查是否已经添加过启动项,结果体现在复选按钮上。然后我们设置值项的值


1 LONG WINAPI RegSetValueEx(
2 _In_ HKEY hKey,//子健
3 _In_opt_ LPCTSTR lpValueName,//值项名称
4 _Reserved_ DWORD Reserved,//保留,为0
5 _In_ DWORD dwType,//类型
6 _In_ const BYTE *lpData,//数据字符串
7 _In_ DWORD cbData//数据大小,不包括结束支字符
8 );

还有一个函数用来获取当前运行的程序的路径,这个需要在设置注册表值时用到,返回值为程序路径名的长度

1 DWORD WINAPI GetModuleFileName(
2 _In_opt_ HMODULE hModule,//加载的模式,这里选择为NULL,默认加载当前进程的路径
3 _Out_ LPTSTR lpFilename,//用来保存文件路径的字符串
4 _In_ DWORD nSize//字符串大小
5 );

如果复选按钮为空的话,就从注册表里删除值项

1 LONG WINAPI RegDeleteValue(
2 _In_ HKEY hKey,//子健
3 _In_opt_ LPCTSTR lpValueName//值项名称
4 );

最后操作完成关闭注册表

LONG WINAPI RegCloseKey(
_In_ HKEY hKey//子健
);

需要这么几个重要函数,下面来说具体过程

  首先我们在程序启动后检查注册表里是否已经存在这个程序的启动项,如果存在就将结果保存在成员变量isInStartUp里,否则将isInStartUp设置为false,如果已经添加,就将复选按钮设置为选中状态,在OnInitDialog()里实现如下


 1 //获取启动项
2 HKEY key;
3 LPCTSTR szRun = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";//启动项的路径
4 if (RegOpenKeyEx(HKEY_CURRENT_USER,szRun,0,KEY_ALL_ACCESS,&key) == ERROR_SUCCESS)
5 {
6 char szFileName[MAX_PATH] = {0};
7 //DWORD dRet = GetModuleFileName(NULL,szFileName,MAX_PATH);
8 DWORD type = REG_SZ;
9 DWORD bufSize = sizeof(szFileName);
10 char file[MAX_PATH] = {0};
11 long lRet = RegGetValue(HKEY_CURRENT_USER,szRun,"ShutDown",RRF_RT_ANY,&type,szFileName,&bufSize);
12 if (lRet == ERROR_SUCCESS)
13 {
14 isInStartUp = true;//已经添加启动项,设置checkbox为选中状态
15 m_checkbox.SetCheck(BST_CHECKED);
16 //MessageBox(szFileName);
17 }
18 else
19 {
20 isInStartUp = false;
21 m_checkbox.SetCheck(BST_UNCHECKED);
22 }
23 }
24 else
25 {
26 MessageBox("打开注册表失败");
27 }
28 RegCloseKey(key);

这个不用多解释,很简单。接着来,在单击过确定按钮后处理添加启动项,在OnBnClickedOk()处理后续操作


 1     //首先检查复选框是否选中
2 UINT ischecked = IsDlgButtonChecked(IDC_CHECK1);
3
4 //获取选择的时间
5 hour = m_com_hour.GetCurSel();
6 minute = m_com_minute.GetCurSel();
7 second = m_com_second.GetCurSel();
8
9 //数据进行格式化处理
10 CString str = "";
11 str.Format("%2d时%2d分%2d秒", hour, minute, second);
12 // GetDlgItem(IDC_STATIC_NOW)->SetWindowText(str);
13 int resoult = MessageBox("确定要在"+str+"关机吗?","是否关机?",MB_OKCANCEL);
14 if (resoult == IDOK)
15 {
16 //是否添加到启动项
17 AutoStart(ischecked);
18 //更新程序窗口中显示的关机时间
19 GetDlgItem(IDC_STATIC_SHUT)->SetWindowText(str);
20 ........
21 .........
22 }

上面关于注册表的操作封装到了函数AutoStart()中。


 1 //是否添加到启动项
2 void CAutoShutDownDlg::AutoStart(UINT check)
3 {
4 UINT ischecked = check;
5 //打开注册表选项
6 HKEY key;
7 LPCTSTR szRun = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
8 if (RegOpenKeyEx(HKEY_CURRENT_USER,szRun,0,KEY_SET_VALUE,&key) == ERROR_SUCCESS)
9 {
10 if (ischecked != 0 )//选中
11 {
12 //打开成功,设置开机启动项
13 char szFileName[MAX_PATH] = {0};
14 //获取当前进程的路径
15 DWORD dRet = GetModuleFileName(NULL,szFileName,MAX_PATH);
16 // 添加一个值项,即添加开机启动项,第二个参数为应用程序名,不加.exe后缀
17 long lRet = RegSetValueEx(key,"ShutDown",0,REG_SZ,(BYTE *)szFileName,dRet);
18 if (lRet != ERROR_SUCCESS)
19 {
20 MessageBox("添加启动项失败");
21 }
22 else if(lRet == ERROR_SUCCESS)
23 {
24 isInStartUp = true;
25 MessageBox("添加启动项成功");
26 }
27 }
28 else if (ischecked == 0 && isInStartUp)
29 {
30 long lRet = RegDeleteValue(key,"ShutDown");
31
32 if (lRet != ERROR_SUCCESS)
33 {
34 MessageBox("删除错误");
35 }
36 }

37 }
38 RegCloseKey(key);
39 }

好了,就这样吧,最小化到任务栏后面再说

MFC定时关机程序的实现2-添加启动项到注册表

时间: 2024-10-27 05:42:19

MFC定时关机程序的实现2-添加启动项到注册表的相关文章

MFC定时关机程序的实现1

写个定时关机程序自用,界面简单实用,最终界面如下 第一步,新建一个MFC对话框应用程序,拖几个控件过来, 界面如下: 然后给下拉列表框,复选按钮绑定变量,以方便进行操作. CComboBox m_com_hour; CComboBox m_com_minute; CComboBox m_com_second; 第二步,先实现简单关机功能,不通过文件读写进行关键.在选择过时间后,确定关机后按时关机. 1,给下拉列表框添加更改事件,直接右键控件->选择添加事件处理程序,选择CBN_SELCHANGE

C语言 -- 定时关机程序

<strong><span style="font-size:14px;">C语言  --  定时关机程序</span></strong> <strong></strong><span style="font-size:14px;"></span> <strong><span style="font-size:14px;">特别

用Win32写的定时关机程序

由于本人记性不太好,晚上经常忘记关电脑,白白浪费了很多的电.在网上也找了一些定时关机的软件,想到最近自己也在学习VC++,就想自己写一个定时关机的小程序,正好也可以检验自己所学的东西. 程序源码下载地址:点击下载 先来看看效果图: 写的比较简陋,但是只要能实现功能就好了. 写Win32应用程序首先要有WinMain函数: int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR    lpCmdLine

32位程序访问64位系统上的Windows注册表

今天在工作的过程中遇到个奇怪的为问题,就是通过c#获取注册表键值的问题,一般都比较简单: string SQLPath = string.Empty; RegistryKey hkml = Registry.LocalMachine; RegistryKey MSSQLServerKey = hkml.OpenSubKey(@"SOFTWARE\MICROSOFT\MSSQLServer"); if (MSSQLServerKey != null) { string[] keys =

CentOS 7系统添加启动项

CentOS 7系统已经把CentOS 6的 runlevel 系统服务管理替换成了systemd.在 /etc/rc[0-6S].d 下添加启动项已经不能在系统启动的时候自动执行,需要通过新的 systemd.unit 配置添加启动项. systemd 特点 1. 可以指定unit间的依赖关系 2. 可以控制unit间的执行顺序或允许它们并发执行 简单的例子 该例子的功能是通过systemd配置一个启动项 1. 在 /usr/lib/systemd/system 目录下创建一个文件 myser

在防火墙的例外中注册程序(Windows7和XP),改写注册表

在写程序的时候,经常遇到被防火墙拦截的情况,尤其是一些网络程序,不管是对外访问还是外部连接,都会被拦截. 在大多情况下,Windows会静默拦截外部对内的连接访问,而内部对外的访问会提示用户信息. 现在我们需要把自己的程序加入到防火墙的例外之中去,好让程序之间能够正常通信. 第一种方法是读写注册表的方式: XP下是这几个键值(有的时候貌似只用2个键就行,但情况不同,最保险的方式是这4个键都写): [c-sharp] view plain copy 1.  HKEY_LOCAL_MACHINE/S

程序自启动位置(8种方法,注册表有6处)

如果系统启动时自动加载的程序过多,会造成启动速度缓慢,而很多病毒或者木马也是在系统启动时自动加载的.所以了解怎样在Windows中查找自启动程序是非常重要的. 一.在“启动”文件夹中寻找 “启动”文件夹一般位于“系统盘符/Documents and Settings/用户名/开始菜单/程序/启动/”目录(Win 2000/XP)或“系统盘符/WINDOWS/Start Menu/Programs/启动/”目录.通过快捷方式的属性可以查出程序所在的位置. 二.从自动批处理文件中寻找 在Win 98

LINUX下EFIBOOTMGR的使用,删除UEFI主板多余启动项和添加启动项

用uefi装了几次次archlinux,搞的uefi启动选项下多出来好多启动项..这东西重格硬盘也是不好用的.发现以下方法可以解决. efibootmgr   //显示efi的启动项 删除一个引导项 # efibootmgr -b 0001 -B 其中 0001是要删除的引导项编号,通过 efibootmgr命令可以直接查看.输出如下所示: # efibootmgr BootCurrent: 0001Timeout: 1 secondsBootOrder: 0001,000B,0000,0080

在亚马逊linux环境上装mysql+添加启动项

安装mysql sudo yum install mysql sudo yum install mysql-server sudo yum install mysql-devel 添加到系统启动项sudo chkconfig mysqld on 可以check一下sudo chkconfig --list mysqld