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)
{
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)
{
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()
{
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)
{
bool bEnable = false;
GetMenu()->EnableMenuItem(ID_EDIT_DISABLEENTRY, bEnable ? 0 : MF_ENABLED); GetMenu()->EnableMenuItem(ID_EDIT_ENABLEENTRY, bEnable ? 0 : MF_DISABLED | MF_GRAYED); GetMenu()->EnableMenuItem(ID_EDIT_REMOVEENTRY, bEnable ? 0 : MF_ENABLED); GetMenu()->EnableMenuItem(ID_EDIT_EDITENTRY, bEnable ? 0 : MF_ENABLED); m_ctlRemoveButton.EnableWindow(true); m_ctlAddNewButton.EnableWindow(true);
if(strSelectedItemPath.Find(_T("Registry")) != -1)
{
m_lstctrlStartupDetailsFolder.ShowWindow(SW_HIDE);
m_lstctrlStartupDetailsRegistry.ShowWindow(SW_SHOW);
if(strSelectedItemPath.Find(_T("CurrentUser")) != -1) {
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);
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);
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);
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);
FillStartUpList_Registry(vec64BitAppValueData,
_T("HKEY_CURRENT_USER"),
_T("Run"),
_T("Enabled"),
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"));
}
}
}
else if(strSelectedItemPath.Find(_T("LocalUser")) != -1) {
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);
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);
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);
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);
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); FillStartUpList_Folder(vecListOfStartupPrograms); }
else if(strSelectedItemText == _T("Current User"))
{
vector<CString> vecListOfStartupPrograms;
ListStartupProgramsForSpecificUser(CSIDL_APPDATA, vecListOfStartupPrograms); FillStartUpList_Folder(vecListOfStartupPrograms); }
}
}
}
- Disable selected startup entries from registry
void CStartupDlg::DisableSelectedEntries()
{
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()
{
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".