Ved 启动管理器





5.00/5 (3投票s)
本文使用VC++编写,作为管理Windows启动应用程序的实用工具。
引言
启动程序是在Windows启动时自动启动或开始的条目。有些程序需要在Windows启动时自动启动,但启动列表中的大多数应用程序会占用系统内存和CPU。这还会增加系统的启动时间。其中一些程序会在后台运行,从而降低系统性能。因此,有必要根据您的需求管理启动应用程序。
背景
启动项是Windows操作系统的重要组成部分。通过Windows,我们可以使用“Windows Management Instrumentation”查看启动程序。要通过此过程查看启动程序,我们需要遵循以下步骤:
1) 打开命令提示符并键入命令“WMIC”,然后按“Enter”键。
2) 之后,键入“STARTUP”,然后按“Enter”键。
我们也可以通过“MSCONFIG”或“TASKMANAGER”查看启动程序。
关于启动项
在Windows操作系统上,我们可以通过两种方法使任何应用程序作为启动项运行。要么我们将执行命令(包含任何命令行参数的可执行路径)放入系统的注册表中,要么我们将应用程序的链接放入Windows操作系统的特殊文件夹中。
注册表
注册表中启动应用程序的位置如下:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce
RUN
在“RUN”子键中找到的命令会在用户每次登录计算机时启动。关于“RUN”子键下的命令的有趣点是:
- 此子键下的命令将在每次窗口登录后运行,而不是在启动时运行。
- 这些命令没有特定的执行顺序。
- 此键位于“HKEY_LOCAL_MACHINE”和“HKEY_CURRENT_USER”注册表配置单元下。
- 如果位于“HKEY_LOCAL_MACHINE”下,则命令会影响所有用户。
RUNONCE
此类别下的命令只运行一次。Windows在执行后会从“RunOnce”子键路径中删除这些命令。对于其他情况,“RUNONCE”子键与“RUN”类似。
要了解有关这些条目和其他启动项的更多信息,请参阅以下链接:
http://www.tenouk.com/ModuleP1.html
https://msdn.microsoft.com/en-us/library/windows/desktop/aa376977(v=vs.85).aspx
https://msdn.microsoft.com/en-us/windows/hardware/drivers/install/runonce-registry-key
https://support.microsoft.com/en-us/help/310593/description-of-the-runonceex-registry-key
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724072(v=vs.85).aspx
注意
- 如果您的操作系统是64位,则32位应用程序的启动项将存储在:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\RunOnce - Wow6432Node
要在64位计算机上管理32位应用程序,将使用“Wow6432Node”键。
启动文件夹
启动目录或文件夹包含在Windows登录后立即启动的快捷方式或可执行文件的列表。在Windows 8/10上,我们可以在以下路径找到它们:
所有用户
%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\StartUp
访问此路径的快捷方式:打开“运行”,键入“shell:common startup”并按 Enter。
用户配置文件/当前用户
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
访问此路径的快捷方式:打开“运行”,键入“shell:startup”并按 Enter。
使用的类
在详细阐述本文这一部分之前,我想感谢“Sven Wiegand”的文章《检索文件版本信息》。我在此应用程序中使用了“CFileVersionInfo”类来检索文件信息。您可以在此处找到它:
https://codeproject.org.cn/Articles/1502/CFileVersionInfo-Retrieving-a-File-s-full-Version
此实用程序的源代码包含以下类:
- CStartupDlg: 这是应用程序的主要类,负责用户界面。
- CCommonUtilities: 此类包含项目中使用的通用实用函数。
- CRegistryUtility: 此类包含项目所需的注册表操作函数。
- CAddNewStartupEntry: 这是对话框类,用于通过用户界面将新的启动项添加到注册表中。
使用代码
注册表实用函数
以下两个函数用于从注册表中访问启动项:
32BIT
void CRegistryUtility::Query32BitAppValues(const HKEY hRoot, const CString strSubKey, vector<pair<CString, CString>> &vecValueData)
/* ===================================================================================
NAME OF FUNCTION: Query32BitAppValues
CREDIT: Satish Jagtap
PURPOSE: Retrieve data from registry.
PARAMETERS: 1) [IN] const HKEY hRoot: Root key or hive
2) [IN] const CString strSubKey: Key path to retrieve data from
3) [OUT] vector<pair<CString, CString>> &vecValueData: List of
retrieved data entries
RETURN VALUE: None
CALLS TO: - QueryRegistryKeyForValAndData
CALLED FROM: - None
Added date: - 1 Jan, 2016
===================================================================================*/
{
HKEY hKey = NULL;
if(RegOpenKeyEx(hRoot, strSubKey, 0, KEY_ALL_ACCESS|KEY_WOW64_32KEY, &hKey) != ERROR_SUCCESS) return;
QueryRegistryKeyForValAndData(hKey, vecValueData);
RegCloseKey(hKey);
}
64BIT
void CRegistryUtility::Query64BitAppValues(const HKEY hRoot, const CString strSubKey, vector<pair<CString, CString>> &vecValueData)
/* ===================================================================================
NAME OF FUNCTION: Query64BitAppValues
CREDIT: Satish Jagtap
PURPOSE: Retrieve data from registry.
PARAMETERS: 1) [IN] const HKEY hRoot: Root key or hive
2) [IN] const CString strSubKey: Key path to retrieve data from
3) [OUT] vector<pair<CString, CString>> &vecValueData: List of
retrieved data entries
RETURN VALUE: None
CALLS TO: - QueryRegistryKeyForValAndData
CALLED FROM: - None
Added date: - 1 Jan, 2016
===================================================================================*/
{
HKEY hKey = NULL;
if(RegOpenKeyEx(hRoot, strSubKey, 0, KEY_ALL_ACCESS|KEY_WOW64_64KEY, &hKey) != ERROR_SUCCESS) return;
QueryRegistryKeyForValAndData(hKey, vecValueData);
RegCloseKey(hKey);
}
主要功能
- 从注册表的“RUN”和“RUNONCE”子项中检索所有启动项。
void CStartupDlg::RefreshStartupList_Enable()
/* ===================================================================================
NAME OF FUNCTION: RefreshStartupList_Enable
CREDIT: Satish Jagtap
PURPOSE: Refresh list control with enabled startup list.
PARAMETERS: None
RETURN VALUE: None
CALLS TO: - 1) CCommonUtilities::GetFullPathOfSelectedItem
2) CRegistryUtility::Query32BitAppValues
3) CRegistryUtility::Query64BitAppValues
4) FillStartUpList_Registry
5) ListStartupProgramsForSpecificUser
6) FillStartUpList_Folder
CALLED FROM: - 1) OnTvnSelchangedTreeStartupEntries
2) OnBnClickedButtonAddnew
3) OnFileAddNewStartupEntry
4) OnBnClickedButtonRemove
5) OnEditRemoveEntry
6) OnEditEditEntry
7) DisableSelectedEntries
Added date: - 1 Jan, 2016
===================================================================================*/
{
HTREEITEM hitemSelected = m_treectlStartupEntries.GetSelectedItem();
CString strSelectedItemText = m_treectlStartupEntries.GetItemText(hitemSelected);
CString strSelectedItemPath = m_objCommonUtilities.GetFullPathOfSelectedItem(m_treectlStartupEntries, hitemSelected);
if(strSelectedItemPath.Find(_T("Enabled Entries")) != -1)
{
/***************************************************/
//Enable/disable menu items
bool bEnable = false;
GetMenu()->EnableMenuItem(ID_EDIT_DISABLEENTRY, bEnable ? 0 : MF_ENABLED); //Enable "Disable Entry" menu item
GetMenu()->EnableMenuItem(ID_EDIT_ENABLEENTRY, bEnable ? 0 : MF_DISABLED | MF_GRAYED); //Disable "Enable Entry" menu item
GetMenu()->EnableMenuItem(ID_EDIT_REMOVEENTRY, bEnable ? 0 : MF_ENABLED); //Enable "Remove Entry" menu item
GetMenu()->EnableMenuItem(ID_EDIT_EDITENTRY, bEnable ? 0 : MF_ENABLED); //Enable "Edit Entry" menu item
m_ctlRemoveButton.EnableWindow(true); //Enable "Remove" button
m_ctlAddNewButton.EnableWindow(true); //Enable "Add New" button
/***************************************************/
if(strSelectedItemPath.Find(_T("Registry")) != -1)
{
m_lstctrlStartupDetailsFolder.ShowWindow(SW_HIDE);
m_lstctrlStartupDetailsRegistry.ShowWindow(SW_SHOW);
if(strSelectedItemPath.Find(_T("CurrentUser")) != -1) //Retrieve Current User entries
{
if(strSelectedItemPath.Find(_T("Run\\")) != -1)
{
if(strSelectedItemText == _T("32Bit"))
{
vector<pair<CString, CString>> vec32BitAppValueData;
m_objRegistryUtility.Query32BitAppValues(HKEY_CURRENT_USER, _T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"), vec32BitAppValueData);
//Fill list control with start up entries details
FillStartUpList_Registry(vec32BitAppValueData,
_T("HKEY_CURRENT_USER"),
_T("Run"),
_T("Enabled"),
_T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"));
}
else if(strSelectedItemText == _T("64Bit"))
{
vector<pair<CString, CString>> vec64BitAppValueData;
m_objRegistryUtility.Query64BitAppValues(HKEY_CURRENT_USER, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"), vec64BitAppValueData);
//Fill list control with start up entries details
FillStartUpList_Registry(vec64BitAppValueData,
_T("HKEY_CURRENT_USER"),
_T("Run"),
_T("Enabled"),
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"));
}
}
if(strSelectedItemPath.Find(_T("RunOnce\\")) != -1)
{
if(strSelectedItemText == _T("32Bit"))
{
vector<pair<CString, CString>> vec32BitAppValueData;
m_objRegistryUtility.Query32BitAppValues(HKEY_CURRENT_USER, _T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce"), vec32BitAppValueData);
//Fill list control with start up entries details
FillStartUpList_Registry(vec32BitAppValueData,
_T("HKEY_CURRENT_USER"),
_T("Run"),
_T("Enabled"),
_T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce"));
}
else if(strSelectedItemText == _T("64Bit"))
{
vector<pair<CString, CString>> vec64BitAppValueData;
m_objRegistryUtility.Query64BitAppValues(HKEY_CURRENT_USER, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"), vec64BitAppValueData);
//Fill list control with start up entries details
FillStartUpList_Registry(vec64BitAppValueData,
_T("HKEY_CURRENT_USER"),
_T("Run"),
_T("Enabled"),
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"));
}
}
}
else if(strSelectedItemPath.Find(_T("LocalUser")) != -1) //Retrieve Local User entries
{
if(strSelectedItemPath.Find(_T("Run\\")) != -1)
{
if(strSelectedItemText == _T("32Bit"))
{
vector<pair<CString, CString>> vec32BitAppValueData;
m_objRegistryUtility.Query32BitAppValues(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"), vec32BitAppValueData);
//Fill list control with start up entries details
FillStartUpList_Registry(vec32BitAppValueData,
_T("HKEY_LOCAL_MACHINE"),
_T("Run"),
_T("Enabled"),
_T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run"));
}
else if(strSelectedItemText == _T("64Bit"))
{
vector<pair<CString, CString>> vec64BitAppValueData;
m_objRegistryUtility.Query64BitAppValues(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"), vec64BitAppValueData);
//Fill list control with start up entries details
FillStartUpList_Registry(vec64BitAppValueData,
_T("HKEY_LOCAL_MACHINE"),
_T("Run"),
_T("Enabled"),
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"));
}
}
if(strSelectedItemPath.Find(_T("RunOnce\\")) != -1)
{
if(strSelectedItemText == _T("32Bit"))
{
vector<pair<CString, CString>> vec32BitAppValueData;
m_objRegistryUtility.Query32BitAppValues(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce"), vec32BitAppValueData);
//Fill list control with start up entries details
FillStartUpList_Registry(vec32BitAppValueData,
_T("HKEY_LOCAL_MACHINE"),
_T("Run"),
_T("Enabled"),
_T("SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce"));
}
else if(strSelectedItemText == _T("64Bit"))
{
vector<pair<CString, CString>> vec64BitAppValueData;
m_objRegistryUtility.Query64BitAppValues(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"), vec64BitAppValueData);
//Fill list control with start up entries details
FillStartUpList_Registry(vec64BitAppValueData,
_T("HKEY_LOCAL_MACHINE"),
_T("Run"),
_T("Enabled"),
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"));
}
}
}
}
else if(strSelectedItemPath.Find(_T("Startup Folders")) != -1)
{
m_lstctrlStartupDetailsFolder.ShowWindow(SW_SHOW);
m_lstctrlStartupDetailsRegistry.ShowWindow(SW_HIDE);
if(strSelectedItemText == _T("All Users"))
{
vector<CString> vecListOfStartupPrograms;
ListStartupProgramsForSpecificUser(CSIDL_COMMON_APPDATA, vecListOfStartupPrograms); //Retrieve startup programs from all user's app data
FillStartUpList_Folder(vecListOfStartupPrograms); //populate list control
}
else if(strSelectedItemText == _T("Current User"))
{
vector<CString> vecListOfStartupPrograms;
ListStartupProgramsForSpecificUser(CSIDL_APPDATA, vecListOfStartupPrograms); //Retrieve startup programs from current user's app data
FillStartUpList_Folder(vecListOfStartupPrograms); //populate list control
}
}
}
}
- 禁用注册表中选定的启动项。
void CStartupDlg::DisableSelectedEntries()
/* ===================================================================================
NAME OF FUNCTION: DisableSelectedEntries
CREDIT: Satish Jagtap
PURPOSE: Disable selected registry entries.
PARAMETERS: None
RETURN VALUE: None
CALLS TO: - 1) CCommonUtilities::GetSelectedItemsFromList
2) CCommonUtilities::SplitString
3) CINIUtility::WriteToINIFile
4) RemoveSelectedItemsFromList_Registry
5) RefreshStartupList_Enable
CALLED FROM: - 1) OnEditDisableEntry
Added date: - 1 Jan, 2016
===================================================================================*/
{
vector<CString> vecListSelectedItems;
TCHAR szPath[MAX_PATH] = {0};
CString strDirectory = _T("");
CString strDisabledEntries = _T("");
if(SUCCEEDED(SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, FALSE)))
{
strDirectory = szPath;
strDirectory.Replace(_T("\\"), _T("/"));
strDirectory += _T("/VedStartupManager/");
if(!PathIsDirectory(strDirectory)) CreateDirectory(strDirectory, NULL);
}
if(m_lstctrlStartupDetailsRegistry.IsWindowVisible())
{
m_objCommonUtilities.GetSelectedItemsFromList(m_lstctrlStartupDetailsRegistry, vecListSelectedItems);
if(vecListSelectedItems.size() > 0)
{
int nSelectedItems = vecListSelectedItems.size();
CString strFilePath = _T("");
for(int nIndex = 0; nIndex < nSelectedItems; nIndex++)
{
CStringArray saTokens;
CString strValueName = _T("");
CString strData = _T("");
CString strRoot = _T("");
CString strSubKey = _T("");
m_objCommonUtilities.SplitString(vecListSelectedItems[nIndex], _T(","), saTokens);
CString strAppName = _T("");
CString strKeyName = _T("");
CString strStringToWrite = _T("");
CString strINIFile = strDirectory + _T("DisabledEntries_Reg.ini");
strAppName = saTokens[2].Trim() + _T("\\") + saTokens[5].Trim();
strKeyName = saTokens[0].Trim();
strStringToWrite = saTokens[1].Trim();
m_objINIUtility.WriteToINIFile(strAppName, strKeyName, strStringToWrite, strINIFile);
}
RemoveSelectedItemsFromList_Registry(vecListSelectedItems, strDisabledEntries);
RefreshStartupList_Enable();
MessageBox(_T("Selected items are disabled file successfully."), _T("Startup Manager"), MB_OK);
}
else
{
MessageBox(_T("You have selected no entry/entries to disable."), _T("Startup Manager"), MB_OK);
}
}
}
- 启用选定的启动项。
void CStartupDlg::EnableSelectedEntries()
/* ===================================================================================
NAME OF FUNCTION: EnableSelectedEntries
CREDIT: Satish Jagtap
PURPOSE: Enable selected disabled registry entries.
PARAMETERS: None
RETURN VALUE: None
CALLS TO: - 1) CCommonUtilities::GetSelectedItemsFromList
2) CCommonUtilities::SplitString
3) CINIUtility::ReadWholeSectionDataFromINI
4) CRegistryUtility::SetApplicationOnStartup
5) RefreshStartupList_Disable
CALLED FROM: - 1) OnEditEnableEntry
Added date: - 1 Jan, 2016
===================================================================================*/
{
vector<CString> vecListSelectedItems;
TCHAR szPath[MAX_PATH];
CString strDirectory = _T("");
if(SUCCEEDED(SHGetSpecialFolderPath(NULL, szPath, CSIDL_APPDATA, FALSE)))
{
strDirectory = szPath;
strDirectory.Replace(_T("\\"), _T("/"));
strDirectory += _T("/VedStartupManager/");
}
if(m_lstctrlStartupDetailsRegistry.IsWindowVisible())
{
m_objCommonUtilities.GetSelectedItemsFromList(m_lstctrlStartupDetailsRegistry, vecListSelectedItems);
if(vecListSelectedItems.size() > 0)
{
int nSelectedItems = vecListSelectedItems.size();
CString strFilePath = _T("");
for(int nIndex = 0; nIndex < nSelectedItems; nIndex++)
{
CStringArray saTokens;
CString strAppName = _T("");
CString strKeyName = _T("");
CString strStringToWrite = _T("");
CString strRoot = _T("");
CString strSubKey = _T("");
CString strINIFile = strDirectory + _T("DisabledEntries_Reg.ini");
m_objCommonUtilities.SplitString(vecListSelectedItems[nIndex], _T(","), saTokens);
strRoot = saTokens[2].Trim();
strAppName = saTokens[2].Trim() + _T("\\") + saTokens[5].Trim();
strKeyName = saTokens[0].Trim();
strSubKey = saTokens[5].Trim();
vector<pair<CString, CString>> vecWholeSectionData;
m_objINIUtility.ReadWholeSectionDataFromINI(strINIFile, strAppName, vecWholeSectionData);
HKEY hRoot;
CString strApplicationPath;
if(strRoot.CompareNoCase(_T("HKEY_LOCAL_MACHINE")) == 0)
hRoot = HKEY_LOCAL_MACHINE;
else if(strRoot.CompareNoCase(_T("HKEY_CURRENT_USER")) == 0)
hRoot = HKEY_CURRENT_USER;
m_objRegistryUtility.SetApplicationOnStartup(hRoot, strSubKey, saTokens[0], saTokens[1]);
WritePrivateProfileString(strAppName, saTokens[0], NULL, strINIFile);
RefreshStartupList_Disable();
}
}
else
{
MessageBox(_T("You have selected no entry/entries to disable."), _T("Startup Manager"), MB_OK);
}
}
}
注意:要查看更多功能,请参阅本文随附的源代码。
使用应用程序
此应用程序可帮助您高效地管理Windows启动项。您可以轻松管理32位和64位启动项。您可以使用此实用程序对启动项执行以下操作:
- 添加新的启动项:将新的启动项添加到注册表。
- 启用条目:启用已禁用条目。
- 禁用条目:禁用注册表启动项。
- 删除条目:从注册表中删除启动项。
- 编辑条目:编辑现有启动项。
- 执行条目:执行启动项。
- 导出到文本文件:将启动项的详细信息导出到文本文件。
- 打开条目位置:打开启动项的位置。
关注点
在本文中,为了禁用注册表中的启动项,我使用INI文件作为中间源来存储禁用项。禁用项显示在树控件的不同分支下,以便于访问。在此应用程序中,我为32位和64位启动项创建了单独的分支。
备注
- 此实用程序仅限于“RUN”和“RUNONCE”子项。
- 在此实用程序中,我没有提供禁用“启动文件夹”中的启动项的功能。