@@ -25,6 +25,28 @@ BOOL TryInvoke(F&& func, LPCWSTR msg)
2525#define ErrThrow (msg ) \
2626 do { TryInvoke ([&] { return E_FAIL; }, msg); return FALSE ; } while (0 );
2727
28+
29+ std::wstring defaultTaskName ()
30+ {
31+ // 获取所需缓冲区大小
32+ const auto required_size = GetEnvironmentVariableW (L" USERNAME" , nullptr , 0 );
33+ if (required_size == 0 ) {
34+ return L" timer-devourer-unknown" ;
35+ }
36+
37+ std::wstring username (required_size, L' \0 ' );
38+
39+ const auto copied = GetEnvironmentVariableW (L" USERNAME" , username.data (), required_size);
40+ if (copied == 0 || copied >= required_size) {
41+ return L" timer-devourer-unknown" ;
42+ }
43+
44+ // 调整大小(copied 是实际字符数)
45+ username.resize (copied);
46+
47+ return L" timer-devourer-" + username;
48+ }
49+
2850/* *
2951 *
3052 * @return BOOL
@@ -34,7 +56,7 @@ BOOL CreateStartupTask()
3456 // 错误位标志
3557 auto hr = S_OK;
3658
37- std::wstring task_name;
59+ std::wstring task_name = defaultTaskName () ;
3860
3961 std::wstring username_domain;
4062 username_domain.resize (USERNAME_DOMAIN_LEN);
@@ -68,12 +90,12 @@ BOOL CreateStartupTask()
6890 ErrThrow (L" 环境变量:USERDOMAIN获取失败" );
6991 }
7092
93+ username.resize (username_len);
94+ username_domain.resize (userdomain_len);
95+
7196 username_domain += L" \\ " ;
7297 username_domain += username;
7398
74- task_name += L" timer-" ;
75- task_name += username;
76-
7799 TryStep (com_scope.init (), L" COM组件:初始化错误" );
78100
79101
@@ -226,3 +248,117 @@ BOOL CreateStartupTask()
226248
227249 return SUCCEEDED (hr);
228250}
251+
252+
253+ BOOL DeleteStartupTask ()
254+ {
255+ HRESULT hr = S_OK;
256+
257+ WCHAR username[USERNAME_LEN];
258+ std::wstring task_name = defaultTaskName ();
259+
260+ COMScope com_scope;
261+ COMPtr<ITaskService> p_service (nullptr );
262+ COMPtr<ITaskFolder> p_task_folder (nullptr );
263+
264+
265+ TryStep (com_scope.init (), L" COM组件:初始化错误" );
266+
267+ TryStep (CoCreateInstance (
268+ __uuidof (TaskScheduler),
269+ nullptr ,
270+ CLSCTX_INPROC_SERVER,
271+ __uuidof (ITaskService),
272+ reinterpret_cast <void **>(p_service.AsOutPtr ()))
273+ , L" COM组件TaskScheduler:创建失败" );
274+ TryStep (hr , L" COM组件:创建ITaskService失败" );
275+
276+ hr = p_service->Connect (_variant_t (), _variant_t (), _variant_t (), _variant_t ());
277+ TryStep (hr, L" COM组件:连接ITaskService失败" );
278+
279+ hr = p_service->GetFolder (_bstr_t (TASK_SCHED_FOLDER), p_task_folder.AsOutPtr ());
280+ if (FAILED (hr))
281+ {
282+ // 断言文件夹不存在,不需要删除任务
283+ return TRUE ;
284+ }
285+
286+ {
287+ COMPtr<IRegisteredTask> p_exist_reg_task (nullptr );
288+ hr = p_task_folder->GetTask (_bstr_t (task_name.c_str ()), p_exist_reg_task.AsOutPtr ());
289+ if (SUCCEEDED (hr))
290+ {
291+ hr = p_task_folder->DeleteTask (_bstr_t (task_name.c_str ()), 0 );
292+ }
293+ }
294+
295+ return (SUCCEEDED (hr));
296+ }
297+
298+
299+ BOOL IsActiveStartupTask (std::wstring* path)
300+ {
301+ HRESULT hr = S_OK;
302+
303+ std::wstring wstrTaskName = defaultTaskName ();
304+
305+ COMScope com_scope;
306+ COMPtr<ITaskService> p_service (nullptr );
307+ COMPtr<ITaskFolder> p_task_folder (nullptr );
308+
309+ BOOL command_path_match = FALSE ;
310+
311+ TryStep (com_scope.init (), L" COM组件:初始化错误" );
312+ TryStep (CoCreateInstance (
313+ __uuidof (TaskScheduler),
314+ nullptr ,
315+ CLSCTX_INPROC_SERVER,
316+ __uuidof (ITaskService),
317+ p_service.AsOutVoidPtr ())
318+ , L" COM组件TaskScheduler:创建失败" );
319+
320+ // Connect to the task service.
321+ hr = p_service->Connect (_variant_t (), _variant_t (), _variant_t (), _variant_t ());
322+ TryStep (hr, L" COM组件:连接ITaskService失败" );
323+
324+ // ------------------------------------------------------
325+ // Get the TrafficMonitor task folder.
326+ hr = p_service->GetFolder (_bstr_t (TASK_SCHED_FOLDER), p_task_folder.AsOutPtr ());
327+ TryStep (hr, L" COM组件:获取ITaskFolder失败" );
328+
329+ // ------------------------------------------------------
330+ // If the task exists, disable.
331+ {
332+ COMPtr<IRegisteredTask> p_exist_reg_task (nullptr );
333+ hr = p_task_folder->GetTask (_bstr_t (wstrTaskName.c_str ()), p_exist_reg_task.AsOutPtr ());
334+ if (SUCCEEDED (hr))
335+ {
336+ VARIANT_BOOL is_enabled;
337+ hr = p_exist_reg_task->get_Enabled (&is_enabled);
338+ // 判断已存在的任务计划命令的exe文件路径是否为当前exe的路径
339+ CComBSTR xml_buff{};
340+ p_exist_reg_task->get_Xml (&xml_buff);
341+ CSimpleXML xml;
342+ xml.LoadXMLContentDirect (std::wstring (xml_buff));
343+ // 获得配置中的执行路径
344+ std::wstring command_path = xml.GetNode (L" Command" , L" Exec" );
345+ if (path != nullptr )
346+ {
347+ *path = command_path;
348+ }
349+ // 获得当前exe的路径
350+ std::wstring exec_path;
351+ exec_path.resize (MAX_PATH);
352+ GetModuleFileName (NULL , exec_path.data (), MAX_PATH);
353+ command_path_match = (command_path == exec_path);
354+ SysFreeString (xml_buff);
355+ if (SUCCEEDED (hr))
356+ {
357+ // Got the value. Return it.
358+ hr = (is_enabled == VARIANT_TRUE) ? S_OK : E_FAIL; // Fake success or fail to return the value.
359+ }
360+ }
361+ }
362+
363+ return (SUCCEEDED (hr) && command_path_match);
364+ }
0 commit comments