把程序设为开机启动,有三种方式:
(1). 把程序增加到注册表的开机运行项,
系统: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
用户: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
需要注意32位程序在64位系统运行,操作注册表被重定向的问题.
(2). 增加执行程序的快捷方式到系统开机启动目录,Windows自动启动放入该文件夹的所有快捷方式
注意WIN7个XP启动目录不一样
WIN7: C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
XP: C:\Documents and Settings\Administrator\「开始」菜单\程序\启动
(3). 把程序设置成服务,通常只把监控进程,守护进程设置成服务
下面介绍方法(1)的实现:
// 设置开机启动
void SetProcAutoRun(const char* szProcFullName/* = ""*/)
{
BOOL bWOW64 = IsWow64Proc();
PVOID oldValue = NULL;
//关闭
if (bWOW64)
{
//关闭WOW64重定向(在导注册表时很重要,避免文件被写到Wow6432Node)
typedef BOOL(WINAPI *LPFN_Wow64DisableWow64FsRedirection)(PVOID *OldValue);
LPFN_Wow64DisableWow64FsRedirection fnWow64DisableWow64FsRedirection = NULL;
fnWow64DisableWow64FsRedirection = (LPFN_Wow64DisableWow64FsRedirection)GetProcAddress(
GetModuleHandle(TEXT("kernel32")), "Wow64DisableWow64FsRedirection");
if (fnWow64DisableWow64FsRedirection != NULL)
{
fnWow64DisableWow64FsRedirection(&oldValue);
}
}
//修改注册表值
if (AddRegisterRun(szProcFullName))
{
OutputDebugString("Set auto run mode success.");
}
if (bWOW64)
{
//恢复WOW64重定向
typedef BOOL(WINAPI *LPFN_Wow64RevertWow64FsRedirection)(PVOID OlValue);
LPFN_Wow64RevertWow64FsRedirection fnWow64RevertWow64FsRedirection = NULL;
fnWow64RevertWow64FsRedirection = (LPFN_Wow64RevertWow64FsRedirection)GetProcAddress(
GetModuleHandle(TEXT("kernel32")), "Wow64RevertWow64FsRedirection");
if (fnWow64RevertWow64FsRedirection != NULL)
{
fnWow64RevertWow64FsRedirection(oldValue);
}
}
}
//修改注册表值
//szProcFullName为进程的全路径文件名
//szProcName为不包含路径的执行文件名
bool AddRegisterRun(const char* szProcFullName)
{
//打开子键(注册表键不区分大小写)
HKEY hSubKey = NULL;
HKEY hKey = HKEY_CURRENT_USER;
const char* szSubKey = TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
LONG lRet = RegOpenKeyEx(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey);
if (lRet != ERROR_SUCCESS)
{
return false;
}
//查询键值
DWORD dwType = 0;
DWORD dwLen = MAX_PATH;
UCHAR szData[MAX_PATH] = { 0 };
const char* szQueryKey = szProcName;
lRet = RegQueryValueEx(hSubKey, szQueryKey, NULL, &dwType, szData, &dwLen);
if (lRet != ERROR_SUCCESS)
{
//创建子键
lRet = RegSetValueEx(hSubKey, szQueryKey, NULL, REG_SZ, (const BYTE*)szProcFullName, strlen(szProcFullName));
if (lRet != ERROR_SUCCESS)
{
RegCloseKey(hSubKey);
return false;
}
}
else //子健存在时,再校验值是否匹配(应为程序绝对路径)
{
//键值不相等时需要修改
if (0 != _stricmp(szProcFullName, (char*)szData))
{
//修改键值
lRet = RegSetValueEx(hSubKey, szQueryKey, NULL, dwType, (const BYTE*)szProcFullName, strlen(szProcFullName));
if (lRet != ERROR_SUCCESS)
{
RegCloseKey(hSubKey);
return false;
}
}
}
RegCloseKey(hSubKey);
return true;
}
转载于:https://blog.51cto.com/51code/1656465