WindowsAPI编程核心技术-自启动技术
注册表
RegOpenKeyEx
打开注册表键。
1 2 3 4 5 6 7 8 9 10 11 12
| LONG WINAPI RegOpenKeyEx( _In_ HKEY hKey, _In_opt_ LPCTSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult )
|
RegSetValueEx
设置指定值的数据或类型。
1 2 3 4 5 6 7 8 9 10 11 12 13
| LONG WINAPI RegSetValueEx( _In_ HKEY hKey, _In_opt_ LPCTSTR lpValueName, _Reserved_ DWORD Reserved, _In_ DWORD dwType, _In_ const BYTE *lpData, _In_ DWORD cbData )
|
例子
两个开机自启动的注册表路径:
1 2
| HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
|
第二个想修改必须得管理员权限,第一个用户默认权限就行。
x64下为了兼容x86的正常运行,第二个可能会被重定位到这个路径:
1
| HEKY_LOVAL_MACHINE\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run
|
但是在RegOpenKeyEx
中设置KEY_WOW64_64KEY
选项就问题不大。
1 2 3 4 5 6 7 8 9 10 11
| BOOL Reg_CurrentUser(WCHAR* lpszFileName, WCHAR* lpszValueName) { HKEY hKey; if (ERROR_SUCCESS != ::RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, &hKey)) return FALSE; if (ERROR_SUCCESS != ::RegSetValueEx(hKey, lpszValueName, 0, REG_SZ, (BYTE*)lpszFileName, (1 + ::lstrlen(lpszFileName)))) { ::RegCloseKey(hKey); return FALSE; }; ::RegCloseKey(hKey); return TRUE; };
|
快速启动目录
SHGetSpecialFolderPath
获取指定的系统路径。
1 2 3 4 5 6 7 8 9 10
| BOOL SHGetSpecialFolder( _In_ HWND hwndOwner, _In_? LPTSTR lpszPath, _In_ int nFolder, _In_ BOOL fCreate )
|
例子
系统每次启动的快速启动文件夹可能都不一样,需要用SHGetSpecialFolder
来获得。把要启动的程序直接CopyFile
过去,或者快捷方式也行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <ShlObj.h> #include <cstdio> BOOL AutoRun_StartUp(WCHAR* lpszSrcFilePath, WCHAR* lpszDestFileName) { BOOL bRet = FALSE; WCHAR szStartupPath[MAX_PATH] = { 0 }; WCHAR szDestFilePath[MAX_PATH] = { 0 }; bRet = ::SHGetSpecialFolderPath(NULL, szStartupPath, CSIDL_STARTUP, TRUE); printf("%s\n", szStartupPath); if (FALSE == bRet) return FALSE; ::wsprintf(szDestFilePath, L"%s\\%s", szStartupPath, lpszDestFileName); bRet = ::CopyFile(lpszSrcFilePath, szDestFilePath, FALSE); if (FALSE == bRet) return FALSE; return TRUE; };
|
计划任务
涉及COM组件,太复杂了,略。
系统服务
OpenSCManager
建立一个到服务控制管理器的连接,并打开指定的数据库。
1 2 3 4 5 6 7 8
| SC_HANDLE OpenSCManager( _In_ LPCTSTR lpMachineName, _In_ LPSTSTR lpDatabaseName, _In_ DWORD dwDesiredAccess )
|
CreateService
创建一个服务对象,并添加到指定服务控制管理器数据库中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| SC_HANDLE CreateService( _In_ SC_HANDLE hSCManager, _In_ LPCTSTR lpServiceName, _In_ LPCTSTR lpDisplayName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwServiceType, _In_ DWORD dwStartType, _In_ DWORD dwErrorControl, _In_ LPCTSTR lpBinaryPathName, _In_ LPCTSTR lpLoadOrderGroup, _In_ LPCTSTR lpdwTagId, _In_ LPCTSTR lpDependencies, _In_ LPCTSTR lpServiceStartName, _In_ LPCTSTR lpPassword )
|
OpenService
打开一个已经存在的服务。
1 2 3 4 5 6 7 8
| SC_HANDLE WINAPI OpenService( _In_ SC_HANDLE hSCManager, _In_ LPCTSTR lpServiceName, _In_ DWORD dwDesiredAccess )
|
StartService
启动服务
1 2 3 4 5 6 7 8
| BOOL WINAPI StartService( _In_ SC_HANDLE hService, _In_ DWORD dwNumServiceArgs, _In_opt_ LPCTSTR* lpServiceArgVectors )
|
StartServiceCtrlDispatcher
服务进程主线程连接到服务控制管理器,将该线程作为调用过程的服务控制分派器线程。
1 2 3 4
| BOOL WINAPI StartServiceCtrlDispatcher( _In_ const SERVICE_TABLE_ENTRY* lpServiceTable )
|
例子
创建自启动系统服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include<shlwapi.h> BOOL SystemServiceOperate(WCHAR* lpszDriverPath, int iOperateType) { BOOL bRet = TRUE; WCHAR szName[MAX_PATH] = { 0 }; ::lstrcpy(szName, lpszDriverPath); ::PathStripPath(szName); SC_HANDLE shOSCM = NULL, shCS = NULL; SERVICE_STATUS ss; DWORD dwErrorCode = 0; BOOL bSuccess = FALSE; shOSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (!shOSCM) return FALSE; if (0 != iOperateType) { shCS = OpenService(shOSCM, szName, SERVICE_ALL_ACCESS); if (!shCS) { ::CloseServiceHandle(shOSCM); shOSCM = NULL; return FALSE; }; }; switch (iOperateType) { case 0: { shCS = ::CreateService(shOSCM, szName, szName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, lpszDriverPath, NULL, NULL, NULL, NULL, NULL); if (!shCS) bRet = FALSE; break; }; case 1: { if (!::StartService(shCS, 0, NULL)) bRet = FALSE; break; }; case 2: { if (!::ControlService(shCS, SERVICE_CONTROL_STOP, &ss)) bRet = FALSE; break; }; case 3: { if (!::DeleteService(shCS)) bRet = FALSE; break; }; default: break; }; if (shCS) { ::CloseServiceHandle(shCS); shCS = NULL; }; if (shOSCM) { ::CloseServiceHandle(shOSCM); shOSCM = NULL; }; return bRet; };
|
系统服务程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include<tchar.h> WCHAR g_szServiceName[MAX_PATH] = { 0 }; SERVICE_STATUS_HANDLE g_ServiceStatusHandle; void CALLBACK ServiceCtrlHandle(DWORD request) { return; }; void WINAPI ServiceMain(DWORD dwArgc, char* lpszArgv) { g_ServiceStatusHandle = ::RegisterServiceCtrlHandler(g_szServiceName, ServiceCtrlHandle); }; int _tmain(int argc, _TCHAR* argv[]) { SERVICE_TABLE_ENTRY stDispatchTable[] = { {g_szServiceName,(LPSERVICE_MAIN_FUNCTION)ServiceMain}, {NULL,NULL} }; ::StartServiceCtrlDispatcher(stDispatchTable); return 0; };
|