Ved Startup Manager





5.00/5 (3 votes)
This article is written in VC++ as utility to manage startup applications of Windows.
Introduction
Startup programs are entries which are launched or start by windows automatically. For some programs it is necessary to start automatically with windows but majority of applications residing in startup list are eating your system's memory and CPU. It also increases your system's startup time. Some of them keep running in background which degrades your system performance. So it is necessary to manage startup applications according to your need.
Background
Startup entries are essential part of Windows Operating System. Through windows we can view startup programs using, "Windows Management Instrumentation". To view startup programs through this process we need to follow following steps:
1) Open command prompt and type command, "WMIC" and hit the "Enter" key.
2) After that type, "STARTUP" and hit the "Enter" key.
We can also able to see startup programs through "MSCONFIG" or through "TASKMANAGER".
About Startup Entries
On Windows OS we can make any application to run as startup using two methods. Either we put execution command (executable path with its commandline arguments if any) in system’s registry or we put link for an application in special folders of windows OS.
Registry
Locations for startup applications in registry are as follows:
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
Commands found in subkey "RUN" starts every time when user log on to computer. Interesting points about commands found under "RUN" subkey key are:
- Command found under this subkey to be run each time after window log on and not at boot time.
- There is not any specific order to execute these commands.
- This key is present under, "HKEY_LOCAL_MACHINE" and "HKEY_CURRENT_USER" hives.
- If present under, "HKEY_LOCAL_MACHINE" then command affects to all users.
RUNONCE
Commands under this category runs only once. Windows deletes these commands from "RunOnce" subkey path after execution. For other cases "RUNONCE" subkey is similar to "RUN".
To know more about these entries and other startup entries please go through following links:
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
NOTE:
- If your operating system is 64 bit then, 32 bit application's startup entries get stored on:
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:
To manage 32 bit application on 64 bit machine "Wow6432Node" key is used.
Startup Folders
Startup directories or folders contains a list of shortcuts or executables which start with window just after windows logon. We can find them on Windows 8/10 on the following path:
ALL USERS
%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\StartUp
Shortcut way to access this path, open "RUN", type "shell:common startup" and hit Enter.
USER PROFILE/CURRENT USER
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup
Shortcut way to access this path, open "RUN", type "shell:startup" and hit Enter.
Classes Used
Before elaborating this section of article, I wants to thank "Sven Wiegand" for his article for retrieving file version information. I have used, "CFileVersionInfo" class here in this application to retrieve file information. You will find it here:
https://www.codeproject.com/Articles/1502/CFileVersionInfo-Retrieving-a-File-s-full-Version
Source code of this utility contains following classes:
- CStartupDlg: This is applications main class dealing with user interface.
- CCommonUtilities: This class contains common utility functions used throughout the project.
- CRegistryUtility: This class contains registry manipulating functions needed in this project.
- CAddNewStartupEntry: This is dialog class used to add new startup entries in the registry through user interface.
Using the code
Registry utility function
Following two functions used to access startup entries from registry.
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);
}
Main functionality
- Retrieve all startup entries from registry under, "RUN" and "RUNONCE" subkey
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
}
}
}
}
- Disable selected startup entries from registry
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);
}
}
}
- Enable selected startup entries
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);
}
}
}
Note: To view more functionalities please go through source code attached along with this article.
Using An Application
This application help you to manage windows startup entries efficiently. You can manage easily manage 32 bit and 64 bit startup entries. You can do following operations with startup entries using this utility:
- Add New Startup Entry: Add new startup entry to registry
- Enable entry: Unable disabled entry
- Disable Entry: Disabled registry startup entry
- Remove Entry: Remove strartup entry from registry
- Edit Entry: Edit existing startup entry
- Execute Entry: Execute startup entry
- Export To Text File: Export details of startup entry to text file
- Open entry Location: Open location of startup entry
Points of Interest
In this article to disable startup entries from registry, I used INI file as an intermediate source to store disabled entries. Disabled entries are shown under different branch of tree control for easy access. In this application I created separate branches for 32 bit and 64 bit startup entries.
Remarks
- This utility is only limited to "RUN" and "RUNONCE" subkeys.
- In this utility, I have not provided to disable startup entries from, "STARTUP FOLDERS".