unsigned CSoftUninstall::RegMonitor() { CRegKey reg; LONG ret = reg.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", KEY_NOTIFY); if(ret != ERROR_SUCCESS) return unsigned(-1); CRegKey reg2; ret = reg2.Open(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", KEY_NOTIFY); if(ret != ERROR_SUCCESS) return unsigned(-1); CRegKey reg3; if(Is64BitWindows()) { ret = reg3.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", KEY_NOTIFY | KEY_WOW64_64KEY); if(ret != ERROR_SUCCESS) return unsigned(-1); } HANDLE hEvents[2] = {0}; hEvents[0] = _regMonitorEvent; hEvents[1] = ::CreateEventW(NULL, FALSE, FALSE, NULL); do { ret = reg.NotifyChangeKeyValue(TRUE, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hEvents[1]); if(ret != ERROR_SUCCESS) break; ret = reg2.NotifyChangeKeyValue(TRUE, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hEvents[1]); if(ret != ERROR_SUCCESS) break; if(Is64BitWindows()) { ret = reg3.NotifyChangeKeyValue(TRUE, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hEvents[1]); if(ret != ERROR_SUCCESS) break; } DWORD res = ::WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); if(res == WAIT_OBJECT_0 + 1) { // 等注册表稳定 ::Sleep(500); // 强制刷新 DataRefresh(TRUE); } else { // 退出 break; } } while(TRUE); ::CloseHandle(hEvents[1]); return 0; }
DWORD CIISxpressRegSettings::ChangeNotificationProc(void) { // we want low priority ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_LOWEST); // open the registry key for notifications CRegKey Config; if (Config.Open(HKEY_LOCAL_MACHINE, m_sRegPath, KEY_NOTIFY | m_dwOpenFlags) != ERROR_SUCCESS) { return 0; } // create the notification event HANDLE hRegChange = ::CreateEvent(NULL, FALSE, FALSE, NULL); if (hRegChange == NULL) return 0; // allow the event to be automatically managed Ripcord::Types::AutoHandle::AutoEventHandle RegChangeEvent(hRegChange); hRegChange = INVALID_HANDLE_VALUE; // the events we want to monitor HANDLE hEvents[2]; hEvents[0] = this->m_NotificationTermEvent; hEvents[1] = RegChangeEvent; while (1) { // register the notification event if (Config.NotifyChangeKeyValue(TRUE, REG_NOTIFY_CHANGE_LAST_SET, RegChangeEvent) != ERROR_SUCCESS) { break; } // wait for a change or an exit DWORD dwStatus = ::WaitForMultipleObjects(_countof(hEvents), hEvents, FALSE, INFINITE); if (dwStatus == WAIT_OBJECT_0) { // it's an exit break; } else if (dwStatus == (WAIT_OBJECT_0 + 1)) { // the registry has changed, update our settings Load(); } } return 0; }